3 Copyright (c) Scott Gasch
11 Test the move generator.
19 $Id: testgenerate.c 345 2007-12-02 22:56:42Z scott $
26 UINT64 g_uPlyTestLeafNodeCount = 0;
27 UINT64 g_uPlyTestTotalNodeCount = 0;
29 extern CHAR *GenerateRandomLegalFenString();
32 PlyTest(SEARCHER_THREAD_CONTEXT *ctx,
38 ULONG uPly = ctx->uPly;
39 ULONG uLegalMoves = 0;
43 memcpy(&board, &(ctx->sPosition), sizeof(POSITION));
46 if (uDepth > MAX_PLY_PER_SEARCH)
52 g_uPlyTestTotalNodeCount++;
53 g_uPlyTestLeafNodeCount++;
56 g_uPlyTestTotalNodeCount++;
59 GenerateMoves(ctx, mv, (fInCheck ? GENERATE_ESCAPES : GENERATE_ALL_MOVES));
60 for (u = ctx->sMoveStack.uBegin[uPly];
61 u < ctx->sMoveStack.uEnd[uPly];
64 mv = ctx->sMoveStack.mvf[u].mv;
65 mv.bvFlags |= WouldGiveCheck(ctx, mv);
67 if (MakeMove(ctx, mv))
70 ASSERT(!InCheck(&ctx->sPosition, GET_COLOR(mv.pMoved)));
71 fGivesCheck = IS_CHECKING_MOVE(mv);
75 ASSERT(InCheck(&ctx->sPosition, FLIP(GET_COLOR(mv.pMoved))));
79 ASSERT(!InCheck(&ctx->sPosition, FLIP(GET_COLOR(mv.pMoved))));
82 PlyTest(ctx, uDepth - 1, fGivesCheck);
84 ASSERT(PositionsAreEquivalent(&board, &ctx->sPosition));
91 TestMoveGenerator(void)
93 typedef struct _TEST_MOVEGEN
103 "3Q4/1Q4Q1/4Q3/2Q4R/Q4Q2/3Q4/1Q4Rp/1K1BBNNk w - - 0 1",
104 { 218, 0, 0, 0, 0, 0, 0 }
107 "r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - - 0 0",
108 { 48, 2039, 97862, 4085603, 193690690ULL, 8031647685ULL }
111 "8/PPP4k/8/8/8/8/4Kppp/8 w - - 0 0",
112 { 18, 290, 5044, 89363, 1745545, 34336777ULL, 749660761ULL }
115 "8/2p5/3p4/KP5r/1R3p1k/8/4P1P1/8 w - - 0 0",
116 { 14, 191, 2812, 43238, 674624, 11030083ULL, 78633661ULL }
119 "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w - - 0 0",
120 { 20, 400, 8902, 197281, 4865609, 119060324ULL, 3195901860ULL }
125 SEARCHER_THREAD_CONTEXT *ctx;
128 Trace("Testing move generator...\n");
129 ctx = SystemAllocateMemory(sizeof(SEARCHER_THREAD_CONTEXT));
131 for (u = 0; u < ARRAY_LENGTH(x); u++)
133 if (FALSE == FenToPosition(&pos, x[u].szFen))
135 UtilPanic(INCONSISTENT_STATE,
136 NULL, NULL, NULL, NULL,
139 InitializeSearcherContext(&pos, ctx);
141 for (v = 1; v <= 4; v++)
143 g_uPlyTestLeafNodeCount = 0;
144 g_uPlyTestTotalNodeCount = 0;
145 PlyTest(ctx, v, FALSE);
147 if ((x[u].uLeaves[v-1]) &&
148 (g_uPlyTestLeafNodeCount != x[u].uLeaves[v-1]))
150 UtilPanic(TESTCASE_FAILURE,
151 NULL, "Perft", NULL, NULL,
156 SystemFreeMemory(ctx);
161 TestLegalMoveGenerator(void)
166 SEARCHER_THREAD_CONTEXT *ctx;
168 ULONG uLegalKingMoves;
169 ULONG uTotalLegalMoves;
172 Trace("Testing legal move generator...\n");
173 ctx = SystemAllocateMemory(sizeof(SEARCHER_THREAD_CONTEXT));
181 p = "8/2K1p2k/1Q2B1p1/2N5/q4q2/3p2Pp/7P/8 w - - 2 0";
184 p = GenerateRandomLegalFenString();
188 if (FALSE == FenToPosition(&pos, p))
190 UtilPanic(TESTCASE_FAILURE,
191 NULL, "FenToPosition", NULL, NULL,
195 if (FALSE == IsBoardLegal(&pos))
200 if (TRUE == InCheck(&pos, pos.uToMove))
202 uLegalKingMoves = uTotalLegalMoves = 0;
203 InitializeSearcherContext(&pos, ctx);
206 GenerateMoves(ctx, mv, GENERATE_ESCAPES);
207 for (v = ctx->sMoveStack.uBegin[0];
208 v < ctx->sMoveStack.uEnd[0];
211 mv = ctx->sMoveStack.mvf[v].mv;
212 ASSERT(mv.bvFlags & MOVE_FLAG_ESCAPING_CHECK);
213 if (TRUE == MakeMove(ctx, mv))
216 if (IS_KING(mv.pMoved))
224 ctx->sMoveStack.mvf[v].mv.uMove = 0;
228 ASSERT(NUM_KING_MOVES(ctx, ctx->uPly) == uLegalKingMoves);
229 if (uTotalLegalMoves > 1)
231 ASSERT(!ONE_LEGAL_MOVE(ctx, ctx->uPly));
233 else if (uTotalLegalMoves == 1)
235 ASSERT(ONE_LEGAL_MOVE(ctx, ctx->uPly));
241 SystemFreeMemory(ctx);