I've implemented perft() and divide(), but I've run into an issue where perft() returns a different total number of nodes than divide.
perft("r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - 0 1",2); yields 2053 nodes
divide("r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - 0 1",2); yields a total of 2039 nodes.
I happen to know that the 2039 is the correct number. but I have no idea how to figure out why perft() is overcounting by 14 nodes, especially since divide() calls perft().
here is my perft() code:
Code: Select all
public static void perft(int depth,Game game, long[] stats,boolean verbose)
{
Color color = game.getBoard().getColorToMove();
Color enemy = color.getEnemy();
Collection<Move> moves = game.getBoard().getMoves(color, false);
if (depth == 0)//divide may call perft 0;
{
++stats[0];
}
else for(Move move : moves)
{
game.applyMove(move);
// System.out.println("Applied " + move);
if (!game.getBoard().inCheck(color))
{
if(verbose)
{
for(int i=0;i<(3-depth);++i)
{
System.out.printf(" ");
}
System.out.print("+>" + move);
if (depth == 1)
System.out.print("\t (" + stats[0] + ")");
else
System.out.print(" <" + game.getBoard().getMoves(color, false).size() + ">" + " " + color.toString());
System.out.println();
}
if (move.isCapturingMove()) ++stats[1];
if (move instanceof EnpassantMove) ++stats[2];
if (move instanceof CastleMove) ++stats[3];
if (move instanceof PromotionMove) ++stats[4];
if (game.getBoard().inCheck(enemy))
{
++stats[5];
if (game.getBoard().getMoves(enemy, false).size() == 0) ++stats[6];
}
if (depth == 1) ++stats[0]; //avoid recursive call
else perft(depth - 1, game,stats,verbose);
}
// System.out.println("Undoing " + move);
game.undoMove();
}
Code: Select all
public static void divide(int depth, Game game, boolean verbose)
{
Board board = game.getBoard();
long[] stats = new long[7];
Color color = game.getBoard().getColorToMove();
Collection<Move> legalMoves = game.getBoard().getMoves(color, false);
for(Move move : legalMoves)
{
if (verbose) System.out.println("start:" + move);
long[] localStats = new long[7];
game.applyMove(move);
if (verbose) System.out.println(board);
if (!game.getBoard().inCheck(color))
{
perft(depth-1,game,localStats,verbose);
for(int i=0;i<localStats.length;++i)
{
stats[i]+=localStats[i];
}
if (move instanceof PromotionMove)
{
PromotionMove pmove = (PromotionMove) move;
System.out.println(locationString(pmove.getStartLocation()) + locationString(pmove.getEndLocation()) + pmove.getNewType().toString(Color.WHITE) + " " + localStats[0]);
}
else
{
System.out.println(locationString(move.getStartLocation()) + locationString(move.getEndLocation()) + " " + localStats[0]);
}
}
game.undoMove();
}
System.out.println("Nodes: " + stats[0]);
System.out.println(game.getBoard());
}
Thanks,
Dave