extern int check_resigns(cubeinfo * pci)
{
    float rEqBefore, rEqAfter;
    const float max_cost = 0.05f;
    const float max_gain = 1e-6f;
    decisionData dd;
    cubeinfo ci;
    int resigned = 1;

    if (pci == NULL) {
        GetMatchStateCubeInfo(&ci, &ms);
        pci = &ci;
    }

    get_eq_before_resign(pci, &dd);
    do {
        getResignEquities(dd.aarOutput[0], pci, resigned, &rEqBefore, &rEqAfter);
        if (rEqBefore - rEqAfter > max_cost) {
            resigned = 4;
            break;
        } else if (rEqAfter - rEqBefore < max_gain)
            break;
    }
    while (resigned++ <= 3);
    return resigned == 4 ? -1 : resigned;
}
Пример #2
0
static GtkTreeModel *
create_model(const int n, evalcontext * pec, const matchstate * pms)
{
    GtkTreeStore *model;
    TanBoard anBoard;
    cubeinfo ci;
    float arOutput[NUM_ROLLOUT_OUTPUTS];
    int i, j;

    memcpy(anBoard, pms->anBoard, sizeof(anBoard));

    /* create tree store */
    model = gtk_tree_store_new(3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);

    GetMatchStateCubeInfo(&ci, pms);

    for (i = 0, j = 1; i < n; ++i, j *= 21);

    ProgressStartValue(_("Calculating equities"), j);

    add_level(model, NULL, n - 1, (ConstTanBoard) anBoard, pec, &ci, TRUE, arOutput);

    ProgressEnd();

    if (!fInterrupt) {
        gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(model), 2, sort_func, NULL, NULL);
        gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(model), 2, GTK_SORT_DESCENDING);
        return GTK_TREE_MODEL(model);
    } else
        return NULL;
}
Пример #3
0
static void
EvalMoves(hintdata * phd, evalcontext * pec)
{
    GList *pl;
    cubeinfo ci;
    int *ai;
    GList *plSelList = MoveListGetSelectionList(phd);

    if (!plSelList)
        return;

    GetMatchStateCubeInfo(&ci, &ms);

    for (pl = plSelList; pl; pl = pl->next) {
        scoreData sd;
        sd.pm = MoveListGetMove(phd, pl);
        sd.pci = &ci;
        sd.pec = pec;

        if (RunAsyncProcess((AsyncFun) asyncScoreMove, &sd, _("Evaluating positions...")) != 0) {
            MoveListFreeSelectionList(plSelList);
            return;
        }

        /* Calling RefreshMoveList here requires some extra work, as
         * it may reorder moves */
        MoveListUpdate(phd);
    }
    MoveListFreeSelectionList(plSelList);

    MoveListClearSelection(0, 0, phd);

    ai = (int *) malloc(phd->pml->cMoves * sizeof(int));
    RefreshMoveList(phd->pml, ai);

    if (phd->piHighlight && phd->pml->cMoves)
        *phd->piHighlight = ai[*phd->piHighlight];

    free(ai);

    find_skills(phd->pmr, &ms, -1, -1);
    MoveListUpdate(phd);
    if (phd->hist) {
        SetAnnotation(pmrCurAnn);
        ChangeGame(NULL);
    }
}
Пример #4
0
static void
TextPrintMoveAnalysis(GString * gsz, const matchstate * pms, moverecord * pmr)
{

    char szBuf[1024];
    char sz[64];
    unsigned int i;

    cubeinfo ci;

    GetMatchStateCubeInfo(&ci, pms);

    /* check if move should be printed */

    if (!exsExport.afMovesDisplay[pmr->n.stMove])
        return;

    /* print alerts */

    if (badSkill(pmr->n.stMove)) {

        /* blunder or error */

        g_string_append_printf(gsz, _("Alert: %s move"), gettext(aszSkillType[pmr->n.stMove]));

        if (!pms->nMatchTo || (pms->nMatchTo && !fOutputMWC))
            g_string_append_printf(gsz, " (%+7.3f)\n",
                                   pmr->ml.amMoves[pmr->n.iMove].rScore - pmr->ml.amMoves[0].rScore);
        else
            g_string_append_printf(gsz, " (%+6.3f%%)\n",
                                   100.0f *
                                   eq2mwc(pmr->ml.amMoves[pmr->n.iMove].rScore, &ci) -
                                   100.0f * eq2mwc(pmr->ml.amMoves[0].rScore, &ci));

    }

    if (pmr->lt != LUCK_NONE) {

        /* joker */

        g_string_append_printf(gsz, _("Alert: %s roll!"), gettext(aszLuckType[pmr->lt]));

        if (!pms->nMatchTo || (pms->nMatchTo && !fOutputMWC))
            g_string_append_printf(gsz, " (%+7.3f)\n", pmr->rLuck);
        else
            g_string_append_printf(gsz, " (%+6.3f%%)\n", 100.0f * eq2mwc(pmr->rLuck, &ci) - 100.0f * eq2mwc(0.0f, &ci));

    }

    g_string_append(gsz, "\n");

    g_string_append_printf(gsz, _("Rolled %d%d"), pmr->anDice[0], pmr->anDice[1]);

    if (pmr->rLuck != ERR_VAL)
        g_string_append_printf(gsz, " (%s):\n", GetLuckAnalysis(pms, pmr->rLuck));
    else
        g_string_append_printf(gsz, ":\n");

    if (pmr->ml.cMoves) {

        for (i = 0; i < pmr->ml.cMoves; i++) {
            if (i >= exsExport.nMoves && i != pmr->n.iMove)
                continue;

            g_string_append(gsz, i == pmr->n.iMove ? "*" : " ");
            g_string_append(gsz, FormatMoveHint(szBuf, pms, &pmr->ml, i,
                                                i != pmr->n.iMove ||
                                                i != pmr->ml.cMoves - 1 ||
                                                pmr->ml.cMoves == 1 ||
                                                i < exsExport.nMoves,
                                                exsExport.fMovesDetailProb,
                                                exsExport.afMovesParameters[pmr->ml.amMoves[i].esMove.et - 1]));


        }

    } else {

        if (pmr->n.anMove[0] >= 0)
            /* no movelist saved */
            g_string_append_printf(gsz, "*    %s\n", FormatMove(sz, pms->anBoard, pmr->n.anMove));
        else
            /* no legal moves */
            /* FIXME: output equity?? */
            g_string_append_printf(gsz, "*    %s\n", _("Cannot move"));

    }

    g_string_append(gsz, "\n\n");

    return;

}
Пример #5
0
static void
TextPrintCubeAnalysis(GString * gsz, const matchstate * pms, moverecord * pmr)
{

    cubeinfo ci;
    /* we need to remember the double type to be able to do the right
     * thing for beavers and racoons */
    static doubletype dt = DT_NORMAL;

    GetMatchStateCubeInfo(&ci, pms);


    switch (pmr->mt) {

    case MOVE_NORMAL:

        /* cube analysis from move */

        TextPrintCubeAnalysisTable(gsz,
                                   pmr->CubeDecPtr->aarOutput,
                                   pmr->CubeDecPtr->aarStdDev,
                                   pmr->fPlayer, &pmr->CubeDecPtr->esDouble, &ci, FALSE, -1, pmr->stCube, SKILL_NONE);
        dt = DT_NORMAL;

        break;

    case MOVE_DOUBLE:

        dt = DoubleType(pms->fDoubled, pms->fMove, pms->fTurn);
        if (dt != DT_NORMAL) {
            g_string_append(gsz, _("Cannot analyse beaver nor raccoons!\n"));
            break;
        }
        TextPrintCubeAnalysisTable(gsz,
                                   pmr->CubeDecPtr->aarOutput,
                                   pmr->CubeDecPtr->aarStdDev,
                                   pmr->fPlayer, &pmr->CubeDecPtr->esDouble, &ci, TRUE, -1, pmr->stCube, SKILL_NONE);

        break;

    case MOVE_TAKE:
    case MOVE_DROP:

        /* cube analysis from double, {take, drop, beaver} */

        if (dt != DT_NORMAL) {
            dt = DT_NORMAL;
            g_string_append(gsz, _("Cannot analyse beaver nor raccoons!\n"));
            break;
        }
        TextPrintCubeAnalysisTable(gsz, pmr->CubeDecPtr->aarOutput, pmr->CubeDecPtr->aarStdDev, pmr->fPlayer, &pmr->CubeDecPtr->esDouble, &ci, TRUE, pmr->mt == MOVE_TAKE, SKILL_NONE,  /* FIXME: skill from prev. cube */
                                   pmr->stCube);

        break;

    default:

        g_assert_not_reached();


    }

    return;

}
Пример #6
0
/*
 * Call UpdateMostList to update the movelist in the GTK hint window.
 * For example, after new evaluations, rollouts or toggle of MWC/Equity.
 *
 */
