summaryrefslogtreecommitdiff
path: root/src/testsup.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/testsup.c')
-rw-r--r--src/testsup.c357
1 files changed, 357 insertions, 0 deletions
diff --git a/src/testsup.c b/src/testsup.c
new file mode 100644
index 0000000..43e39e9
--- /dev/null
+++ b/src/testsup.c
@@ -0,0 +1,357 @@
+/**
+
+Copyright (c) Scott Gasch
+
+Module Name:
+
+ testgenerate.c
+
+Abstract:
+
+ Test the move generator.
+
+Author:
+
+ Scott Gasch ([email protected]) 8 April 2005
+
+Revision History:
+
+ $Id: testsup.c 345 2007-12-02 22:56:42Z scott $
+
+**/
+
+#include "chess.h"
+
+FLAG
+IsBoardLegal(POSITION *pos)
+{
+ COOR c;
+
+ for (c = A1; c <= H1; c++)
+ {
+ if (!IS_EMPTY(pos->rgSquare[c].pPiece))
+ {
+ if (IS_PAWN(pos->rgSquare[c].pPiece))
+ {
+ return(FALSE);
+ }
+ }
+ }
+
+ for (c = A8; c <= H8; c++)
+ {
+ if (!IS_EMPTY(pos->rgSquare[c].pPiece))
+ {
+ if (IS_PAWN(pos->rgSquare[c].pPiece))
+ {
+ return(FALSE);
+ }
+ }
+ }
+
+ if (InCheck(pos, WHITE) &&
+ InCheck(pos, BLACK))
+ {
+ return(FALSE);
+ }
+
+ if (InCheck(pos, FLIP(pos->uToMove)))
+ {
+ return(FALSE);
+ }
+ return(TRUE);
+}
+
+
+void
+GenerateRandomLegalPosition(POSITION *pos)
+{
+ COOR c, c1;
+ ULONG x, uIndex;
+ ULONG uColor;
+ PIECE p;
+ ULONG u;
+
+ do
+ {
+ //
+ // Clear the board
+ //
+ memset(pos, 0, sizeof(POSITION));
+ for (u = 0; u < ARRAY_SIZE(pos->cPawns[WHITE]); u++)
+ {
+ pos->cPawns[WHITE][u] = pos->cPawns[BLACK][u] = ILLEGAL_COOR;
+ }
+
+ for (u = 0; u < ARRAY_SIZE(pos->cNonPawns[WHITE]); u++)
+ {
+ pos->cNonPawns[WHITE][u] = pos->cNonPawns[BLACK][u] = ILLEGAL_COOR;
+ }
+
+ //
+ // Place both kings legally
+ //
+ c = RANDOM_COOR;
+ ASSERT(IS_ON_BOARD(c));
+ pos->rgSquare[c].pPiece = WHITE_KING;
+ ASSERT(pos->cNonPawns[WHITE][0] == ILLEGAL_COOR);
+ pos->cNonPawns[WHITE][0] = c;
+ pos->uNonPawnCount[WHITE][KING] = 1;
+ pos->uNonPawnCount[WHITE][0] = 1;
+ pos->uNonPawnMaterial[WHITE] = VALUE_KING;
+
+ do
+ {
+ c1 = RANDOM_COOR;
+ }
+ while(DISTANCE(c, c1) < 2);
+ ASSERT(IS_ON_BOARD(c1));
+ pos->rgSquare[c1].pPiece = BLACK_KING;
+ ASSERT(pos->cNonPawns[BLACK][0] == ILLEGAL_COOR);
+ pos->cNonPawns[BLACK][0] = c1;
+ pos->uNonPawnCount[BLACK][KING] = 1;
+ pos->uNonPawnCount[BLACK][0] = 1;
+ pos->uNonPawnMaterial[BLACK] = VALUE_KING;
+
+ //
+ // Place the rest of the armies
+ //
+ FOREACH_COLOR(uColor)
+ {
+ ASSERT(IS_VALID_COLOR(uColor));
+
+ for (x = 0;
+ x < (ULONG)(rand() % 15 + 1);
+ x++)
+ {
+ //
+ // Pick a random empty square
+ //
+ do
+ {
+ c = RANDOM_COOR;
+ }
+ while((pos->rgSquare[c].pPiece) || (RANK1(c) || RANK8(c)));
+
+ do
+ {
+ p = RANDOM_PIECE;
+ if (WHITE == uColor)
+ {
+ p |= WHITE;
+ }
+ else
+ {
+ p &= ~WHITE;
+ }
+ ASSERT(GET_COLOR(p) == uColor);
+
+ if (IS_PAWN(p) &&
+ (pos->uPawnCount[uColor] < 8) &&
+ (!RANK1(c)) &&
+ (!RANK8(c)))
+ {
+ //
+ // The pawn list is not ordered at all, add
+ // the new pawn's location to the list and
+ // point from the pawn to the list.
+ //
+ pos->cPawns[uColor][pos->uPawnCount[uColor]] = c;
+ pos->rgSquare[c].uIndex = pos->uPawnCount[uColor];
+ pos->rgSquare[c].pPiece = p;
+ pos->uPawnCount[uColor]++;
+ pos->uPawnMaterial[uColor] += VALUE_PAWN;
+ break;
+ }
+ else if (!IS_KING(p) &&
+ (IS_VALID_PIECE(p)))
+ {
+ uIndex = pos->uNonPawnCount[uColor][0];
+ pos->cNonPawns[uColor][uIndex] = c;
+ pos->uNonPawnCount[uColor][0]++;
+ pos->uNonPawnCount[uColor][PIECE_TYPE(p)]++;
+ pos->rgSquare[c].pPiece = p;
+ pos->rgSquare[c].uIndex = uIndex;
+ pos->uNonPawnMaterial[uColor] += PIECE_VALUE(p);
+ if (IS_BISHOP(p))
+ {
+ if (IS_WHITE_SQUARE_COOR(c))
+ {
+ pos->uWhiteSqBishopCount[uColor]++;
+ }
+ }
+ break;
+ }
+ }
+ while(1);
+
+ } // next piece
+
+ } // next color
+ ASSERT(pos->uNonPawnCount[WHITE][KING] == 1);
+ ASSERT(pos->uNonPawnCount[BLACK][KING] == 1);
+ //pos->uNonPawnCount[WHITE][0]--;
+ //pos->uNonPawnCount[BLACK][0]--;
+
+ //
+ // Do the rest of the position
+ //
+ pos->iMaterialBalance[WHITE] =
+ ((SCORE)(pos->uNonPawnMaterial[WHITE] +
+ pos->uPawnMaterial[WHITE]) -
+ (SCORE)(pos->uNonPawnMaterial[BLACK] +
+ pos->uPawnMaterial[BLACK]));
+ pos->iMaterialBalance[BLACK] = -pos->iMaterialBalance[WHITE];
+ pos->uToMove = RANDOM_COLOR;
+ pos->uFifty = rand() % 100;
+ if (pos->rgSquare[E1].pPiece == WHITE_KING)
+ {
+ if (pos->rgSquare[A1].pPiece == WHITE_ROOK)
+ {
+ pos->bvCastleInfo |= CASTLE_WHITE_SHORT;
+ }
+ if (pos->rgSquare[H1].pPiece == WHITE_ROOK)
+ {
+ pos->bvCastleInfo |= CASTLE_WHITE_LONG;
+ }
+ }
+ if (pos->rgSquare[E8].pPiece == BLACK_KING)
+ {
+ if (pos->rgSquare[A8].pPiece == BLACK_ROOK)
+ {
+ pos->bvCastleInfo |= CASTLE_BLACK_SHORT;
+ }
+ if (pos->rgSquare[H8].pPiece == BLACK_ROOK)
+ {
+ pos->bvCastleInfo |= CASTLE_BLACK_LONG;
+ }
+ }
+ pos->u64NonPawnSig = ComputeSig(pos);
+ pos->u64PawnSig = ComputePawnSig(pos);
+
+ //
+ // See if it's legal
+ //
+ if (VerifyPositionConsistency(pos, TRUE) &&
+ !InCheck(pos, FLIP(pos->uToMove)))
+ {
+ break;
+ }
+ }
+ while(1);
+}
+
+
+#define SYM_SQ(c) ((7 - (((c) & 0xF0) >> 4)) << 4) \
+ | (7 - ((c) & 0x0F))
+void
+GenerateRandomLegalSymetricPosition(POSITION *pos)
+{
+ CHAR szFen[256];
+ CHAR *p;
+ ULONG uPieceCount[7];
+ COOR c, xc;
+ PIECE pPiece = KING;
+ PIECE pBoard[128];
+ ULONG x, y;
+
+ do
+ {
+ memset(pBoard, 0, sizeof(pBoard));
+ memset(uPieceCount, 0, sizeof(uPieceCount));
+
+ y = (ULONG)((rand() % 15) + 1);
+ for (x = 0;
+ x < y;
+ x++)
+ {
+ //
+ // Pick a piece type
+ //
+ do
+ {
+ pPiece = (rand() % 5) + 1;
+ switch(pPiece)
+ {
+ case PAWN:
+ if (uPieceCount[PAWN] < 8)
+ {
+ uPieceCount[PAWN]++;
+ }
+ else
+ {
+ pPiece = 0;
+ }
+ break;
+ case KNIGHT:
+ case BISHOP:
+ case ROOK:
+ case QUEEN:
+ if (uPieceCount[pPiece] < 2)
+ {
+ uPieceCount[pPiece]++;
+ }
+ else
+ {
+ if (uPieceCount[PAWN] < 8)
+ {
+ uPieceCount[PAWN]++;
+ pPiece = PAWN;
+ }
+ }
+ break;
+ default:
+ pPiece = 0;
+ break;
+ }
+ }
+ while(pPiece == 0);
+
+ //
+ // Pick a location
+ //
+ do
+ {
+ c = RANDOM_COOR;
+ }
+ while (!IS_ON_BOARD(c) ||
+ (pBoard[c] != 0) ||
+ ((pPiece == PAWN) && ((RANK(c) == 1) || (RANK(c) == 8))));
+ xc = SYM_SQ(c);
+ ASSERT(IS_ON_BOARD(xc));
+ ASSERT(IS_EMPTY(pBoard[xc]));
+
+ pBoard[c] = (pPiece << 1) | WHITE;
+ pBoard[xc] = (pPiece << 1) | BLACK;
+ pPiece = 0;
+ }
+
+ do
+ {
+ c = RANDOM_COOR;
+ }
+ while (!IS_ON_BOARD(c) ||
+ (pBoard[c] != 0));
+ xc = SYM_SQ(c);
+ ASSERT(IS_ON_BOARD(xc));
+ ASSERT(IS_EMPTY(pBoard[xc]));
+ pBoard[c] = WHITE_KING;
+ pBoard[xc] = BLACK_KING;
+
+ memset(szFen, 0, sizeof(szFen));
+ p = szFen;
+ for (x = 0; x < 120; x++)
+ {
+ if ((x % 15 == 0) &&
+ (x != 120) &&
+ (x != 0)) *p++ = '/';
+
+ if (!IS_ON_BOARD(x)) continue;
+ if (0 == pBoard[x]) *p++ = '1';
+ else *p++ = *(PieceAbbrev(pBoard[x]) + 1);
+ }
+ strcat(p, " w - - 0 0");
+ FenToPosition(pos, szFen);
+ }
+ while(!IsBoardLegal(pos));
+}