From 1b779b76676dc4aa62bcd1fb95653de74a96e9fe Mon Sep 17 00:00:00 2001 From: MrGeorgen Date: Sun, 17 Mar 2024 22:04:13 +0100 Subject: [PATCH] not working: check --- CMakeLists.txt | 2 +- {src => include}/chess/generated/.gitkeep | 0 include/chess/magic.h | 10 ++ include/chess/types.h | 2 +- lib/chess/magic.c | 24 +++ src/chess/main.c | 5 +- src/chess/move.c | 173 +++++++++++++++++----- src/chess/move.h | 3 +- src/findMagicNumber.c | 54 +++---- src/generateCode/moveConsts.c | 8 +- 10 files changed, 198 insertions(+), 83 deletions(-) rename {src => include}/chess/generated/.gitkeep (100%) create mode 100644 include/chess/magic.h create mode 100644 lib/chess/magic.c diff --git a/CMakeLists.txt b/CMakeLists.txt index f97b3d9..9c901f9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ file(GLOB LIB_SOURCES "lib/chess/*.c") add_executable(genMoveConsts src/generateCode/moveConsts.c ${LIB_SOURCES}) add_custom_command( OUTPUT moveConsts.h # Output file from code generation - COMMAND genMoveConsts > src/chess/generated/moveConsts.h + COMMAND genMoveConsts > include/chess/generated/moveConsts.h DEPENDS genMoveConsts # Depends on the code generation executable ) add_custom_target(generateCode DEPENDS moveConsts.h) diff --git a/src/chess/generated/.gitkeep b/include/chess/generated/.gitkeep similarity index 100% rename from src/chess/generated/.gitkeep rename to include/chess/generated/.gitkeep diff --git a/include/chess/magic.h b/include/chess/magic.h new file mode 100644 index 0000000..e85f20a --- /dev/null +++ b/include/chess/magic.h @@ -0,0 +1,10 @@ +#ifndef CHESS_MAGIC_H +#define CHESS_MAGIC_H + +#include +#include + +uint_least64_t slidingMovementMask(const uint_least8_t *direction, uint_least8_t directionLength, + uint_least8_t field, uint_least64_t blockMask); +uint_least64_t* getMagicAttackPtr(const uint_least64_t mask, const struct magic_t magic); +#endif diff --git a/include/chess/types.h b/include/chess/types.h index c27a3c5..38ec197 100644 --- a/include/chess/types.h +++ b/include/chess/types.h @@ -5,7 +5,7 @@ #include #define BOARD_SIZE 8 -#define TOTAL_BOARD_SIZE BOARD_SIZE * BOARD_SIZE +#define TOTAL_BOARD_SIZE (BOARD_SIZE * BOARD_SIZE) #define LENGTH(array) (sizeof array / sizeof *array) #define NOT_SELECTED UINT_LEAST8_MAX diff --git a/lib/chess/magic.c b/lib/chess/magic.c new file mode 100644 index 0000000..05e23c0 --- /dev/null +++ b/lib/chess/magic.c @@ -0,0 +1,24 @@ +#include +#include +#include +#include + +uint_least64_t slidingMovementMask(const uint_least8_t *direction, uint_least8_t directionLength, + uint_least8_t field, uint_least64_t blockMask) { + defineDirectionOffset; + const uint_least8_t *localDirectionOffset = DIRECTION_OFFSET + field * DIRECTION_LENGTH; + uint_least64_t movementMask = 0; + for(uint_least8_t j = 0; j < directionLength; ++j) { + const int_least8_t modifier = DIRECTION_MODIFIER[direction[j]]; + for(uint_least8_t currentField = field + modifier, i = 0; + i < localDirectionOffset[direction[j]] - 1; ++i, currentField += modifier) { + movementMask = bitsetSet(movementMask, currentField); + if(bitsetGet(blockMask, currentField)) break; + } + } + return movementMask; +} + +uint_least64_t* getMagicAttackPtr(const uint_least64_t mask, const struct magic_t magic) { + return magic.attackTable + ((mask * magic.magicNumber) >> magic.shift); +} diff --git a/src/chess/main.c b/src/chess/main.c index fa3471a..bd7b576 100644 --- a/src/chess/main.c +++ b/src/chess/main.c @@ -1,4 +1,3 @@ -#include #include #include #include @@ -47,7 +46,7 @@ static void selectCircle(cairo_t *cr, const struct drawData_t *drawData, uint_le } static struct gameState_t userMove(struct gameState_t gameState, struct move_t move) { - gameState = makeMove(gameState, turn, move); + gameState = makeMove(gameState, move); #ifdef NO_COMPUTER turn = !turn; #else @@ -179,7 +178,7 @@ 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, {{true, true}, {true, true}}, 0, NOT_SELECTED}; + static struct gameState_t gameState = {board, WHITE, {{true, true}, {true, true}}, 0, NOT_SELECTED}; { struct piece_t piece; const char startFEN[] = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"; diff --git a/src/chess/move.c b/src/chess/move.c index 4b3d192..dc35f21 100644 --- a/src/chess/move.c +++ b/src/chess/move.c @@ -1,15 +1,19 @@ -#include #include #include #include #include "move.h" #include -#include "generated/moveConsts.h" +#include +#include +#include +#include +#include "magicNumber.h" +#include #define trailingBits(num) __builtin_ctzll(num) struct addMoveCtx_t { - uint_least64_t *board; + struct gameState_t gameState; struct move_t *moves; uint_least8_t *movesLength; }; @@ -21,6 +25,38 @@ static uint_least8_t getDirectionOffset(uint_least8_t field, uint_least8_t direc return DIRECTION_OFFSET[field * DIRECTION_LENGTH + direction]; } +static uint_least8_t getMagicSize(const struct magic_t magic) { + return 1 << (64 - magic.shift); +} + +static size_t getTotalMagicSize(const struct magic_t *magic) { + size_t size = 0; + for(uint_least8_t i = 0; i < TOTAL_BOARD_SIZE; ++i) { + size += getMagicSize(magic[i]); + } + return size; +} + +void initMagicTable() { + size_t size = getTotalMagicSize(rookMagic) + getTotalMagicSize(bishopMagic); + uint_least64_t *attackTable = malloc(size * sizeof *attackTable); + if(attackTable == NULL) { + perror("failed to allocate memory: "); + exit(1); + } + for(uint_least8_t field = 0; field < TOTAL_BOARD_SIZE; ++field) { + struct magic_t *magic = rookMagic + field; + attackTable += getMagicSize(*magic); + magic->attackTable = attackTable; + uint_least64_t pieceArangement = 0; + do { // https://stackoverflow.com/questions/7277554/what-is-a-good-way-to-iterate-a-number-through-all-the-possible-values-of-a-mask + const uint_least64_t attackMask = slidingMovementMask(ROOK_DIRECTION, LENGTH(ROOK_DIRECTION), field, pieceArangement); + *getMagicAttackPtr(pieceArangement, *magic) = attackMask; + pieceArangement = (pieceArangement - magic->mask) & magic->mask; + } while(pieceArangement != 0); + } +} + static uint_least8_t getCapturePos(uint_least8_t src, uint_least8_t dst, uint_least8_t spezialMove) { if(spezialMove != EN_PASSANT) return dst; const uint_least8_t file = dst % 8; @@ -28,21 +64,76 @@ static uint_least8_t getCapturePos(uint_least8_t src, uint_least8_t dst, uint_le return rank * BOARD_SIZE + file; } -static bool inCheck(uint_least64_t *board, uint_least8_t field, bool color) { - defineKnightCheck; - defineKingCheck; - definePawnCheck; - const struct piece_t knight = {KNIGHT, !color}; - const struct piece_t pawn = {PAWN, !color}; - const struct piece_t king = {KING, !color}; - return bitboardGetMask(board, knight) & KNIGHT_CHECK[field] || - bitboardGetMask(board, pawn) & PAWN_CHECK[2 * field + color] || - bitboardGetMask(board, king) & KING_CHECK[field]; +static bool checkMagic(const uint_least64_t *board, const struct piece_t attackPiece, + const struct magic_t *magic, const uint_least64_t kingMask) { + uint_least8_t attackerField; + for(uint_least64_t attackerMask = bitboardGetMask(board, attackPiece); attackerMask != 0; + attackerMask = bitsetClear(attackerMask, attackerField)) { + attackerField = trailingBits(attackerMask); + const struct magic_t magicField = magic[attackerField]; + const uint_least64_t checkMask = *getMagicAttackPtr(bitboardMaskAllPieces(board) & magicField.mask, magicField); + if(checkMask & kingMask) return true; + } + return false; +} + +static bool checkSimpleLookup(const uint_least64_t *board, const uint_least8_t field, const bool color) { + defineKnightCheck; + defineKingCheck; + definePawnCheck; + const struct piece_t knight = {KNIGHT, !color}; + const struct piece_t pawn = {PAWN, !color}; + const struct piece_t king = {KING, !color}; + return bitboardGetMask(board, knight) & KNIGHT_CHECK[field] || + bitboardGetMask(board, pawn) & PAWN_CHECK[2 * field + color] || + bitboardGetMask(board, king) & KING_CHECK[field]; +} + +static bool inCheck(const uint_least64_t *board, const uint_least64_t kingMask, const bool color) { + const struct piece_t rook = {ROOK, !color}; + const struct piece_t bishop = {BISHOP, !color}; + const struct piece_t queen = {QUEEN, !color}; + uint_least8_t field; + for(uint_least64_t mask = kingMask; mask != 0; mask = bitsetClear(mask, field)) { + field = trailingBits(mask); + if(checkSimpleLookup(board, field, color)) return true; + } + return checkMagic(board, rook, rookMagic, kingMask) || checkMagic(board, bishop, bishopMagic, kingMask) || + checkMagic(board, queen, rookMagic, kingMask) || checkMagic(board, queen, bishopMagic, kingMask); +} + +static uint_least8_t getCastleRankI(bool color) { + if(color == WHITE) { + return (BOARD_SIZE - 1) * BOARD_SIZE; + } + return 0; +} + +static void castleMoveRook(uint_least64_t *board, uint_least8_t spezialMove, bool color, bool undo) { + if(spezialMove == SHORT_CASTLE || spezialMove == LONG_CASTLE) { + const uint_least8_t rookSrc = getCastleRankI(color) + (spezialMove == SHORT_CASTLE ? BOARD_SIZE - 1 : 0); + const uint_least8_t rookDst = getCastleRankI(color) + (spezialMove == SHORT_CASTLE ? 5 : 3); + const struct piece_t rook = {ROOK, color}; + bitboardSet(board, rook, undo ? rookSrc : rookDst); + bitboardClear(board, rook, undo ? rookDst : rookSrc); + } +} + +static 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); + bitboardClear(board, dstPiece, move.dst); + if(move.capturedPiece != NOT_SELECTED) { + const struct piece_t piece = {move.capturedPiece, !color}; + bitboardSet(board, piece, move.dst); + } + castleMoveRook(board, move.spezialMove, color, true); } static void addMove(struct addMoveCtx_t ctx, struct piece_t movedPiece, uint_least8_t src, uint_least8_t dst, uint_least8_t spezialMove) { - uint_least64_t *board = ctx.board; + uint_least64_t *board = ctx.gameState.board; uint_least8_t *movesLength = ctx.movesLength; uint_least8_t capturedPiece = NOT_SELECTED; const struct piece_t pieceAll = {ALL_PIECES, movedPiece.color}; @@ -61,9 +152,16 @@ static void addMove(struct addMoveCtx_t ctx, struct piece_t movedPiece, uint_lea } } const struct move_t move = {src, dst, spezialMove, movedPiece.type, movedPiece.type, capturedPiece}; - ctx.moves[*movesLength] = move; - ++*movesLength; - return; + makeMove(ctx.gameState, move); + { + const bool color = ctx.gameState.color; + const struct piece_t king = {KING, color}; + if(!inCheck(board, bitboardGetMask(board, king), color)) { + ctx.moves[*movesLength] = move; + ++*movesLength; + } + undoMove(board, move, color); + } } static void addPreGenMoves(struct addMoveCtx_t ctx, const struct moveDst_t *moveDst, @@ -76,7 +174,7 @@ static void addPreGenMoves(struct addMoveCtx_t ctx, const struct moveDst_t *move static void moveSliding(const uint_least8_t *direction, uint_least8_t directionLength, struct addMoveCtx_t ctx, uint_least8_t field, struct piece_t movedPiece) { - uint_least64_t *board = ctx.board; + uint_least64_t *board = ctx.gameState.board; for(uint_least8_t j = 0; j < directionLength; ++j) { const int_least8_t modifier = DIRECTION_MODIFIER[direction[j]]; @@ -93,7 +191,7 @@ static void moveSliding(const uint_least8_t *direction, uint_least8_t directionL static void movePawn(struct addMoveCtx_t ctx, bool color, uint_least8_t src, uint_least8_t dst, bool promotion, uint_least8_t spezialMove) { - uint_least64_t *board = ctx.board; + uint_least64_t *board = ctx.gameState.board; struct move_t *moves = ctx.moves; uint_least8_t *movesLength = ctx.movesLength; const struct piece_t piece = {PAWN, color}; @@ -112,7 +210,7 @@ uint_least8_t pieceValidMoves(struct gameState_t gameState, struct piece_t piece struct move_t *moves, bool promotion) { uint_least64_t *board = gameState.board; uint_least8_t movesLength = 0; - struct addMoveCtx_t addmoveCtx = {board, moves, &movesLength}; + struct addMoveCtx_t addmoveCtx = {gameState, moves, &movesLength}; switch(piece.type) { case KING: { @@ -123,10 +221,10 @@ uint_least8_t pieceValidMoves(struct gameState_t gameState, struct piece_t piece const uint_least8_t rankShift = piece.color == WHITE ? BOARD_SIZE * (BOARD_SIZE - 1) : 0; const uint_least64_t shortCastleMask = (uint_least64_t)0b11 << (5 + rankShift); const uint_least64_t longCastleMask = (uint_least64_t)0b111 << (1 + rankShift); - if(canCastle.shortCastle && !(allPiecesMask & shortCastleMask)) { + if(canCastle.shortCastle && !(allPiecesMask & shortCastleMask) && !inCheck(board, shortCastleMask, piece.color)) { addMove(addmoveCtx, piece, src, src + 2 * DIRECTION_MODIFIER[EAST], SHORT_CASTLE); } - if(canCastle.longCastle && !(allPiecesMask & longCastleMask)) { + if(canCastle.longCastle && !(allPiecesMask & longCastleMask) && !inCheck(board, longCastleMask, piece.color)) { addMove(addmoveCtx, piece, src, src + 2 * DIRECTION_MODIFIER[WEST], LONG_CASTLE); } break; @@ -212,53 +310,48 @@ static void setCastleInfo(struct castle_t *canCastle, uint_least8_t posOnRank) { } } -struct gameState_t makeMove(struct gameState_t gameState, bool color, struct move_t move) { +struct gameState_t makeMove(struct gameState_t gameState, struct move_t move) { uint_least64_t *board = gameState.board; - const uint_least8_t castleRankI[2] = {0, (BOARD_SIZE - 1) * BOARD_SIZE}; - const struct piece_t srcPiece = {move.srcPiece, color}; - const struct piece_t dstPiece = {move.dstPiece, color}; + const struct piece_t srcPiece = {move.srcPiece, gameState.color}; + const struct piece_t dstPiece = {move.dstPiece, gameState.color}; bitboardClear(board, srcPiece, move.src); bitboardSet(board, dstPiece, move.dst); if(move.capturedPiece != NOT_SELECTED) { - const struct piece_t capturedPiece = {move.capturedPiece, !color}; + const struct piece_t capturedPiece = {move.capturedPiece, !gameState.color}; bitboardClear(board, capturedPiece, getCapturePos(move.src, move.dst, move.spezialMove)); } - if(move.spezialMove == SHORT_CASTLE || move.spezialMove == LONG_CASTLE) { - const uint_least8_t rookSrc = castleRankI[color] + (move.spezialMove == SHORT_CASTLE ? BOARD_SIZE - 1 : 0); - const uint_least8_t rookDst = castleRankI[color] + (move.spezialMove == SHORT_CASTLE ? 5 : 3); - const struct piece_t rook = {ROOK, color}; - bitboardSet(board, rook, rookDst); - bitboardClear(board, rook, rookSrc); - } + castleMoveRook(board, move.spezialMove, gameState.color, false); { - struct castle_t *canCastleCurrentPlayer = gameState.canCastle + color; + struct castle_t *canCastleCurrentPlayer = gameState.canCastle + gameState.color; if(canCastleCurrentPlayer->longCastle || canCastleCurrentPlayer->shortCastle) { if(move.dstPiece == KING) { canCastleCurrentPlayer->longCastle = false; canCastleCurrentPlayer->shortCastle = false; } else { - setCastleInfo(canCastleCurrentPlayer, move.src - castleRankI[color]); + setCastleInfo(canCastleCurrentPlayer, move.src - getCastleRankI(gameState.color)); } } } { // if the rook is captured - struct castle_t *canCastleOther = gameState.canCastle + !color; + struct castle_t *canCastleOther = gameState.canCastle + !gameState.color; if(canCastleOther->longCastle || canCastleOther->shortCastle) { - setCastleInfo(canCastleOther, move.dst - castleRankI[!color]); + setCastleInfo(canCastleOther, move.dst - getCastleRankI(!gameState.color)); } } { const int_least8_t dist = (int_least8_t)move.dst - (int_least8_t)move.src; gameState.enPassantTo = FUTURE_EN_PASSANT ? move.src + dist / 2 : NOT_SELECTED; } - ++gameState.halfMoveCounter; + if(move.capturedPiece != NOT_SELECTED || srcPiece.type == PAWN) gameState.halfMoveCounter = 0; + else ++gameState.halfMoveCounter; + gameState.color = !gameState.color; return gameState; } struct gameState_t computerMove(struct gameState_t gameState) { struct move_t moves[MAX_VALID_MOVES]; validMoves(gameState, false, moves); - return makeMove(gameState, BLACK, moves[0]); + return makeMove(gameState, moves[0]); } diff --git a/src/chess/move.h b/src/chess/move.h index 4cf7c7a..d7edd0b 100644 --- a/src/chess/move.h +++ b/src/chess/move.h @@ -25,6 +25,7 @@ struct move_t { struct gameState_t { uint_least64_t *board; + bool color; // color to move struct castle_t canCastle[2]; // The number of halfmoves since the last capture or pawn advance, used for the fifty-move rule. @@ -37,7 +38,7 @@ uint_least8_t validMoves(struct gameState_t gameState, bool color, struct move_t uint_least8_t pieceValidMoves(struct gameState_t gameState, struct piece_t piece, uint_least8_t src, struct move_t *moves, bool promotion); -struct gameState_t makeMove(struct gameState_t gameState, bool color, struct move_t move); +struct gameState_t makeMove(struct gameState_t gameState, struct move_t move); struct gameState_t computerMove(struct gameState_t gameState); #endif diff --git a/src/findMagicNumber.c b/src/findMagicNumber.c index 78464f1..01a0520 100644 --- a/src/findMagicNumber.c +++ b/src/findMagicNumber.c @@ -1,14 +1,14 @@ #include -#include #include #include #include #include #include -#include "chess/generated/moveConsts.h" -#include #include #include +#include +#include +#include #define MAX_BITS 12 #define MAX_SIZE (1 << MAX_BITS) @@ -35,27 +35,12 @@ static uint_least8_t countOnes(uint_least64_t n) { } static void printerMagic(FILE *file, struct magic_t magic) { - fprintf(file, "{ NULL, %" PRIuLEAST64 ", %" PRIuLEAST64 ", %" PRIuLEAST8 "}", magic.mask, magic.magicNumber, magic.shift); + fprintf(file, "{ 0, %" PRIuLEAST64 "u, %" PRIuLEAST64 "u, %" PRIuLEAST8 "}", magic.mask, magic.magicNumber, magic.shift); } -static uint_least64_t slidingMovementMask(const uint_least8_t *direction, uint_least8_t directionLength, - uint_least8_t field, uint_least64_t blockMask) { - defineDirectionOffset; - const uint_least8_t *localDirectionOffset = DIRECTION_OFFSET + field * DIRECTION_LENGTH; - uint_least64_t movementMask = 0; - for(uint_least8_t j = 0; j < directionLength; ++j) { - const int_least8_t modifier = DIRECTION_MODIFIER[direction[j]]; - for(uint_least8_t currentField = field + modifier, i = 0; - i < localDirectionOffset[direction[j]]; ++i, currentField += modifier) { - movementMask = bitsetSet(movementMask, currentField); - if(bitsetGet(blockMask, currentField)) break; - } - } - return movementMask; -} static bool tryMagicNum(uint_least8_t field, struct magic_t *magic, uint_least64_t magicNumber, - const uint_least64_t *preClacAttack) { + const uint_least64_t *preClacAttack, const uint_least8_t *direction) { preClacAttack += field * MAX_SIZE; bool usedMagic = false; if(countOnes((magic->mask * magicNumber) & 0xFF00000000000000ULL) < 6) return false; @@ -65,20 +50,21 @@ static bool tryMagicNum(uint_least8_t field, struct magic_t *magic, uint_least64 attackTable[i] = UINT_LEAST64_MAX; } bool validMagic = true; - uint_least64_t pieceArangement = 0; + uint_least64_t pieceArrangement = 0; size_t j = 0; do { - const uint_least32_t i = (pieceArangement * magicNumber) >> shift; + const uint_least64_t i = (pieceArrangement * magicNumber) >> shift; const uint_least64_t storedAttack = attackTable[i]; const uint_least64_t calcAttack = preClacAttack[j]; + //assert(slidingMovementMask(direction, 4, field, pieceArrangement) == calcAttack); if(storedAttack != UINT_LEAST64_MAX && storedAttack != calcAttack) { validMagic = false; break; } attackTable[i] = calcAttack; - pieceArangement = (pieceArangement - magic->mask) & magic->mask; + pieceArrangement = (pieceArrangement - magic->mask) & magic->mask; ++j; - } while(pieceArangement != 0); + } while(pieceArrangement != 0); if(validMagic) { magic->shift = shift; magic->magicNumber = magicNumber; @@ -95,26 +81,26 @@ static void initMagicField(uint_least64_t *attackMask, struct magic_t *magicTabl attackMask += field * MAX_SIZE; magic->mask = slidingMovementMask(direction, directionLength, field, 0); magic->shift = 64 - MAX_BITS - 1; - uint_least64_t pieceArangement = 0; + uint_least64_t pieceArrangement = 0; size_t i = 0; do { - attackMask[i] = slidingMovementMask(direction, directionLength, field, pieceArangement); - pieceArangement = (pieceArangement - magic->mask) & magic->mask; + assert(i < MAX_SIZE); + attackMask[i] = slidingMovementMask(direction, directionLength, field, pieceArrangement); + assert(countOnes(attackMask[i]) <= 12); + pieceArrangement = (pieceArrangement - magic->mask) & magic->mask; ++i; - } while(pieceArangement != 0); + } while(pieceArrangement != 0); } int main() { - const uint_least8_t rookDirection[] = {NORTH, SOUTH, EAST, WEST}; - const uint_least8_t bishopDirection[] = {NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST}; struct magic_t rookMagicTable[TOTAL_BOARD_SIZE] = {}; struct magic_t bishopMagicTable[TOTAL_BOARD_SIZE] = {}; uint_least64_t *attackMask = malloc(ATTACK_TABLE_LENGTH * sizeof *attackMask); uint_least64_t *rookAttackMask = attackMask; uint_least64_t *bishopAttackMask = attackMask + TOTAL_BOARD_SIZE * MAX_SIZE; for(uint_least8_t field = 0; field < TOTAL_BOARD_SIZE; ++field) { - initMagicField(rookAttackMask, rookMagicTable, field, rookDirection, LENGTH(rookDirection)); - initMagicField(bishopAttackMask, bishopMagicTable, field, bishopDirection, LENGTH(bishopDirection)); + initMagicField(rookAttackMask, rookMagicTable, field, ROOK_DIRECTION, LENGTH(ROOK_DIRECTION)); + initMagicField(bishopAttackMask, bishopMagicTable, field, BISHOP_DIRECTION, LENGTH(BISHOP_DIRECTION)); } srand(time(NULL)); for(;;) { @@ -123,11 +109,11 @@ int main() { for(uint_least8_t field = 0; field < TOTAL_BOARD_SIZE; ++field) { { struct magic_t *magic = rookMagicTable + field; - isMagic |= tryMagicNum(field, magic, magicNumber, rookAttackMask); + isMagic |= tryMagicNum(field, magic, magicNumber, rookAttackMask, ROOK_DIRECTION); } { struct magic_t *magic = bishopMagicTable + field; - isMagic |= tryMagicNum(field, magic, magicNumber, bishopAttackMask); + isMagic |= tryMagicNum(field, magic, magicNumber, bishopAttackMask, BISHOP_DIRECTION); } } if(isMagic) { diff --git a/src/generateCode/moveConsts.c b/src/generateCode/moveConsts.c index 9854dcd..56b252d 100644 --- a/src/generateCode/moveConsts.c +++ b/src/generateCode/moveConsts.c @@ -1,6 +1,5 @@ #include #include -#include #include #include #include @@ -31,7 +30,10 @@ int main() { printf("#ifndef CHESS_GENERATED_MOVE_CONSTS_H\n" "#define CHESS_GENERATED_MOVE_CONSTS_H\n" "#include \n" - "#include \n"); + "#include \n" + "const static uint_least8_t ROOK_DIRECTION[] = {NORTH, SOUTH, EAST, WEST};\n" + "const static uint_least8_t BISHOP_DIRECTION[] = {NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST};\n" +); uint_least8_t directionOffset[TOTAL_BOARD_SIZE * DIRECTION_LENGTH]; for(uint_least16_t field = 0; field < TOTAL_BOARD_SIZE; ++field) { uint_least8_t file = field % BOARD_SIZE; @@ -56,7 +58,7 @@ int main() { directionModifier[SOUTHWEST] = directionModifier[SOUTH] + directionModifier[WEST]; directionModifier[NORTHEAST] = directionModifier[NORTH] + directionModifier[EAST]; directionModifier[NORTHWEST] = directionModifier[NORTH] + directionModifier[WEST]; - defineArray("const int_least8_t DIRECTION_MODIFIER", printerll, directionModifier); + defineArray("const static int_least8_t DIRECTION_MODIFIER", printerll, directionModifier); { uint_least64_t knightCheck[TOTAL_BOARD_SIZE]; struct moveDst_t knightMoves[TOTAL_BOARD_SIZE] = {};