3 Copyright (c) Scott Gasch
11 Test the move generator.
19 $Id: testsup.c 345 2007-12-02 22:56:42Z scott $
26 IsBoardLegal(POSITION *pos)
30 for (c = A1; c <= H1; c++)
32 if (!IS_EMPTY(pos->rgSquare[c].pPiece))
34 if (IS_PAWN(pos->rgSquare[c].pPiece))
41 for (c = A8; c <= H8; c++)
43 if (!IS_EMPTY(pos->rgSquare[c].pPiece))
45 if (IS_PAWN(pos->rgSquare[c].pPiece))
52 if (InCheck(pos, WHITE) &&
58 if (InCheck(pos, FLIP(pos->uToMove)))
67 GenerateRandomLegalPosition(POSITION *pos)
80 memset(pos, 0, sizeof(POSITION));
81 for (u = 0; u < ARRAY_SIZE(pos->cPawns[WHITE]); u++)
83 pos->cPawns[WHITE][u] = pos->cPawns[BLACK][u] = ILLEGAL_COOR;
86 for (u = 0; u < ARRAY_SIZE(pos->cNonPawns[WHITE]); u++)
88 pos->cNonPawns[WHITE][u] = pos->cNonPawns[BLACK][u] = ILLEGAL_COOR;
92 // Place both kings legally
95 ASSERT(IS_ON_BOARD(c));
96 pos->rgSquare[c].pPiece = WHITE_KING;
97 ASSERT(pos->cNonPawns[WHITE][0] == ILLEGAL_COOR);
98 pos->cNonPawns[WHITE][0] = c;
99 pos->uNonPawnCount[WHITE][KING] = 1;
100 pos->uNonPawnCount[WHITE][0] = 1;
101 pos->uNonPawnMaterial[WHITE] = VALUE_KING;
107 while(DISTANCE(c, c1) < 2);
108 ASSERT(IS_ON_BOARD(c1));
109 pos->rgSquare[c1].pPiece = BLACK_KING;
110 ASSERT(pos->cNonPawns[BLACK][0] == ILLEGAL_COOR);
111 pos->cNonPawns[BLACK][0] = c1;
112 pos->uNonPawnCount[BLACK][KING] = 1;
113 pos->uNonPawnCount[BLACK][0] = 1;
114 pos->uNonPawnMaterial[BLACK] = VALUE_KING;
117 // Place the rest of the armies
119 FOREACH_COLOR(uColor)
121 ASSERT(IS_VALID_COLOR(uColor));
124 x < (ULONG)(rand() % 15 + 1);
128 // Pick a random empty square
134 while((pos->rgSquare[c].pPiece) || (RANK1(c) || RANK8(c)));
147 ASSERT(GET_COLOR(p) == uColor);
150 (pos->uPawnCount[uColor] < 8) &&
155 // The pawn list is not ordered at all, add
156 // the new pawn's location to the list and
157 // point from the pawn to the list.
159 pos->cPawns[uColor][pos->uPawnCount[uColor]] = c;
160 pos->rgSquare[c].uIndex = pos->uPawnCount[uColor];
161 pos->rgSquare[c].pPiece = p;
162 pos->uPawnCount[uColor]++;
163 pos->uPawnMaterial[uColor] += VALUE_PAWN;
166 else if (!IS_KING(p) &&
169 uIndex = pos->uNonPawnCount[uColor][0];
170 pos->cNonPawns[uColor][uIndex] = c;
171 pos->uNonPawnCount[uColor][0]++;
172 pos->uNonPawnCount[uColor][PIECE_TYPE(p)]++;
173 pos->rgSquare[c].pPiece = p;
174 pos->rgSquare[c].uIndex = uIndex;
175 pos->uNonPawnMaterial[uColor] += PIECE_VALUE(p);
178 if (IS_WHITE_SQUARE_COOR(c))
180 pos->uWhiteSqBishopCount[uColor]++;
191 ASSERT(pos->uNonPawnCount[WHITE][KING] == 1);
192 ASSERT(pos->uNonPawnCount[BLACK][KING] == 1);
193 //pos->uNonPawnCount[WHITE][0]--;
194 //pos->uNonPawnCount[BLACK][0]--;
197 // Do the rest of the position
199 pos->iMaterialBalance[WHITE] =
200 ((SCORE)(pos->uNonPawnMaterial[WHITE] +
201 pos->uPawnMaterial[WHITE]) -
202 (SCORE)(pos->uNonPawnMaterial[BLACK] +
203 pos->uPawnMaterial[BLACK]));
204 pos->iMaterialBalance[BLACK] = -pos->iMaterialBalance[WHITE];
205 pos->uToMove = RANDOM_COLOR;
206 pos->uFifty = rand() % 100;
207 if (pos->rgSquare[E1].pPiece == WHITE_KING)
209 if (pos->rgSquare[A1].pPiece == WHITE_ROOK)
211 pos->bvCastleInfo |= CASTLE_WHITE_SHORT;
213 if (pos->rgSquare[H1].pPiece == WHITE_ROOK)
215 pos->bvCastleInfo |= CASTLE_WHITE_LONG;
218 if (pos->rgSquare[E8].pPiece == BLACK_KING)
220 if (pos->rgSquare[A8].pPiece == BLACK_ROOK)
222 pos->bvCastleInfo |= CASTLE_BLACK_SHORT;
224 if (pos->rgSquare[H8].pPiece == BLACK_ROOK)
226 pos->bvCastleInfo |= CASTLE_BLACK_LONG;
229 pos->u64NonPawnSig = ComputeSig(pos);
230 pos->u64PawnSig = ComputePawnSig(pos);
235 if (VerifyPositionConsistency(pos, TRUE) &&
236 !InCheck(pos, FLIP(pos->uToMove)))
245 #define SYM_SQ(c) ((7 - (((c) & 0xF0) >> 4)) << 4) \
248 GenerateRandomLegalSymetricPosition(POSITION *pos)
252 ULONG uPieceCount[7];
260 memset(pBoard, 0, sizeof(pBoard));
261 memset(uPieceCount, 0, sizeof(uPieceCount));
263 y = (ULONG)((rand() % 15) + 1);
273 pPiece = (rand() % 5) + 1;
277 if (uPieceCount[PAWN] < 8)
290 if (uPieceCount[pPiece] < 2)
292 uPieceCount[pPiece]++;
296 if (uPieceCount[PAWN] < 8)
317 while (!IS_ON_BOARD(c) ||
319 ((pPiece == PAWN) && ((RANK(c) == 1) || (RANK(c) == 8))));
321 ASSERT(IS_ON_BOARD(xc));
322 ASSERT(IS_EMPTY(pBoard[xc]));
324 pBoard[c] = (pPiece << 1) | WHITE;
325 pBoard[xc] = (pPiece << 1) | BLACK;
333 while (!IS_ON_BOARD(c) ||
336 ASSERT(IS_ON_BOARD(xc));
337 ASSERT(IS_EMPTY(pBoard[xc]));
338 pBoard[c] = WHITE_KING;
339 pBoard[xc] = BLACK_KING;
341 memset(szFen, 0, sizeof(szFen));
343 for (x = 0; x < 120; x++)
347 (x != 0)) *p++ = '/';
349 if (!IS_ON_BOARD(x)) continue;
350 if (0 == pBoard[x]) *p++ = '1';
351 else *p++ = *(PieceAbbrev(pBoard[x]) + 1);
353 strcat(p, " w - - 0 0");
354 FenToPosition(pos, szFen);
356 while(!IsBoardLegal(pos));