//NOT USED!
extern int TryBearoff(ConstTanBoard b, int dice0, int dice1) {

  movelist ml;
  unsigned int i, iMove, cMoves;

  if (ClassifyPosition(msBoard(), VARIATION_STANDARD) > CLASS_RACE) {
    /* It's a contact position; don't automatically bear off */
    printf("> CLASS_RACE!\n");
    return -2;
  }

  GenerateMoves(&ml, b, dice0, dice1, FALSE);
  cMoves = (dice0 == dice1) ? 4 : 2;

  for (i = 0; i < ml.cMoves; i++)
    for (iMove = 0; iMove < cMoves; iMove++) {
      if ((ml.amMoves[i].anMove[iMove << 1] < 0) || (ml.amMoves[i].anMove[(iMove << 1) + 1] != -1)) {
        break;
      } else if (iMove == cMoves - 1) {
        printf("OK\n");
        printMove(ml.amMoves[i].anMove);
        return 0;
      }
    }

  printf("KO\n");
  return -1;
}
OPEN_POS_DATA DetermineFreAndCorDown1LevelForWin(POSITION p)
{
	OPEN_POS_DATA dat=GetOpenData(p);
	MOVELIST* moves=GenerateMoves(p);
	MOVELIST* temp=moves;
	int count=0;
	int minFremoteness=FREMOTENESS_MAX;
	int minCorruption=CORRUPTION_MAX;
	for(; moves; moves=moves->next)
	{
		POSITION child=DoMove(p,moves->move);
		OPEN_POS_DATA cdat=GetOpenData(child);
		if(GetDrawValue(cdat)!=lose || GetLevelNumber(cdat)!=GetLevelNumber(dat)) continue;
		if(GetCorruptionLevel(cdat)==minCorruption && GetFremoteness(cdat)<minFremoteness)
		{
			minFremoteness=GetFremoteness(cdat);
			corruptedPositions[p]=corruptedPositions[p]||corruptedPositions[child];
		}
		if(GetCorruptionLevel(cdat)<minCorruption)
		{
			minCorruption=GetCorruptionLevel(cdat);
			minFremoteness=GetFremoteness(cdat);
			corruptedPositions[p]=corruptedPositions[child];
		}
		count++;
	}
	FreeMoveList(temp);
	if(count==0) return GetOpenData(p);
	dat=SetFremoteness(SetCorruptionLevel(dat,minCorruption),minFremoteness+1);
	return dat;
}
void PopulateEdgelist(EDGELIST *tree) {
	int level;
	POSITION parent, child;
	MOVELIST *childMoves;
	MOVE theMove;
	OPEN_POS_DATA pdata, cdata;
	int resizeCount = 0;
	int resizeLevelCount = 0;

	if(!kLoopy || !gUseOpen)
		level = 0;

	for(parent=0; parent < gNumberOfPositions; parent++) {
		if(GetValueOfPosition(parent) == undecided &&
		   Remoteness(parent) != REMOTENESS_MAX) {
			continue;
		}

		if(Primitive(parent) != undecided) {
			continue;
		} else {
			childMoves = GenerateMoves(parent);
		}

		while(1) {
			theMove = childMoves->move;
			child = DoMove(parent, theMove);

			if(kLoopy && gUseOpen) {
				pdata = GetOpenData(parent);
				cdata = GetOpenData(child);
				level = GetLevelNumber(pdata);
			}

			/* If the level is more than the number in tree, resize to handle more levels */

			if(level > (GameTree.NumberOfLevels - 1)) {
				resizeCount++;
				ResizeTree(&GameTree, level);
			}

			(((GameTree.edges)[level])[(GameTree.nextEdgeInLevel)[level]]).Parent = parent;
			(((GameTree.edges)[level])[(GameTree.nextEdgeInLevel)[level]]).Child = child;
			(GameTree.nextEdgeInLevel)[level] += 1;

			/* Resize an individual level if no room left */

			if(((GameTree.edgesPerLevel)[level] - 2) <= (GameTree.nextEdgeInLevel)[level]) {
				resizeLevelCount++;
				(GameTree.edges)[level] = SafeRealloc((GameTree.edges)[level], (GameTree.edgesPerLevel)[level] * 2 * sizeof(EDGE));
				(GameTree.edgesPerLevel)[level] = (GameTree.edgesPerLevel)[level] * 2;
			}

			if((childMoves = childMoves->next) == NULL) {
				break;
			}
		}
	}
	//printf("Levels resized: %d, tree resized: %d\n", resizeLevelCount, resizeCount);
}
Beispiel #4
0
VALUE Primitive (POSITION position)
{
	if (GenerateMoves(position) != NULL) {
		return undecided;
	} else {
		if(gStandardGame)
			return lose;
		else
			return win;
	}
}
Beispiel #5
0
void BPMiniGame_UnderTheHat::LevelUp() {
	if (Tries >= 10 && SuccessTime == -1) {
		SuccessTime = TheGame->TickCount;
		return;
	}
	
	++CurrentLevel;
	GenerateMoves();
	MakeMove();
	
	ostringstream level;
	level << "Level: " << CurrentLevel << "/10";
	TheGame->AllocString(&sfcCurrentLevel, level.str().c_str(), LARGE, 320, 35, CENTRED, true);
}
BOOL _PositionStruct::IsMate(void) {
  int i, nGenMoveNum, pcCaptured;
  int mvs[MAX_GEN_MOVES];

  nGenMoveNum = GenerateMoves(mvs);
  for (i = 0; i < nGenMoveNum; i ++) {
    pcCaptured = MovePiece(mvs[i]);
    if (!Checked()) {
      UndoMovePiece(mvs[i], pcCaptured);
      return FALSE;
    } else {
      UndoMovePiece(mvs[i], pcCaptured);
    }
  }
  return TRUE;
}
Beispiel #7
0
int ResetTree::IterativeAlphaBeta(int PrimeDepth, int Depth, long long int *MoveCount)
{
  int i;
  int retval;

  // Generate the moves list
  GenerateMoves(PrimeDepth,RUNS_SERIALLY);

  for (i=1;i<=Depth;i++)
  {
    retval = SerialAlphaBetaOnList(i,0,MAX_SCORE,MIN_SCORE,MoveCount);
  }

  DeleteTree(RUNS_SERIALLY);

  return(retval);
}
static void
HyperEquity ( const int nUs, const int nThem,
              hyperequity *phe, const int nC, const hyperequity aheOld[],
              float arNorm[] ) {

  TanBoard anBoard;
  TanBoard anBoardTemp;
  movelist ml;
  int i, j;
  unsigned int k;
  int nUsNew, nThemNew;
  hyperequity heBest;
  hyperequity heOld;
  hyperequity heNew;
  int nPos = Combination ( 25 + nC, nC );
  const hyperequity *phex;
  float r;
  hyperclass hc;

  /* save old hyper equity */

  memcpy ( &heOld, phe, sizeof ( hyperequity ) );

  /* generate board for position */
  
  PositionFromBearoff ( anBoard[ 0 ], nThem, 25, nC );
  PositionFromBearoff ( anBoard[ 1 ], nUs, 25, nC );

  switch ( ( hc = ClassifyHyper ( anBoard ) ) ) {
  case HYPER_OVER:

    HyperOver ( (ConstTanBoard)anBoard, phe->arOutput, nC );

    for ( k = 0; k < 5; ++k )
      phe->arEquity[ k ] = Utility ( phe->arOutput, &ci );

    /* special calc for Jacoby rule */

    phe->arEquity[ EQUITY_CENTER_JACOBY ] = 
      Utility ( phe->arOutput, &ciJacoby );

    return;
    break;

  case HYPER_ILLEGAL:

    return;
    break;

  case HYPER_BEAROFF:
  case HYPER_CONTACT:

    for ( k = 0; k < NUM_OUTPUTS; ++k )
      heNew.arOutput[ k ] = 0.0f;
    for ( k = 0; k < 5; ++k )
      heNew.arEquity[ k ] = 0.0f;

    for ( i = 1; i <= 6; ++i ) 
      for ( j = 1; j <= i; ++j ) {
      
        GenerateMoves ( &ml, (ConstTanBoard)anBoard, i, j, FALSE );

        if ( ml.cMoves ) {

          /* at least one legal move: find the equity of the best move */

          for ( k = 0; k < 5; ++k )
            heBest.arEquity[ k ] = -10000.0f;
        
          for ( k = 0; k < ml.cMoves; ++k ) {
          
            PositionFromKey ( anBoardTemp, &ml.amMoves[ k ].key );
          
            nUsNew = PositionBearoff( anBoardTemp[ 1 ], 25, nC );
            nThemNew = PositionBearoff( anBoardTemp[ 0 ], 25, nC );
          
            g_assert ( nUsNew >= 0 );
            g_assert ( nUsNew < nUs );
            g_assert ( nThemNew >= 0 );

            /* cubeless */

            phex = &aheOld[ nPos * nThemNew + nUsNew ];

            r = - phex->arEquity[ EQUITY_CUBELESS ];
 
            if ( r >= heBest.arEquity[ EQUITY_CUBELESS ] ) {
              memcpy ( heBest.arOutput, phex->arOutput, 
                       NUM_OUTPUTS * sizeof ( float ) );
              InvertEvaluation ( heBest.arOutput );
              heBest.arEquity[ EQUITY_CUBELESS ] = r;
            }

            /* I own cube:
               from opponent's view he doesn't own cube */

            r = - phex->arEquity[ EQUITY_OPPONENT ];
          
            if ( r >= heBest.arEquity[ EQUITY_OWNED ] )
              heBest.arEquity[ EQUITY_OWNED ] = r;

            /* Centered cube, i.e., centered for opponent too */

            r = - CubeEquity ( phex->arEquity[ EQUITY_CENTER ],
                               phex->arEquity[ EQUITY_OPPONENT ],
                               +1.0 );
            
            if ( r >= heBest.arEquity[ EQUITY_CENTER ] )
              heBest.arEquity[ EQUITY_CENTER ] = r;

            /* centered cube with Jacoby rule */

            r = - CubeEquity ( phex->arEquity[ EQUITY_CENTER_JACOBY ],
                               phex->arEquity[ EQUITY_OPPONENT ],
                               +1.0 );
            
            if ( r >= heBest.arEquity[ EQUITY_CENTER_JACOBY ] )
              heBest.arEquity[ EQUITY_CENTER_JACOBY ] = r;

            /* Opponent owns cube: from opponent's view he owns cube */

            r = - CubeEquity ( phex->arEquity[ EQUITY_OWNED ],
                               phex->arEquity[ EQUITY_OPPONENT ],
                               +1.0 );

            if ( r >= heBest.arEquity[ EQUITY_OPPONENT ] )
              heBest.arEquity[ EQUITY_OPPONENT ] = r;

          }

        }
        else {

          /* no legal moves: equity is minus the equity of the reverse
             position, which has the opponent on roll */
          
          memcpy( &heBest, &aheOld[ nPos * nThem  + nUs ], 
                  sizeof ( hyperequity ) );

          InvertEvaluation ( heBest.arOutput );
          
          for ( k = 0; k < 5; ++k )
            heBest.arEquity[ k ] = - heBest.arEquity[ k ];

        }

        /* sum up equities */

        for ( k = 0; k < NUM_OUTPUTS; ++k )
          heNew.arOutput[ k ] += 
            ( i == j ) ? heBest.arOutput[ k ] : 2.0 * heBest.arOutput[ k ];
        for ( k = 0; k < 5; ++k )
          heNew.arEquity[ k ] += 
            ( i == j ) ? heBest.arEquity[ k ] : 2.0 * heBest.arEquity[ k ];

      }
  
    /* normalise */

    for ( k = 0; k < NUM_OUTPUTS; ++k )
      phe->arOutput[ k ] = heNew.arOutput[ k ] / 36.0;
    for ( k = 0; k < 5; ++k )
      phe->arEquity[ k ] = heNew.arEquity[ k ] / 36.0;

    break;

  }

  /* calculate contribution to norm */

  for ( k = 0; k < NUM_OUTPUTS; ++k ) {
    r = fabsf ( phe->arOutput[ k ] - heOld.arOutput[ k ] );
    if ( r > arNorm[ k ] ) {
       arNorm[ k ] = r;
       aiNorm[ k ] = nUs * nPos + nThem;
    }
  }
  for ( k = 0; k < 5; ++k ) {
    r = fabsf( phe->arEquity[ k ] - heOld.arEquity[ k ] );
    if ( r > arNorm[ 5 + k ] ) {
       arNorm[ 5 + k ] = r;
       aiNorm[ 5 + k ] = nUs * nPos + nThem;
    }
  }


}
static void
BearOff2(int nUs, int nThem,
         const int nTSP, const int nTSC,
         short int asiEquity[4], const int n, const int fCubeful, xhash * ph, bearoffcontext * pbc, FILE * pfTmp)
{

    int j, anRoll[2];
    unsigned int i;
    TanBoard anBoard, anBoardTemp;
    movelist ml;
    int aiBest[4];
    int asiBest[4];
    int aiTotal[4];
    short int k;
    short int *psij;
    short int asij[4];
    const short int EQUITY_P1 = 0x7FFF;
    const short int EQUITY_M1 = ~EQUITY_P1;

    if (!nUs) {

        /* we have won */
        asiEquity[0] = asiEquity[1] = asiEquity[2] = asiEquity[3] = EQUITY_P1;
        return;

    }

    if (!nThem) {

        /* we have lost */
        asiEquity[0] = asiEquity[1] = asiEquity[2] = asiEquity[3] = EQUITY_M1;
        return;

    }

    PositionFromBearoff(anBoard[0], nThem, nTSP, nTSC);
    PositionFromBearoff(anBoard[1], nUs, nTSP, nTSC);

    for (i = nTSP; i < 25; i++)
        anBoard[1][i] = anBoard[0][i] = 0;

    /* look for position in bearoff file */

    if (pbc && isBearoff(pbc, (ConstTanBoard) anBoard)) {
        unsigned short int nUsL = (unsigned short) PositionBearoff(anBoard[1], pbc->nPoints, pbc->nChequers);
        unsigned short int nThemL = (unsigned short) PositionBearoff(anBoard[0], pbc->nPoints, pbc->nChequers);
        int nL = Combination(pbc->nPoints + pbc->nChequers, pbc->nPoints);
        unsigned int iPos = nUsL * nL + nThemL;
        unsigned short int aus[4];

        BearoffCubeful(pbc, iPos, NULL, aus);

        for (i = 0; i < 4; ++i)
            asiEquity[i] = aus[i] - 0x8000;

        return;
    }

    aiTotal[0] = aiTotal[1] = aiTotal[2] = aiTotal[3] = 0;

    for (anRoll[0] = 1; anRoll[0] <= 6; anRoll[0]++)
        for (anRoll[1] = 1; anRoll[1] <= anRoll[0]; anRoll[1]++) {
            GenerateMoves(&ml, (ConstTanBoard) anBoard, anRoll[0], anRoll[1], FALSE);

            asiBest[0] = asiBest[1] = asiBest[2] = asiBest[3] = -0xFFFF;
            aiBest[0] = aiBest[1] = aiBest[2] = aiBest[3] = -1;

            for (i = 0; i < ml.cMoves; i++) {
                PositionFromKey(anBoardTemp, &ml.amMoves[i].key);

                j = PositionBearoff(anBoardTemp[1], nTSP, nTSC);

                g_assert(j >= 0);
                g_assert(j < nUs);

                if (!nThem) {
                    asij[0] = asij[1] = asij[2] = asij[3] = EQUITY_P1;
                } else if (!j) {
                    asij[0] = asij[1] = asij[2] = asij[3] = EQUITY_M1;
                }
                if (!(psij = XhashLookup(ph, n * nThem + j))) {
                    /* lookup in file */
                    psij = asij;
                    TSLookup(nThem, j, nTSP, nTSC, psij, n, fCubeful, pfTmp);
                    XhashAdd(ph, n * nThem + j, psij, fCubeful ? 8 : 2);
                }

                /* cubeless */

                if (psij[0] < -asiBest[0]) {
                    aiBest[0] = j;
                    asiBest[0] = ~psij[0];
                }

                if (fCubeful) {

                    /* I own cube:
                     * from opponent's view he doesn't own cube */

                    if (psij[3] < -asiBest[1]) {
                        aiBest[1] = j;
                        asiBest[1] = ~psij[3];
                    }

                    /* Centered cube (so centered for opponent too) */

                    k = CubeEquity(psij[2], psij[3], EQUITY_P1);
                    if (~k > asiBest[2]) {
                        aiBest[2] = j;
                        asiBest[2] = ~k;
                    }

                    /* Opponent owns cube:
                     * from opponent's view he owns cube */

                    k = CubeEquity(psij[1], psij[3], EQUITY_P1);
                    if (~k > asiBest[3]) {
                        aiBest[3] = j;
                        asiBest[3] = ~k;
                    }

                }

            }

            g_assert(aiBest[0] >= 0);
            g_assert(!fCubeful || aiBest[1] >= 0);
            g_assert(!fCubeful || aiBest[2] >= 0);
            g_assert(!fCubeful || aiBest[3] >= 0);

            if (anRoll[0] == anRoll[1])
                for (k = 0; k < (fCubeful ? 4 : 1); ++k)
                    aiTotal[k] += asiBest[k];
            else
                for (k = 0; k < (fCubeful ? 4 : 1); ++k)
                    aiTotal[k] += 2 * asiBest[k];

        }

    /* final equities */
    for (k = 0; k < (fCubeful ? 4 : 1); ++k)
        asiEquity[k] = (short) (aiTotal[k] / 36);

}
static void
NDBearoff(const int iPos, const unsigned int nPoints, float ar[4], xhash * ph, bearoffcontext * pbc)
{

    int d0, d1;
    movelist ml;
    TanBoard anBoard, anBoardTemp;
    int ii, j, k;
    unsigned int i;
#if !defined(G_DISABLE_ASSERT)
    int iBest;
    int iGammonBest;
#endif
    float rBest;
    float rMean;
    float rVarSum, rGammonVarSum;
    float *prj;
    float arj[4] = { 0.0, 0.0, 0.0, 0.0 };
    float arBest[4] = { 0.0, 0.0, 0.0, 0.0 };
    float arGammonBest[4] = { 0.0, 0.0, 0.0, 0.0 };
    float rGammonBest;

    for (i = 0; i < 4; ++i)
        ar[i] = 0.0f;

    if (!iPos)
        return;

    PositionFromBearoff(anBoard[1], iPos, nPoints, 15);

    for (i = nPoints; i < 25; i++)
        anBoard[1][i] = 0;

    /* 
     * look for position in existing bearoff file 
     */

    if (pbc) {
        for (ii = 24; ii >= 0 && !anBoard[1][ii]; --ii);

        if (ii < (int) pbc->nPoints) {
            unsigned int nPosID = PositionBearoff(anBoard[1],
                                                  pbc->nPoints, pbc->nChequers);
            BearoffDist(pbc, nPosID, NULL, NULL, ar, NULL, NULL);
            return;
        }

    }

    memset(anBoard[0], 0, 25 * sizeof(int));

    for (i = 0, k = 0; i < nPoints; ++i)
        k += anBoard[1][i];

    /* loop over rolls */

    rVarSum = rGammonVarSum = 0.0f;

    for (d0 = 1; d0 <= 6; ++d0)
        for (d1 = 1; d1 <= d0; ++d1) {

            GenerateMoves(&ml, (ConstTanBoard) anBoard, d0, d1, FALSE);

            rBest = 1e10;
            rGammonBest = 1e10;
#if !defined(G_DISABLE_ASSERT)
            iBest = -1;
            iGammonBest = -1;
#endif

            for (i = 0; i < ml.cMoves; ++i) {

                PositionFromKey(anBoardTemp, &ml.amMoves[i].key);

                j = PositionBearoff(anBoardTemp[1], nPoints, 15);

                if (!(prj = XhashLookup(ph, j))) {
                    prj = arj;
                    NDBearoff(j, nPoints, prj, ph, pbc);
                    XhashAdd(ph, j, prj, 16);
                }

                /* find best move to win */

                if (prj[0] < rBest) {
#if !defined(G_DISABLE_ASSERT)
                    iBest = j;
#endif
                    rBest = prj[0];
                    memcpy(arBest, prj, 4 * sizeof(float));
                }

                /* find best move to save gammon */

                if (prj[2] < rGammonBest) {
#if !defined(G_DISABLE_ASSERT)
                    iGammonBest = j;
#endif
                    rGammonBest = prj[2];
                    memcpy(arGammonBest, prj, 4 * sizeof(float));
                }

            }

            g_assert(iBest >= 0);
            g_assert(iGammonBest >= 0);

            rMean = 1.0f + arBest[0];

            ar[0] += (d0 == d1) ? rMean : 2.0f * rMean;

            rMean = arBest[1] * arBest[1] + rMean * rMean;

            rVarSum += (d0 == d1) ? rMean : 2.0f * rMean;

            if (k == 15) {

                rMean = 1.0f + arGammonBest[2];

                ar[2] += (d0 == d1) ? rMean : 2.0f * rMean;

                rMean = arGammonBest[3] * arGammonBest[3] + rMean * rMean;

                rGammonVarSum += (d0 == d1) ? rMean : 2.0f * rMean;

            }

        }

    ar[0] /= 36.0f;
    ar[1] = sqrtf(rVarSum / 36.0f - ar[0] * ar[0]);

    ar[2] /= 36.0f;
    ar[3] = sqrtf(rGammonVarSum / 36.0f - ar[2] * ar[2]);

}
static void
BearOff(int nId, unsigned int nPoints,
        unsigned short int aOutProb[64],
        const int fGammon, xhash * ph, bearoffcontext * pbc, const int fCompress, FILE * pfOutput, FILE * pfTmp)
{
#if !defined(G_DISABLE_ASSERT)
    int iBest;
#endif
    int iMode, j, anRoll[2], aProb[64];
    unsigned int i;
    TanBoard anBoard, anBoardTemp;
    movelist ml;
    int k;
    unsigned int us;
    unsigned int usBest;
    unsigned short int *pusj;
    unsigned short int ausj[64];
    unsigned short int ausBest[32];

    unsigned int usGammonBest;
    unsigned short int ausGammonBest[32];
    unsigned int nBack;

    /* get board for given position */

    PositionFromBearoff(anBoard[1], nId, nPoints, 15);

    /* initialise probabilities */

    for (i = 0; i < 64; i++)
        aProb[i] = aOutProb[i] = 0;

    /* all chequers off is easy :-) */

    if (!nId) {
        aOutProb[0] = 0xFFFF;
        aOutProb[32] = 0xFFFF;
        return;
    }

    /* initialise the remainder of the board */

    for (i = nPoints; i < 25; i++)
        anBoard[1][i] = 0;

    for (i = 0; i < 25; i++)
        anBoard[0][i] = 0;

    nBack = 0;
    for (i = 0, k = 0; i < nPoints; ++i) {
        if (anBoard[1][i])
            nBack = i;
        k += anBoard[1][i];
    }

    /* look for position in existing bearoff file */

    if (pbc && nBack < pbc->nPoints) {
        unsigned int nPosID = PositionBearoff(anBoard[1],
                                              pbc->nPoints, pbc->nChequers);
        BearoffDist(pbc, nPosID, NULL, NULL, NULL, aOutProb, aOutProb + 32);
        return;
    }

    if (k < 15)
        aProb[32] = 0xFFFF * 36;

    for (anRoll[0] = 1; anRoll[0] <= 6; anRoll[0]++)
        for (anRoll[1] = 1; anRoll[1] <= anRoll[0]; anRoll[1]++) {
            GenerateMoves(&ml, (ConstTanBoard) anBoard, anRoll[0], anRoll[1], FALSE);

            usBest = 0xFFFFFFFF;
#if !defined(G_DISABLE_ASSERT)
            iBest = -1;
#endif
            usGammonBest = 0xFFFFFFFF;

            for (i = 0; i < ml.cMoves; i++) {
                PositionFromKey(anBoardTemp, &ml.amMoves[i].key);

                j = PositionBearoff(anBoardTemp[1], nPoints, 15);

                g_assert(j >= 0);
                g_assert(j < nId);


                if (!j) {

                    memset(pusj = ausj, 0, fGammon ? 128 : 64);
                    pusj[0] = 0xFFFF;
                    pusj[32] = 0xFFFF;

                } else if (!(pusj = XhashLookup(ph, j))) {
                    /* look up in file generated so far */
                    pusj = ausj;
                    OSLookup(j, nPoints, pusj, fGammon, fCompress, pfOutput, pfTmp);

                    XhashAdd(ph, j, pusj, fGammon ? 128 : 64);
                }

                /* find best move to win */

                if ((us = RollsOS(pusj)) < usBest) {
#if !defined(G_DISABLE_ASSERT)
                    iBest = j;
#endif
                    usBest = us;
                    memcpy(ausBest, pusj, 64);
                }

                /* find best move to save gammon */

                if (fGammon && ((us = RollsOS(pusj + 32)) < usGammonBest)) {
                    usGammonBest = us;
                    memcpy(ausGammonBest, pusj + 32, 64);
                }

            }

            g_assert(iBest >= 0);
            /* g_assert( iGammonBest >= 0 ); */

            if (anRoll[0] == anRoll[1]) {
                for (i = 0; i < 31; i++) {
                    aProb[i + 1] += ausBest[i];
                    if (k == 15 && fGammon)
                        aProb[32 + i + 1] += ausGammonBest[i];
                }
            } else {
                for (i = 0; i < 31; i++) {
                    aProb[i + 1] += 2 * ausBest[i];
                    if (k == 15 && fGammon)
                        aProb[32 + i + 1] += 2 * ausGammonBest[i];
                }
            }
        }

    for (i = 0, j = 0, iMode = 0; i < 32; i++) {
        j += (aOutProb[i] = (unsigned short) ((aProb[i] + 18) / 36));
        if (aOutProb[i] > aOutProb[iMode])
            iMode = i;
    }

    aOutProb[iMode] -= (j - 0xFFFF);

    /* gammon probs */

    if (fGammon) {
        for (i = 0, j = 0, iMode = 0; i < 32; i++) {
            j += (aOutProb[32 + i] = (unsigned short) ((aProb[32 + i] + 18) / 36));
            if (aOutProb[32 + i] > aOutProb[32 + iMode])
                iMode = i;
        }

        aOutProb[32 + iMode] -= (j - 0xFFFF);
    }

}
VALUE DetermineZeroValue(POSITION position)
{
	POSITION i,lowSeen,highSeen;
	POSITION numUndecided, oldNumUndecided, numNew;
	MOVELIST *moveptr, *headMove;
	POSITION child;
	VALUE childValue;
	POSITION numTot, numWin, numTie;
	int tieRemoteness, winRemoteness;

	//if (gTwoBits)
	//    InitializeVisitedArray();

	StoreValueOfPosition(position,Primitive(position));
	MarkAsVisited(position);
	oldNumUndecided = 0;
	numUndecided = 1;
	numNew = 1;

	lowSeen = position;
	highSeen = lowSeen+1;

	while((numUndecided != oldNumUndecided) || (numNew != 0)) {

		oldNumUndecided = numUndecided;
		numUndecided = 0;
		numNew = 0;
		for(i = lowSeen; i <= highSeen; i++) {
			if(Visited(i)) {
				if(GetValueOfPosition(i) == undecided) {
					moveptr = headMove = GenerateMoves(i);
					numTot = numWin = numTie = 0;
					tieRemoteness = winRemoteness = REMOTENESS_MAX;
					while(moveptr != NULL) {
						child = DoMove(i,moveptr->move);
						numTot++;
						if(Visited(child))
							childValue = GetValueOfPosition(child);
						else{
							childValue = Primitive(child);
							numNew++;
							MarkAsVisited(child);
							StoreValueOfPosition(child,childValue);
							if(childValue != undecided) {
								SetRemoteness(child,0);
							}
							if(child < lowSeen) lowSeen = child;
							if(child > highSeen) highSeen = child + 1;
						}

						if(childValue == lose) {
							StoreValueOfPosition(i,win);
							if(Remoteness(i) > Remoteness(child)+1)
								SetRemoteness(i,Remoteness(child)+1);
						}

						if(childValue == win) {
							numWin++;
							if(Remoteness(child) < winRemoteness) {
								winRemoteness = Remoteness(child);
							}
						}
						if(childValue == tie) {
							numTie++;
							if(Remoteness(child) < tieRemoteness) {
								tieRemoteness = Remoteness(child);
							}
						}

						moveptr = moveptr->next;
					}
					FreeMoveList(headMove);
					if((numTot != 0) && (numTot == numWin + numTie)) {
						if(numTie == 0) {
							SetRemoteness(i, winRemoteness+1);
							StoreValueOfPosition(i,lose);
						}else{
							SetRemoteness(i, tieRemoteness+1);
							StoreValueOfPosition(i,tie);
						}
					}

					if(GetValueOfPosition(i) == undecided)
						numUndecided++;
				}
			}
		}

		printf("\nnumUndecided: " POSITION_FORMAT ", diff: " POSITION_FORMAT ", numNew: " POSITION_FORMAT
		       ", lowSeen: " POSITION_FORMAT ", highSeen: " POSITION_FORMAT,
		       numUndecided,numUndecided - oldNumUndecided,numNew,lowSeen,highSeen);

	}

	for(i = 0; i < gNumberOfPositions; i++) {
		if(Visited(i) && (GetValueOfPosition(i) == undecided)) {
			SetRemoteness(i,REMOTENESS_MAX);
			StoreValueOfPosition(i, tie);
		}
		UnMarkAsVisited(i);
	}

	return GetValueOfPosition(position);
}
Beispiel #13
0
bool MoveGeneratorNormal::IsValidMove(const Move& move) {
  MoveArray move_array;
  GenerateMoves(&move_array);
  return move_array.Contains(move);
}
Beispiel #14
0
int MoveGeneratorNormal::CountMoves() {
  MoveArray move_array;
  GenerateMoves(&move_array);
  return move_array.size();
}
Beispiel #15
0
void BPMiniGame_UnderTheHat::Tick() {
	if (SuccessTime != -1 && SuccessTime + 250 < TheGame->TickCount) {
		Success();
		return;
	}
	
	if (BackgroundUp) {
		BackgroundFade += 0.0025f;
		if (BackgroundFade >= 1.0f) {
			BackgroundUp = false;
		}
	} else {
		BackgroundFade -= 0.0025f;
		
		if (BackgroundFade <= 0.0f) {
			BackgroundUp = true;
		}
	}
	
	switch (State) {
		case SHOWING:
			break;
			
		case WAITING:
			if (LastStateChange + 1000 < TheGame->TickCount) {
				State = MOVING;
				MoveAmount = 0.0f;
			}
			break;
			
		case CORRECT:
			if (LastStateChange + 1750 < TheGame->TickCount) {
				LevelUp();
				State = MOVING;
			}
			
			break;
			
		case WRONG:
			if (LastStateChange + 1750 < TheGame->TickCount) {
				GenerateMoves();
				State = MOVING;
			}
			
			break;
			
		case MOVING:
			if (MoveAmount < 1.0f) {
				MoveAmount += 0.1f * TheGame->ElapsedSeconds * MoveSpeed;
				
				for (int i = 0; i < Hats.Count; ++i) {
					BPMiniGame_UnderTheHat_Hat* hat = Hats[i];
					hat->X = TheGame->SmoothStep(hat->StartX, hat->DestX, MoveAmount);
					hat->Y = TheGame->SmoothStep(hat->StartY, hat->DestY, MoveAmount);
				}
			} else {
				if (MovesLeft > 0) {
					// finished a previous move, but we have more moves to do
					MakeMove();
				} else {
					// finished moving - time to guess!
					State = GUESSING;
					ChosenHat = NULL;
				}
			}			
			break;
	}
}
void ComputeOpenPositions()
{
	int curLevel=1;
	POSITION iter;
	InitializeOpenPositions(gNumberOfPositions);
	if(!openPosData) return;
	//PrintChildrenCounts();

	InitializeFR();

	while(1)
	{
		int fringePosCount=0;
		int maxCorruption=0;
		int i;
		/* first, find all fringe positions */
		printf("Get going!\n");
		for(iter=0; iter<gNumberOfPositions; iter++)
		{
			OPEN_POS_DATA dat=GetOpenData(iter);

			/* if the number of children of an undecided value is less than the original number of children but >0, it
			   has a winning child and is therefore a fringe */
			//printf("Pos %d has %d/%d children\n",iter,(int)gNumberChildren[iter],(int)gNumberChildrenOriginal[iter]);
			if(gNumberChildren[iter]>0&&gNumberChildren[iter]<gNumberChildrenOriginal[iter]&&GetDrawValue(dat)==undecided && GetValueOfPosition(iter)==tie && Remoteness(iter)==REMOTENESS_MAX)
			{
				if(curLevel==1) dat=SetCorruptionLevel(dat,0);
				else
				{
					int maxWinChildCorr=0;
					MOVELIST* moves=GenerateMoves(iter);
					MOVELIST* temp=moves;
					for(; moves; moves=moves->next)
					{
						POSITION child=DoMove(iter,moves->move);
						OPEN_POS_DATA cdat=GetOpenData(child);
						if(GetDrawValue(cdat)!=win) continue;
						if(GetCorruptionLevel(cdat)>maxWinChildCorr) maxWinChildCorr=GetCorruptionLevel(cdat);
					}
					FreeMoveList(temp);
					dat=SetCorruptionLevel(dat,maxWinChildCorr);
				}
				//printf("Corruption level of %d is %d\n",iter,GetCorruptionLevel(dat));
				SetOpenData(iter,SetFringe(SetLevelNumber(SetFremoteness(SetDrawValue(dat,lose),0),curLevel),1));
				InsertLoseFR(iter);
				fringePosCount++;
				fringePositions[iter]=1;
			}
		}
		/* if we didn't find any fringe positions, we just label everyone else as pure ties */
		if(fringePosCount==0) {
			//printf("Done!!!\n");
			gAnalysis.LargestFoundLevel = curLevel-1;                               //MATT
			break;
		}
		/* do paper-ish solving of the level.  Corruption and Fremoteness propogate up here */
		while(gHeadLoseFR || gHeadWinFR)
		{
			//printf("HERE\n");
			while(gHeadLoseFR)
			{
				POSITION pos=DeQueueLoseFR();
				POSITIONLIST* parents=gParents[pos];
				OPEN_POS_DATA dat=GetOpenData(pos);
				//printf("Looping!\n");
				for(; parents; parents=parents->next)
				{
					OPEN_POS_DATA pdat;
					OPEN_POS_DATA old;
					if(!(GetValueOfPosition(parents->position)==tie && Remoteness(parents->position)==REMOTENESS_MAX)) continue;
					pdat=GetOpenData(parents->position);
					/* If my parent is already a lose and not already corrupted, corrupt it and move on */
					if(GetDrawValue(pdat)==lose)
					{
						if(!corruptedPositions[parents->position]&&GetFringe(pdat))
						{
							corruptedPositions[parents->position]=1;
							pdat=SetCorruptionLevel(pdat,GetCorruptionLevel(pdat)+1);
							SetOpenData(parents->position,pdat);
							if(GetCorruptionLevel(pdat)>curLevel)
							{
								printf("This is not good!\n");
								PrintSingleOpenData(parents->position);
							}
							PropogateFreAndCorUp(parents->position);
							if(GetCorruptionLevel(pdat)>maxCorruption)
							{
								maxCorruption=GetCorruptionLevel(pdat);
							}
							if(GetFremoteness(pdat)>0)
							{
								printf("No, no, no!!!");
							}
						}
						continue;
					}
					//printf("Parent: %d\n",parents->position);
					if(GetFringe(pdat)) continue;
					old=pdat;
					pdat=SetDrawValue(pdat,win);
					pdat=SetLevelNumber(pdat,curLevel);
					if(GetFremoteness(pdat)>GetFremoteness(dat)+1 || GetDrawValue(old)==undecided)
						pdat=SetFremoteness(pdat,GetFremoteness(dat)+1);
					if(GetCorruptionLevel(pdat)>GetCorruptionLevel(dat) || GetCorruptionLevel(pdat)==CORRUPTION_MAX)
					{
						pdat=SetCorruptionLevel(pdat,GetCorruptionLevel(dat));
						corruptedPositions[parents->position]=corruptedPositions[pos];
					}
					SetOpenData(parents->position,pdat);
					if(pdat!=old)
					{
						InsertWinFR(parents->position);
					}
					if(GetCorruptionLevel(pdat)!=GetCorruptionLevel(old) || GetFremoteness(pdat)!=GetFremoteness(old))
					{
						PropogateFreAndCorUp(parents->position);
					}
				}
			}
			//PrintOpenDataFormatted();
			//printf("HERE1\n");
			while(gHeadWinFR)
			{
				POSITION pos=DeQueueWinFR();
				POSITIONLIST* parents=gParents[pos];
				OPEN_POS_DATA dat=GetOpenData(pos);
				char timeToBreak=0;
				if(pos==kBadPosition) continue;
				for(; parents; parents=parents->next)
				{
					OPEN_POS_DATA pdat;
					OPEN_POS_DATA old;
					if(!(GetValueOfPosition(parents->position)==tie && Remoteness(parents->position)==REMOTENESS_MAX)) continue;
					pdat=GetOpenData(parents->position);
					if(GetFringe(pdat)) continue;
					if(--gNumberChildren[parents->position]==0)
					{
						pdat=SetDrawValue(pdat,lose);
						pdat=SetLevelNumber(pdat,curLevel);
						SetOpenData(parents->position,pdat);
						InsertLoseFR(parents->position);
						timeToBreak=1;
					}
					old=pdat;
					if(GetFremoteness(pdat)<GetFremoteness(dat)+1 && !GetFringe(pdat))
						pdat=SetFremoteness(pdat,GetFremoteness(dat)+1);
					if((GetCorruptionLevel(pdat)<GetCorruptionLevel(dat) || GetCorruptionLevel(pdat)==CORRUPTION_MAX) && GetDrawValue(pdat)==lose)
					{
						pdat=SetCorruptionLevel(pdat,GetCorruptionLevel(dat));
						corruptedPositions[parents->position]=corruptedPositions[pos];
					}
					SetOpenData(parents->position,pdat);
					if(pdat!=old) PropogateFreAndCorUp(parents->position);
				}
				if(timeToBreak) break;
			}
		}
		//printf("HERE!!!!!!!\n");
		/* all that's left is to do fixing at each corruption level. */
		for(i=0; i<curLevel; i++)
		{
			/* load the win/lose frontier and subtract off children from the counts of their parents if they're not in the
			   current level and they are losing */
			for(iter=0; iter<gNumberOfPositions; iter++)
			{
				OPEN_POS_DATA dat=GetOpenData(iter);
				corruptedPositions[iter]=0;
				if(GetFringe(dat) && GetFremoteness(dat)) printf("ASDFDASFDASDFA!\n");
				if((GetCorruptionLevel(dat)>i && GetDrawValue(dat)==lose && GetLevelNumber(dat)==curLevel))
				{
					if(GetDrawValue(dat)==undecided) continue;
					AddToParentsChildrenCount(iter,-1);
				}
				else if(GetCorruptionLevel(dat)==i && GetLevelNumber(dat)==curLevel)
				{
					if(GetDrawValue(dat)==win)
					{
						InsertWinFR(iter);
						AddToParentsChildrenCount(iter,1);
					}
					else if(GetDrawValue(dat)==lose)
						InsertLoseFR(iter);
				}
			}
			/* solve, fixing */
			printf("here1\n");
			while(gHeadLoseFR || gHeadWinFR)
			{
				printf("here1.1\n");
				while(gHeadLoseFR)
				{
					POSITION pos=DeQueueLoseFR();
					POSITIONLIST* parents=gParents[pos];
					OPEN_POS_DATA dat=GetOpenData(pos);
					for(; parents; parents=parents->next)
					{
						OPEN_POS_DATA pdat=GetOpenData(parents->position);
						OPEN_POS_DATA old;
						if(!(GetValueOfPosition(parents->position)==tie && Remoteness(parents->position)==REMOTENESS_MAX)) continue;
						old=pdat;
						/* If I've got a losing parent of the same corruption level, it's legit. */
						if(GetDrawValue(pdat)==lose && GetCorruptionLevel(pdat)==i) continue;
						pdat=SetDrawValue(pdat,win);
						pdat=SetLevelNumber(pdat,curLevel);
						fringePositions[parents->position]=0;
						pdat=SetFringe(pdat, 0);
						if(GetCorruptionLevel(pdat)<i) continue;
						if(GetCorruptionLevel(pdat)>i)
						{
							pdat=SetCorruptionLevel(pdat, i);
							pdat=SetFremoteness(pdat, GetFremoteness(dat)+1);
						}
						if((GetFremoteness(pdat)>GetFremoteness(dat)+1 || GetDrawValue(old)!=GetDrawValue(pdat)) && !GetFringe(old))
							pdat=SetFremoteness(pdat,GetFremoteness(dat)+1);
						if(GetDrawValue(old)==GetDrawValue(pdat) && GetCorruptionLevel(old)==GetCorruptionLevel(pdat) && GetFringe(old)) continue;
						SetOpenData(parents->position,pdat);
						if(GetFremoteness(pdat) && GetFringe(pdat)) printf("Dis not good\n");
						//printf("start propogating\n");
						//PrintSingleOpenData(parents->position);
						if(pdat!=old) PropogateFreAndCorUpFringe(parents->position,0);
						//printf("done propogating\n");
						if(pdat!=old || GetDrawValue(pdat)!=GetDrawValue(old))
						{
							InsertWinFR(parents->position);
						}
						if(GetDrawValue(pdat)==win && GetDrawValue(old)==lose)
						{
							AddToParentsChildrenCount(parents->position,1);
							//if(GetLevelNumber(pdat)==2) printf("l-->w%d\n",parents->position);
						}
						//else if(pdat!=old && GetLevelNumber(pdat)==2) printf("-->w%d\n",parents->position);
					}
				}
				printf("here1.2\n");
				while(gHeadWinFR)
				{
					POSITION pos=DeQueueWinFR();
					POSITIONLIST* parents=gParents[pos];
					OPEN_POS_DATA dat=GetOpenData(pos);
					char timeToBreak=0;

					for(; parents; parents=parents->next)
					{
						OPEN_POS_DATA pdat;
						OPEN_POS_DATA old;
						if(!(GetValueOfPosition(parents->position)==tie && Remoteness(parents->position)==REMOTENESS_MAX)) continue;
						pdat=GetOpenData(parents->position);
						old=pdat;
						if(GetCorruptionLevel(pdat)<i) continue;
						if(--gNumberChildren[parents->position]==0)
						{
							pdat=SetDrawValue(pdat,lose);
							pdat=SetLevelNumber(pdat,curLevel);
							pdat=SetCorruptionLevel(pdat,i);
							SetOpenData(parents->position,pdat);
							fringePositions[parents->position]=0;
							pdat=SetFringe(pdat,0);
							InsertLoseFR(parents->position);
							timeToBreak=1;
						}
						if(GetFremoteness(pdat) && GetFringe(pdat)) printf("Dis not good2.0\n");
						//winning positions cannot uncorrupt above them unless they've actually fixed the parent
						/*if(GetCorruptionLevel(pdat)>GetCorruptionLevel(dat) && GetDrawValue(pdat)==lose)
						   {
						        pdat=SetCorruptionLevel(pdat,GetCorruptionLevel(dat));
						        pdat=SetFremoteness(pdat,GetFremoteness(dat)+1);
						        if(GetFremoteness(pdat) && GetFringe(pdat)) printf("Dis not good2.1\n");
						   }
						   else*/if(GetCorruptionLevel(pdat)==GetCorruptionLevel(dat) && GetFremoteness(pdat)<GetFremoteness(dat)+1 && !GetFringe(pdat) && !(GetDrawValue(pdat)==win && GetCorruptionLevel(pdat)==i))
						{
							pdat=SetFremoteness(pdat,GetFremoteness(dat)+1);
							if(GetFremoteness(pdat) && GetFringe(pdat)) printf("Dis not good2.2\n");
						}
						if(GetDrawValue(old)==GetDrawValue(pdat) && GetCorruptionLevel(old)==GetCorruptionLevel(pdat) && GetFringe(old)) continue;
						SetOpenData(parents->position,pdat);
						if(GetFremoteness(pdat) && GetFringe(pdat)) printf("Dis not good2\n");
						if(pdat!=old) PropogateFreAndCorUpFringe(parents->position,0);
						if(GetDrawValue(old)==win && GetDrawValue(pdat)==lose) AddToParentsChildrenCount(parents->position,1);
					}
					//printf("Done fixing:\n");
					if(timeToBreak) break;
				}
			}
			/* undo our first step after having fixed */
			for(iter=0; iter<gNumberOfPositions; iter++)
			{
				OPEN_POS_DATA dat=GetOpenData(iter);
				if(GetCorruptionLevel(dat)>i && GetDrawValue(dat)==lose && GetLevelNumber(dat)==curLevel)
				{
					if(GetDrawValue(dat)==undecided) continue;
					AddToParentsChildrenCount(iter,1);
				}
			}
			printf("here2\n");
		}
		//PrintChildrenCounts();

		curLevel++;
	}
	/* One more thing... find loop lengths for fringe positions and label drawdraws */
	for(iter=0; iter<gNumberOfPositions; iter++)
	{
		int maxFremote=0;
		OPEN_POS_DATA dat=GetOpenData(iter);
		MOVELIST* moves;
		//printf("There%d\n",iter);
		//PrintSingleOpenData(iter);
		if(GetValueOfPosition(iter)==tie && Remoteness(iter)==REMOTENESS_MAX) {
			if (GetDrawValue(dat) == undecided) {
				dat=SetDrawValue(dat,tie);
				dat=SetFremoteness(dat,0xFFFFFFFF);
				SetOpenData(iter,dat);
				gAnalysis.DrawDraws +=1;                                        //MATT
			} else {
				gAnalysis.DetailedOpenSummary[GetLevelNumber(dat)][GetCorruptionLevel(dat)][GetFremoteness(dat)][GetDrawValue(dat)]+=1;
				gAnalysis.OpenSummary[GetDrawValue(dat)]+=1;
				if(GetCorruptionLevel(dat)>gAnalysis.LargestFoundCorruption) gAnalysis.LargestFoundCorruption=GetCorruptionLevel(dat);  //MATT/David
			}
			if(GetCorruptionLevel(dat)>GetLevelNumber(dat)) PrintSingleOpenData(iter);
			if(GetDrawValue(dat)==win && GetFremoteness(dat)==0) PrintSingleOpenData(iter);
		}
		else continue;
		if(!GetFringe(dat)) continue;
		if(GetFremoteness(dat)!=0)
		{
			printf("ACKKKK!\n");
			PrintSingleOpenData(iter);
		}
		moves=GenerateMoves(iter);
		for(; moves; moves=moves->next)
		{
			POSITION child=DoMove(iter,moves->move);
			OPEN_POS_DATA cdat=GetOpenData(child);
			if(!GetFringe(cdat) && GetLevelNumber(cdat)==GetLevelNumber(dat) && GetFremoteness(cdat)>maxFremote)
				maxFremote=GetFremoteness(cdat);
		}
		dat=SetFremoteness(dat,maxFremote+1);
		SetOpenData(iter,dat);
	}
	CleanupOpenPositions();
	return;
}
Beispiel #17
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);
  }

}