Пример #1
0
void testDoubling() {
  printf("\n\nTEST ACCETTAZIONE DOUBLE...\n");
  int b[2][25] = 
  {
    {2, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},//ALL BEARED OFF 
    {0, 3, 2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0},//ALL BEARED OFF
    //{2, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    //{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0}
  };

  ms.anScore[0] = 0;
  ms.anScore[1] = 0;
  ms.nMatchTo = 7;


  ms.fMove = 0;
  ms.fTurn = 1;
  ms.fCubeOwner = -1;
  setBoard((ConstTanBoard)b);
  printBoard(msBoard());
  printf("ACCETTAZIONE: %s\n\n", acceptDouble()?"OK":"NO");

  ms.fMove = 1;
  ms.fTurn = 0;
  ms.fCubeOwner = -1;
  SwapSides(ms.anBoard);
  printBoard(msBoard());
  printf("ACCETTAZIONE: %s\n", acceptDouble()?"OK":"NO");
}
Пример #2
0
static void
MoveListTempMapClicked(GtkWidget * pw, hintdata * phd)
{
    GList *pl;
    char szMove[100];
    matchstate *ams;
    int i, c;
    gchar **asz;

    GList *plSelList = MoveListGetSelectionList(phd);
    if (!plSelList)
        return;

    c = g_list_length(plSelList);

    ams = (matchstate *) g_malloc(c * sizeof(matchstate));
    asz = (char **) g_malloc(c * sizeof(char *));

    for (i = 0, pl = plSelList; pl; pl = pl->next, ++i) {

        move *m = MoveListGetMove(phd, pl);

        /* Apply move to get board */

        memcpy(&ams[i], &ms, sizeof(matchstate));

        FormatMove(szMove, (ConstTanBoard) ams[i].anBoard, m->anMove);
        ApplyMove(ams[i].anBoard, m->anMove, FALSE);

        /* Swap sides */

        SwapSides(ams[i].anBoard);
        ams[i].fMove = !ams[i].fMove;
        ams[i].fTurn = !ams[i].fTurn;

        /* Show temp map dialog */

        asz[i] = g_strdup(szMove);

    }
    MoveListFreeSelectionList(plSelList);

    GTKSetCurrentParent(pw);
    GTKShowTempMap(ams, c, (const gchar **) asz, TRUE);

    g_free(ams);
    for (i = 0; i < c; ++i)
        g_free(asz[i]);
    g_free(asz);
}
extern void EvaluateRoll(float ar[NUM_ROLLOUT_OUTPUTS], int nDie1, int nDie2, const TanBoard anBoard,
             const cubeinfo * pci, const evalcontext * pec)
{
    TanBoard anBoardTemp;
    cubeinfo ciOpp;

    memcpy(&ciOpp, pci, sizeof(cubeinfo));
    ciOpp.fMove = !pci->fMove;

    memcpy(&anBoardTemp[0][0], &anBoard[0][0], 2 * 25 * sizeof(int));

    if (FindBestMove(NULL, nDie1, nDie2, anBoardTemp, pci, NULL, defaultFilters) < 0)
        g_assert_not_reached();

    SwapSides(anBoardTemp);

    GeneralEvaluationE(ar, (ConstTanBoard) anBoardTemp, &ciOpp, pec);

    return;
}
Пример #4
0
static void
add_level(GtkTreeStore * model, GtkTreeIter * iter,
          const int n, const TanBoard anBoard,
          evalcontext * pec, cubeinfo * pci, const gboolean fInvert, float arOutput[NUM_ROLLOUT_OUTPUTS])
{

    int n0, n1;
    GtkTreeIter child_iter;
    cubeinfo ci;
    TanBoard an;
    float ar[NUM_ROLLOUT_OUTPUTS];
    int anMove[8];
    int i;

    char szRoll[3], szMove[100], *szEquity;

    /* cubeinfo for opponent on roll */

    memcpy(&ci, pci, sizeof(cubeinfo));
    ci.fMove = !pci->fMove;

    for (i = 0; i < NUM_ROLLOUT_OUTPUTS; ++i)
        arOutput[i] = 0.0f;

    for (n0 = 0; n0 < 6; ++n0) {
        for (n1 = 0; n1 <= n0; ++n1) {

            memcpy(an, anBoard, sizeof(an));

            if (FindBestMove(anMove, n0 + 1, n1 + 1, an, pci, pec, defaultFilters) < 0)
                return;

            SwapSides(an);

            gtk_tree_store_append(model, &child_iter, iter);

            if (n) {

                add_level(model, &child_iter, n - 1, (ConstTanBoard) an, pec, &ci, !fInvert, ar);
                if (fInterrupt)
                    return;

            } else {

                /* evaluate resulting position */

                ProgressValueAdd(1);

                if (GeneralEvaluationE(ar, (ConstTanBoard) an, &ci, pec) < 0)
                    return;

            }

            if (fInvert)
                InvertEvaluationR(ar, &ci);

            sprintf(szRoll, "%d%d", n0 + 1, n1 + 1);
            FormatMove(szMove, anBoard, anMove);

            szEquity = OutputMWC(ar[OUTPUT_CUBEFUL_EQUITY], fInvert ? pci : &ci, TRUE);

            gtk_tree_store_set(model, &child_iter, 0, szRoll, 1, szMove, 2, szEquity, -1);

            for (i = 0; i < NUM_ROLLOUT_OUTPUTS; ++i)
                arOutput[i] += (n0 == n1) ? ar[i] : 2.0f * ar[i];

        }

    }

    for (i = 0; i < NUM_ROLLOUT_OUTPUTS; ++i)
        arOutput[i] /= 36.0f;

    /* add average equity */

    szEquity = OutputMWC(arOutput[OUTPUT_CUBEFUL_EQUITY], fInvert ? pci : &ci, TRUE);

    gtk_tree_store_append(model, &child_iter, iter);

    gtk_tree_store_set(model, &child_iter, 0, _("Average equity"), 1, "", 2, szEquity, -1);

    if (!fInvert)
        InvertEvaluationR(arOutput, pci);

}
Пример #5
0
static void
ExportGameText(FILE * pf, listOLD * plGame, const int iGame, const int fLastGame)
{

    listOLD *pl;
    moverecord *pmr;
    matchstate msExport;
    matchstate msOrig;
    int iMove = 0;
    statcontext *psc = NULL;
    static statcontext scTotal;
    xmovegameinfo *pmgi = NULL;
    GString *gsz;
    listOLD *pl_hint = NULL;
    statcontext *psc_rel;

    msOrig.nMatchTo = 0;

    if (!iGame)
        IniStatcontext(&scTotal);

    updateStatisticsGame(plGame);

    if (game_is_last(plGame))
        pl_hint = game_add_pmr_hint(plGame);

    for (pl = plGame->plNext; pl != plGame; pl = pl->plNext) {

        pmr = pl->p;

        FixMatchState(&msExport, pmr);

        switch (pmr->mt) {

        case MOVE_GAMEINFO:

            ApplyMoveRecord(&msExport, plGame, pmr);

            gsz = g_string_new(NULL);
            TextPrologue(gsz, &msExport, iGame);
            fputs(gsz->str, pf);
            g_string_free(gsz, TRUE);

            if (exsExport.fIncludeMatchInfo)
                TextMatchInfo(pf, &mi);

            msOrig = msExport;
            pmgi = &pmr->g;

            psc = &pmr->g.sc;

            AddStatcontext(psc, &scTotal);

            /* FIXME: game introduction */
            break;

        case MOVE_NORMAL:

            if (pmr->fPlayer != msExport.fMove) {
                SwapSides(msExport.anBoard);
                msExport.fMove = pmr->fPlayer;
            }

            msExport.fTurn = msExport.fMove = pmr->fPlayer;
            msExport.anDice[0] = pmr->anDice[0];
            msExport.anDice[1] = pmr->anDice[1];

            gsz = g_string_new(NULL);
            TextBoardHeader(gsz, &msExport, iGame, iMove);
            fputs(gsz->str, pf);
            g_string_free(gsz, TRUE);

            printTextBoard(pf, &msExport);
            gsz = g_string_new(NULL);
            TextAnalysis(gsz, &msExport, pmr);
            fputs(gsz->str, pf);
            g_string_free(gsz, TRUE);

            iMove++;

            break;

        case MOVE_DOUBLE:
        case MOVE_TAKE:
        case MOVE_DROP:

            gsz = g_string_new(NULL);
            TextBoardHeader(gsz, &msExport, iGame, iMove);
            fputs(gsz->str, pf);
            g_string_free(gsz, TRUE);

            printTextBoard(pf, &msExport);

            gsz = g_string_new(NULL);
            TextAnalysis(gsz, &msExport, pmr);
            fputs(gsz->str, pf);
            g_string_free(gsz, TRUE);

            iMove++;

            break;

        default:

            break;

        }

        if (exsExport.fIncludeAnnotation)
            TextPrintComment(pf, pmr);

        ApplyMoveRecord(&msExport, plGame, pmr);

    }

    if (pl_hint)
        game_remove_pmr_hint(pl_hint);

    if (pmgi && pmgi->fWinner != -1) {

        /* print game result */

        fprintf(pf,
                ngettext("%s wins %d point", "%s wins %d points",
                         pmgi->nPoints), ap[pmgi->fWinner].szName, pmgi->nPoints);
    }

    if (psc) {
        gsz = g_string_new(NULL);
        g_string_append_printf(gsz, _("\n\nGame statistics for game %d\n\n"), iGame + 1);
        TextDumpStatcontext(gsz, psc, msOrig.nMatchTo);
        fputs(gsz->str, pf);
        g_string_free(gsz, TRUE);
    }

    if (fLastGame) {
        gsz = g_string_new(NULL);
        if (msOrig.nMatchTo)
            g_string_append_printf(gsz, _("Match statistics\n\n"));
        else
            g_string_append_printf(gsz, _("Session statistics\n\n"));
        TextDumpStatcontext(gsz, &scTotal, msOrig.nMatchTo);

        psc_rel = relational_player_stats_get(ap[0].szName, ap[1].szName);
        if (psc_rel) {
            g_string_append_printf(gsz, _("\nStatistics from database\n\n"));
            TextDumpStatcontext(gsz, psc_rel, 0);
            g_free(psc_rel);
        }
        fputs(gsz->str, pf);
        g_string_free(gsz, TRUE);
    }

    TextEpilogue(pf, &msExport);
}
Пример #6
0
static void
printTextBoard(FILE * pf, const matchstate * pms)
{

    TanBoard anBoard;
    char szBoard[2048];
    char sz[32], szCube[32], szPlayer0[MAX_NAME_LEN + 3], szPlayer1[MAX_NAME_LEN + 3],
        szScore0[35], szScore1[35], szMatch[35];
    char *apch[7] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL };
    unsigned int anPips[2];

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

    apch[0] = szPlayer0;
    apch[6] = szPlayer1;

    if (pms->anScore[0] == 1)
        sprintf(apch[1] = szScore0, _("%d point"), pms->anScore[0]);
    else
        sprintf(apch[1] = szScore0, _("%d points"), pms->anScore[0]);

    if (pms->anScore[1] == 1)
        sprintf(apch[5] = szScore1, _("%d point"), pms->anScore[1]);
    else
        sprintf(apch[5] = szScore1, _("%d points"), pms->anScore[1]);

    if (pms->fDoubled) {
        apch[pms->fTurn ? 4 : 2] = szCube;

        sprintf(szPlayer0, "O: %s", ap[0].szName);
        sprintf(szPlayer1, "X: %s", ap[1].szName);
        sprintf(szCube, _("Cube offered at %d"), pms->nCube << 1);
    } else {
        sprintf(szPlayer0, "O: %s", ap[0].szName);
        sprintf(szPlayer1, "X: %s", ap[1].szName);

        apch[pms->fMove ? 4 : 2] = sz;

        if (pms->anDice[0])
            sprintf(sz, _("Rolled %d%d"), pms->anDice[0], pms->anDice[1]);
        else if (!GameStatus((ConstTanBoard) anBoard, pms->bgv))
            strcpy(sz, _("On roll"));
        else
            sz[0] = 0;

        if (pms->fCubeOwner < 0) {
            apch[3] = szCube;

            if (pms->nMatchTo)
                sprintf(szCube, _("%d point match (Cube: %d)"), pms->nMatchTo, pms->nCube);
            else
                sprintf(szCube, _("(Cube: %d)"), pms->nCube);
        } else {
            size_t cch = strlen(ap[pms->fCubeOwner].szName);

            if (cch > 20)
                cch = 20;

            sprintf(szCube, _("%c: %*s (Cube: %d)"), pms->fCubeOwner ? 'X' :
                    'O', (int) cch, ap[pms->fCubeOwner].szName, pms->nCube);

            apch[pms->fCubeOwner ? 6 : 0] = szCube;

            if (pms->nMatchTo)
                sprintf(apch[3] = szMatch, _("%d point match"), pms->nMatchTo);
        }
    }



    if (pms->fResigned)
        sprintf(strchr(sz, 0), _(", resigns %s"), gettext(aszGameResult[pms->fResigned - 1]));

    if (!pms->fMove)
        SwapSides(anBoard);


    fputs(DrawBoard(szBoard, (ConstTanBoard) anBoard, pms->fMove, apch,
                    MatchIDFromMatchState(pms), anChequers[ms.bgv]), pf);

    PipCount((ConstTanBoard) anBoard, anPips);

    fprintf(pf, "Pip counts: O %u, X %u\n\n", anPips[0], anPips[1]);

}
Пример #7
0
extern int
ParseFIBSBoard(char *pch, TanBoard anBoard,
               char *szPlayer, char *szOpp, int *pnMatchTo,
               int *pnScore, int *pnScoreOpp,
               int anDice[2], int *pnCube, int *pfCubeOwner, int *pfDoubled, int *pfCrawford)
{

    int i, c, n, fCanDouble, fOppCanDouble, anOppDice[2];
    int nTmp, fNonCrawford, fPostCrawford;
    char *szTmp;
    int nTurn, nColor, nDirection;
    int anFIBSBoard[26];

    /* Names and match length/score */
    c = -1;
    sscanf(pch, "board:%31[^:]:%31[^:]:%d:%d:%d:%n", szPlayer, szOpp, pnMatchTo, pnScore, pnScoreOpp, &c);
    if (c < 0)
        return -1;
    pch += c;

    /* FIBS has a maximum match length of 99.  Unlimited matches are 
     * encoded with a match length of 9999.
     */
    if (*pnMatchTo == 9999)
        *pnMatchTo = 0;

    if (*pnMatchTo && (*pnMatchTo <= *pnScore || *pnMatchTo <= *pnScoreOpp))
        return -1;

    /* If the match length exceeds MAXSCORE we correct the match length
     * to MAXSCORE and the scores to the closest equivalents.
     */
    if (*pnMatchTo > MAXSCORE) {
        if (*pnMatchTo - *pnScore > MAXSCORE)
            *pnScore = 0;
        else
            *pnScore -= *pnMatchTo - MAXSCORE;

        if (*pnMatchTo - *pnScoreOpp > MAXSCORE)
            *pnScoreOpp = 0;
        else
            *pnScoreOpp -= *pnMatchTo - MAXSCORE;

        *pnMatchTo = MAXSCORE;
    }

    /* Board */
    for (i = 0; i < 26; ++i) {
        c = -1;
        sscanf(pch, "%d:%n", &n, &c);
        if (c < 0)
            return -1;
        pch += c;
        anFIBSBoard[i] = -n;
    }

    c = -1;
    sscanf(pch, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%*d:%*d:%*d:%*d:%*d:%*d:"
           "%*d:%d:%d:%n", &nTurn, anDice, anDice + 1, anOppDice,
           anOppDice + 1, pnCube, &fCanDouble, &fOppCanDouble,
           pfDoubled, &nColor, &nDirection, &fNonCrawford, &fPostCrawford, &c);
    if (c < 0)
        return -1;

    /* Consistency check: 0 is a valid value for nColor but signifies
     * end of game which is invalid for our purposes here.
     */
    if (!nTurn || !nColor || !nDirection)
        return -1;

    /* Check whether the cube was turned.  That is indicated by the
     * pfDoubed flag for the "player" and by setting the may double
     * flag to zero for both players for the opponent.  Actually
     * we could completely ignore the pfDoubled flag but it could
     * still help, when processing data from other sources than
     * fibs.com.
     */
    if (!*pfDoubled && !fCanDouble && !fOppCanDouble)
        *pfDoubled = 1;

    int fMustSwap = 0;
    if (*pfDoubled)
        fMustSwap = !fMustSwap;
    if (nTurn * nColor < 0)
        fMustSwap = !fMustSwap;

    /* Opponent's turn? */
    if (fMustSwap) {
        szTmp = szPlayer;
        szPlayer = szOpp;
        szOpp = szTmp;
        nTmp = *pnScore;
        *pnScore = *pnScoreOpp;
        *pnScoreOpp = nTmp;
        nTmp = fCanDouble;
        fCanDouble = fOppCanDouble;
        fOppCanDouble = nTmp;
    }

    if (nTurn * nColor < 0)
        nDirection = -nDirection;
    nColor = nTurn > 0 ? 1 : -1;

    for (i = 0; i < 24; ++i) {
        n = nDirection < 0 ? anFIBSBoard[i + 1] : anFIBSBoard[25 - i - 1];
        if (nColor * n < 0) {
            anBoard[1][i] = n < 0 ? -n : n;
            anBoard[0][23 - i] = 0;
        } else if (nColor * n > 0) {
            anBoard[1][i] = 0;
            anBoard[0][23 - i] = n < 0 ? -n : n;
        } else {
            anBoard[1][i] = anBoard[0][23 - i] = 0;
        }
    }

    if (nDirection < 0) {
        n = anFIBSBoard[25];
        anBoard[1][24] = n < 0 ? -n : n;
        n = anFIBSBoard[0];
        anBoard[0][24] = n < 0 ? -n : n;
    } else {
        n = anFIBSBoard[0];
        anBoard[1][24] = n < 0 ? -n : n;
        n = anFIBSBoard[25];
        anBoard[0][24] = n < 0 ? -n : n;
    }

    /* See https://savannah.gnu.org/bugs/?36485 for this.  */
    if (*pfDoubled)
        SwapSides(anBoard);

    if (!anDice[0] && anOppDice[0]) {
        anDice[0] = anOppDice[0];
        anDice[1] = anOppDice[1];
    }

    /*
     * Crawford detection.  This is rather tricky with FIBS board states
     * because FIBS sets both may-double flags to 1 in the Crawford game.
     *
     * We have to inspect the last and second last field for that.
     * The last field is the post-Crawford flag, the second last
     * field is the non-Crawford flag.
     *
     * Until at least one of the players is 1-away, you cannot deduce whether
     * the Crawford rule is in use or not.  Once one of the players
     * is 1-away, the non-Crawford flag is set to 3 if the Crawford rule
     * is not in use; otherwise everything is still 0.
     *
     * Once the Crawford game is finished, the post-Crawford flag is set
     * to 1.
     *
     * Since we cannot find out whether the Crawford rule is in use or not
     * in the pre-Crawford games, the cubeful evaluation can be slightly
     * biased.  But since we the vast majority of matches on FIBS is played
     * with the Crawford rule and we assume usage of the Crawford rule
     * as a default, the bias is negligible.
     */
    if (!*pnMatchTo) {
        *pfCrawford = 0;
    } else {
        if (*pnMatchTo - *pnScore == 1 || *pnMatchTo - *pnScoreOpp == 1) {
            if (fNonCrawford || fPostCrawford) {
                *pfCrawford = 0;
            } else {
                *pfCrawford = 1;
            }
        } else {
            *pfCrawford = 0;
        }
    }

    *pfCubeOwner = fCanDouble != fOppCanDouble ? fCanDouble : -1;

    return 0;
}