move gen test
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -9,3 +9,4 @@
|
||||
!.gitkeep
|
||||
!/include
|
||||
!/.gitignore
|
||||
!/test
|
||||
|
||||
@ -19,10 +19,10 @@ pkg_check_modules(GTK4 REQUIRED IMPORTED_TARGET gtk4)
|
||||
pkg_check_modules(LIBRSVG REQUIRED IMPORTED_TARGET librsvg-2.0)
|
||||
|
||||
add_executable(findMagicNumber src/findMagicNumber.c ${LIB_SOURCES})
|
||||
set_property(TARGET findMagicNumber PROPERTY C_STANDARD 99)
|
||||
add_dependencies(findMagicNumber generateCode)
|
||||
|
||||
add_executable(${PROJECT_NAME} ${SOURCES} ${LIB_SOURCES})
|
||||
set_property(TARGET findMagicNumber PROPERTY C_STANDARD 99)
|
||||
set_property(TARGET ${PROJECT_NAME} PROPERTY C_STANDARD 99)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE PkgConfig::GTK4 PkgConfig::LIBRSVG)
|
||||
add_dependencies(${PROJECT_NAME} generateCode)
|
||||
@ -43,3 +43,7 @@ set_property(TARGET chessNoComputer PROPERTY C_STANDARD 99)
|
||||
target_link_libraries(chessNoComputer PRIVATE PkgConfig::GTK4 PkgConfig::LIBRSVG)
|
||||
add_dependencies(chessNoComputer generateCode)
|
||||
target_compile_definitions(chessNoComputer PUBLIC NO_COMPUTER)
|
||||
|
||||
add_executable(moveGenTest test/moveGen.c src/chess/move.c ${LIB_SOURCES})
|
||||
set_property(TARGET moveGenTest PROPERTY C_STANDARD 99)
|
||||
add_test(NAME moveGen COMMAND moveGenTest)
|
||||
|
||||
@ -20,10 +20,11 @@ struct move_t {
|
||||
};
|
||||
|
||||
void genDirectionConsts();
|
||||
uint_least8_t validMoves(struct gameState_t gameState, bool color, struct move_t *moves);
|
||||
uint_least8_t validMoves(struct gameState_t gameState, struct move_t *moves);
|
||||
uint_least8_t pieceValidMoves(struct gameState_t gameState, struct piece_t piece, uint_least8_t src,
|
||||
struct move_t *moves, bool promotion);
|
||||
|
||||
void undoMove(uint_least64_t *board, struct move_t move, bool color);
|
||||
struct gameState_t makeMove(struct gameState_t gameState, struct move_t move);
|
||||
struct gameState_t computerMove(struct gameState_t gameState);
|
||||
void initMagicTable();
|
||||
|
||||
@ -176,9 +176,9 @@ static void on_click(GtkGestureClick *gesture, int n_press, double x, double y,
|
||||
static void app_activate(GApplication *app, gpointer data) {
|
||||
GtkWindow *window = GTK_WINDOW(gtk_window_new());
|
||||
static RsvgHandle *piecesSvg[16];
|
||||
static uint_least64_t board[2 * PIECES_LENGTH] = {};
|
||||
static struct gameState_t gameState = {board, WHITE, {{true, true}, {true, true}}, 0, NOT_SELECTED};
|
||||
|
||||
static uint_least64_t board[BITBOARD_LENGTH];
|
||||
static struct gameState_t gameState;
|
||||
gameState = newGameState(board, "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1");
|
||||
{
|
||||
static struct move_t moves[TOTAL_BOARD_SIZE];
|
||||
static struct drawData_t drawData = {piecesSvg, &gameState, NOT_SELECTED, moves, 0, NOT_SELECTED};
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <chess/types.h>
|
||||
#include "move.h"
|
||||
#include <chess/move.h>
|
||||
#include <chess/bitboard.h>
|
||||
#include <chess/generated/moveConsts.h>
|
||||
#include <stddef.h>
|
||||
@ -132,7 +132,7 @@ static void castleMoveRook(uint_least64_t *board, uint_least8_t spezialMove, boo
|
||||
}
|
||||
}
|
||||
|
||||
static void undoMove(uint_least64_t *board, struct move_t move, bool color) {
|
||||
void undoMove(uint_least64_t *board, struct move_t move, bool color) {
|
||||
const struct piece_t srcPiece = {move.srcPiece, color};
|
||||
const struct piece_t dstPiece = {move.dstPiece, color};
|
||||
bitboardSet(board, srcPiece, move.src);
|
||||
@ -300,10 +300,10 @@ uint_least8_t pieceValidMoves(struct gameState_t gameState, struct piece_t piece
|
||||
return movesLength;
|
||||
}
|
||||
|
||||
uint_least8_t validMoves(struct gameState_t gameState, bool color, struct move_t *moves) {
|
||||
uint_least8_t validMoves(struct gameState_t gameState, struct move_t *moves) {
|
||||
uint_least8_t movesLength = 0;
|
||||
for(uint_least8_t pieceType = KING; pieceType < PIECES_LENGTH; ++pieceType) {
|
||||
const struct piece_t piece = {pieceType, color};
|
||||
const struct piece_t piece = {pieceType, gameState.color};
|
||||
uint_least8_t field;
|
||||
for(uint_least64_t pieceMask = bitboardGetMask(gameState.board, piece);
|
||||
pieceMask != 0; pieceMask = bitsetClear(pieceMask, field)) {
|
||||
@ -367,6 +367,6 @@ struct gameState_t makeMove(struct gameState_t gameState, struct move_t move) {
|
||||
|
||||
struct gameState_t computerMove(struct gameState_t gameState) {
|
||||
struct move_t moves[MAX_VALID_MOVES];
|
||||
validMoves(gameState, false, moves);
|
||||
validMoves(gameState, moves);
|
||||
return makeMove(gameState, moves[0]);
|
||||
}
|
||||
|
||||
@ -76,12 +76,11 @@ struct piece_t pieceAtField(const uint_least64_t *board, uint_least8_t i) {
|
||||
}
|
||||
|
||||
struct gameState_t newGameState(uint_least64_t *board, char *FEN) {
|
||||
const char startFEN[] = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
|
||||
struct gameState_t gameState = {board};
|
||||
for(uint_least8_t i = 0; i < BITBOARD_LENGTH; ++i) {
|
||||
board[i] = 0;
|
||||
}
|
||||
for(uint_least8_t field = 0; *FEN != ' '; ++FEN, ++field) {
|
||||
for(uint_least8_t field = 0; *FEN != ' '; ++FEN) {
|
||||
struct piece_t piece;
|
||||
switch(tolower(*FEN)) {
|
||||
case 'k':
|
||||
@ -112,14 +111,14 @@ struct gameState_t newGameState(uint_least64_t *board, char *FEN) {
|
||||
}
|
||||
if(isalpha(*FEN)) piece.color = isupper(*FEN);
|
||||
bitboardSet(board, piece, field);
|
||||
++field;
|
||||
}
|
||||
gameState.color = *++FEN == 'w' ? WHITE : BLACK;
|
||||
struct castle_t canCastle[2] = {};
|
||||
FEN += 2;
|
||||
if(*FEN == '-') ++FEN;
|
||||
else {
|
||||
for(; *FEN != ' '; ++FEN) {
|
||||
struct castle_t *playerCastle = canCastle + (isupper(*FEN) ? WHITE : BLACK);
|
||||
struct castle_t *playerCastle = gameState.canCastle + (isupper(*FEN) ? WHITE : BLACK);
|
||||
if(tolower(*FEN) == 'k') playerCastle->shortCastle = true;
|
||||
else playerCastle->longCastle = true;
|
||||
}
|
||||
|
||||
@ -48,7 +48,7 @@ int main() {
|
||||
offsetField[SOUTHWEST] = min(offsetField[SOUTH], file);
|
||||
offsetField[NORTHEAST] = min(rank, offsetField[EAST]);
|
||||
}
|
||||
defineArray("#define defineDirectionOffset const uint_least8_t DIRECTION_OFFSET", printerull, directionOffset);
|
||||
defineArray("#define defineDirectionOffset const static uint_least8_t DIRECTION_OFFSET", printerull, directionOffset);
|
||||
int_least8_t directionModifier[DIRECTION_LENGTH];
|
||||
directionModifier[NORTH] = -BOARD_SIZE;
|
||||
directionModifier[SOUTH] = BOARD_SIZE;
|
||||
@ -86,8 +86,8 @@ int main() {
|
||||
}
|
||||
}
|
||||
genCheckMask(knightMoves, knightCheck);
|
||||
defineArray("#define defineKnightCheck const uint_least64_t KNIGHT_CHECK", printerull, knightCheck);
|
||||
defineArray("#define defineKnightMoves const struct moveDst_t KNIGHT_MOVES", printerMoveDst, knightMoves);
|
||||
defineArray("#define defineKnightCheck const static uint_least64_t KNIGHT_CHECK", printerull, knightCheck);
|
||||
defineArray("#define defineKnightMoves const static struct moveDst_t KNIGHT_MOVES", printerMoveDst, knightMoves);
|
||||
}
|
||||
{
|
||||
uint_least64_t kingCheck[TOTAL_BOARD_SIZE];
|
||||
@ -101,8 +101,8 @@ int main() {
|
||||
}
|
||||
}
|
||||
genCheckMask(kingMoves, kingCheck);
|
||||
defineArray("#define defineKingCheck const uint_least64_t KING_CHECK", printerull, kingCheck);
|
||||
defineArray("#define defineKingMoves const struct moveDst_t KING_MOVES", printerMoveDst, kingMoves);
|
||||
defineArray("#define defineKingCheck const static uint_least64_t KING_CHECK", printerull, kingCheck);
|
||||
defineArray("#define defineKingMoves const static struct moveDst_t KING_MOVES", printerMoveDst, kingMoves);
|
||||
}
|
||||
{
|
||||
uint_least64_t pawnCheck[2 * TOTAL_BOARD_SIZE];
|
||||
@ -122,7 +122,7 @@ int main() {
|
||||
pawnCheck[2 * field + color] = checkMask;
|
||||
}
|
||||
}
|
||||
defineArray("#define definePawnCheck const uint_least64_t PAWN_CHECK", printerull, pawnCheck);
|
||||
defineArray("#define definePawnCheck const static uint_least64_t PAWN_CHECK", printerull, pawnCheck);
|
||||
}
|
||||
printf("#endif\n");
|
||||
}
|
||||
|
||||
46
test/moveGen.c
Normal file
46
test/moveGen.c
Normal file
@ -0,0 +1,46 @@
|
||||
#include "chess/types.h"
|
||||
#include <chess/move.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdint.h>
|
||||
#include <chess/bitboard.h>
|
||||
#include <stdio.h>
|
||||
|
||||
struct perf_t {
|
||||
char FEN[256];
|
||||
uint_least8_t depth;
|
||||
uint_least64_t nodes;
|
||||
};
|
||||
|
||||
uint_least64_t perft(const struct gameState_t gameState, const uint_least8_t depth) {
|
||||
struct move_t moves[MAX_VALID_MOVES];
|
||||
uint_least64_t nodes = 0;
|
||||
const uint_least8_t movesLength = validMoves(gameState, moves);
|
||||
if(depth == 1) return movesLength;
|
||||
for(uint_least8_t i = 0; i < movesLength; ++i) {
|
||||
const struct gameState_t newGameState = makeMove(gameState, moves[i]);
|
||||
nodes += perft(newGameState, depth - 1);
|
||||
undoMove(gameState.board, moves[i], gameState.color);
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
|
||||
int main() {
|
||||
struct perf_t testPos[] = {
|
||||
{"rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", 5, 4865609}, // start Position 0
|
||||
{"r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq 0 1", 4, 4085603}, // 1
|
||||
{"8/2p5/3p4/KP5r/1R3p1k/8/4P1P1/8 w - 0 1", 5, 674624}, // 2
|
||||
{"r3k2r/Pppp1ppp/1b3nbN/nP6/BBP1P3/q4N2/Pp1P2PP/R2Q1RK1 w kq - 0 1", 4, 422333}, // 3
|
||||
{"rnbq1k1r/pp1Pbppp/2p5/8/2B5/8/PPP1NnPP/RNBQK2R w KQ - 1 8", 4, 2103487}, // 4
|
||||
{"r4rk1/1pp1qppp/p1np1n2/2b1p1B1/2B1P1b1/P1NP1N2/1PP1QPPP/R4RK1 w - - 0 10", 4, 3894594}, // 5
|
||||
};
|
||||
initMagicTable();
|
||||
for(uint_least16_t i = 0; i < LENGTH(testPos); ++i) {
|
||||
uint_least64_t board[BITBOARD_LENGTH];
|
||||
const struct gameState_t gameState = newGameState(board, testPos[i].FEN);
|
||||
const uint_least64_t nodes = perft(gameState, testPos[i].depth);
|
||||
if(testPos[i].nodes != nodes) {
|
||||
printf("Test %" PRIuLEAST16 " failed: FEN: %s, depth: %" PRIuLEAST8 " calculated nodes: %" PRIuLEAST64
|
||||
", expected nodes: %" PRIuLEAST64 "\n", i, testPos[i].FEN, testPos[i].depth, nodes, testPos[i].nodes);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user