extern void MoveListUpdate ( const hintdata *phd )
{
  unsigned int i, j, colNum;
  char sz[ 32 ];
  cubeinfo ci;
  movelist *pml = phd->pml;
  int col = phd->fDetails ? 8 : 2;
  int showWLTree = showMoveListDetail && !phd->fDetails;

  int offset = (phd->fDetails) ? 0 : MIN_COLUMN_COUNT - DETAIL_COLUMN_COUNT;
  GtkTreeIter iter;
  GtkListStore *store;
  store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(phd->pwMoves)));
  gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter);

  if (!psHighlight)
  { /* Get highlight style first time in */
    GtkStyle *psTemp;
    GtkStyle *psMoves = gtk_widget_get_style(phd->pwMoves);
    GetStyleFromRCFile(&psHighlight, "move-done", psMoves);
    /* Use correct background colour when selected */
    memcpy(&psHighlight->bg[GTK_STATE_SELECTED], &psMoves->bg[GTK_STATE_SELECTED], sizeof(GdkColor));

    /* Also get colour to use for w/l stats in detail view */
    GetStyleFromRCFile(&psTemp, "move-winlossfg", psMoves);
    memcpy(&wlCol, &psTemp->fg[GTK_STATE_NORMAL], sizeof(GdkColor));
    g_object_unref(psTemp);
  }

  /* This function should only be called when the game state matches
     the move list. */
  g_assert( ms.fMove == 0 || ms.fMove == 1 );

  GetMatchStateCubeInfo( &ci, &ms );
  rBest = pml->amMoves[ 0 ].rScore;

  if (!showWLTree)
    gtk_tree_view_column_set_title(gtk_tree_view_get_column(GTK_TREE_VIEW(phd->pwMoves), col),
        (fOutputMWC && ms.nMatchTo) ? _("MWC") : _("Equity"));

  for( i = 0; i < pml->cMoves; i++ )
  {
    float *ar = pml->amMoves[ i ].arEvalMove;
    int rankKnown;
    char *highlight_sz;

    if (showWLTree)
      gtk_list_store_set(store, &iter, 0, pml->amMoves + i, -1);
    else
      gtk_list_store_set(store, &iter, ML_COL_DATA + offset, pml->amMoves + i, -1);

    rankKnown = 1;
    if( i && i == pml->cMoves - 1 && phd->piHighlight && i == *phd->piHighlight )
      /* The move made is the last on the list.  Some moves might
         have been deleted to fit this one in */
    {
      /* Lets count how many moves are possible to see if this is the last move */
      movelist ml;
      int dice[2];
      memcpy(dice, ms.anDice, sizeof(dice));
      if (!dice[0])
      { /* If the dice have got lost, try to find them */
        moverecord* pmr = (moverecord*)plLastMove->plNext->p;
        if (pmr)
        {
          dice[0] = pmr->anDice[0];
          dice[1] = pmr->anDice[1];
        }
      }
      GenerateMoves(&ml, msBoard(), dice[0], dice[1], FALSE);
      if (i < ml.cMoves - 1)
        rankKnown = 0;
    }

    highlight_sz = (phd->piHighlight && *phd->piHighlight == i) ? "*" : "";

    if (rankKnown)
      sprintf( sz, "%s%s%d", pml->amMoves[i].cmark ? "+" : "", highlight_sz, i + 1 );
    else
      sprintf( sz, "%s%s??", pml->amMoves[i].cmark ? "+" : "", highlight_sz );

    if (showWLTree)
    {
      gtk_list_store_set(store, &iter, 1, rankKnown ? (int)i + 1 : -1, -1);
      goto skipoldcode;
    }
    else
      gtk_list_store_set(store, &iter, ML_COL_RANK, sz, -1);
    FormatEval( sz, &pml->amMoves[ i ].esMove );
    gtk_list_store_set(store, &iter, ML_COL_TYPE, sz, -1);

    /* gwc */
    if ( phd->fDetails )
    {
      colNum = ML_COL_WIN;
      for( j = 0; j < 5; j++ ) 
      {
        if (j == 3)
        {
          gtk_list_store_set(store, &iter, colNum, OutputPercent(1.0f - ar[ OUTPUT_WIN ] ), -1);
          colNum++;
        }
        gtk_list_store_set(store, &iter, colNum, OutputPercent(ar[j]), -1);
        colNum++;
      }
    }

    /* cubeless equity */
    gtk_list_store_set(store, &iter, ML_COL_EQUITY + offset,
        OutputEquity( pml->amMoves[ i ].rScore, &ci, TRUE ), -1);
    if (i != 0)
    {
      gtk_list_store_set(store, &iter, ML_COL_DIFF + offset,
          OutputEquityDiff( pml->amMoves[ i ].rScore, 
            rBest, &ci ), -1);
    }

    gtk_list_store_set(store, &iter, ML_COL_MOVE + offset,
        FormatMove( sz, msBoard(),
          pml->amMoves[ i ].anMove ), -1);

    /* highlight row */
    if (phd->piHighlight && *phd->piHighlight == i)
    {
      char buf[20];
      sprintf(buf, "#%02x%02x%02x", psHighlight->fg[GTK_STATE_SELECTED].red / 256, psHighlight->fg[GTK_STATE_SELECTED].green / 256, psHighlight->fg[GTK_STATE_SELECTED].blue / 256);
      gtk_list_store_set(store, &iter, ML_COL_FGCOL + offset, buf, -1);
    }
    else
      gtk_list_store_set(store, &iter, ML_COL_FGCOL + offset, NULL, -1);
skipoldcode:  /* Messy as 3 copies of code at moment... */
    gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter);
  }

}
Пример #7
0
static void
MoveListRolloutClicked(GtkWidget * pw, hintdata * phd)
{
    cubeinfo ci;
    int i, c, res;
    move *m;
    int *ai;
    void *p;
    GList *pl, *plSelList = MoveListGetSelectionList(phd);
    if (!plSelList)
        return;

    GetMatchStateCubeInfo(&ci, &ms);

    c = g_list_length(plSelList);

    /* setup rollout dialog */
    {
        move **ppm = (move **) malloc(c * sizeof(move *));
        cubeinfo **ppci = (cubeinfo **) malloc(c * sizeof(cubeinfo *));
        char (*asz)[40] = (char (*)[40]) malloc(40 * c);

        for (i = 0, pl = plSelList; i < c; pl = pl->next, i++) {
            m = ppm[i] = MoveListGetMove(phd, pl);
            ppci[i] = &ci;
            FormatMove(asz[i], msBoard(), m->anMove);
        }
        MoveListFreeSelectionList(plSelList);

        GTKSetCurrentParent(pw);
        RolloutProgressStart(&ci, c, NULL, &rcRollout, asz, FALSE, &p);

        res = ScoreMoveRollout(ppm, (const cubeinfo **) ppci, c, RolloutProgress, p);

        RolloutProgressEnd(&p, FALSE);

        free(asz);
        free(ppm);
        free(ppci);

        if (res < 0)
            return;

        /* If the source widget parent has been destroyed do not attempt
         * to update the hint window */
        if (!GDK_IS_WINDOW(gtk_widget_get_parent_window(pw)))
            return;

        /* Calling RefreshMoveList here requires some extra work, as
         * it may reorder moves */
        MoveListUpdate(phd);
    }

    MoveListClearSelection(0, 0, phd);

    ai = (int *) malloc(phd->pml->cMoves * sizeof(int));
    RefreshMoveList(phd->pml, ai);

    if (phd->piHighlight && phd->pml->cMoves)
        *phd->piHighlight = ai[*phd->piHighlight];

    free(ai);

    find_skills(phd->pmr, &ms, -1, -1);
    MoveListUpdate(phd);
    if (phd->hist) {
        SetAnnotation(pmrCurAnn);
        ChangeGame(NULL);
    }
}