diff options
Diffstat (limited to 'src/testsup.c')
| -rw-r--r-- | src/testsup.c | 357 |
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)); +} |
