diff options
author | eug-vs <eugene@eug-vs.xyz> | 2022-09-14 05:27:30 +0300 |
---|---|---|
committer | eug-vs <eugene@eug-vs.xyz> | 2022-09-14 05:27:30 +0300 |
commit | 6f7cfbfcde39a57a59db17882339fa26055b75a0 (patch) | |
tree | b2477a1b5c9fef015b62664e96b054f374ac3e14 | |
parent | 8e1d090e0f5c8d2e72fc1e90c22404a9ef808606 (diff) | |
download | j1chess-6f7cfbfcde39a57a59db17882339fa26055b75a0.tar.gz |
feat: precompute king attack tables
-rw-r--r-- | src/board.c | 19 | ||||
-rw-r--r-- | src/board.h | 2 | ||||
-rw-r--r-- | src/main.c | 43 |
3 files changed, 46 insertions, 18 deletions
diff --git a/src/board.c b/src/board.c index 83fe8ce..a0b1bb7 100644 --- a/src/board.c +++ b/src/board.c @@ -18,7 +18,7 @@ void print_bitboard(Bitboard bb) { void precompute_knight_attack_table(Bitboard attacks[64]) { for (int index = 0; index < 64; index++) { - U64 position = (U64)1 << index; + U64 position = BIT << index; attacks[index] = ((position & notAFile & notBFile) << 6) | @@ -32,6 +32,17 @@ void precompute_knight_attack_table(Bitboard attacks[64]) { } } +void precompute_king_attack_table(Bitboard attacks[64]) { + for (int index = 0; index < 64; index++) { + U64 position = BIT << index; + + attacks[index] = + (position & notAFile) << 7 | (position << 8) | (position & notHFile) << 9 | + (position & notAFile) >> 1 | (position & notHFile) << 1 | + (position & notAFile) >> 9 | (position >> 8) | (position & notHFile) >> 7; + } +} + Board parse_FEN(char* FEN) { Board board; for (int i = 0; i < 12; i++) board.pieces[i] = 0; @@ -42,7 +53,7 @@ Board parse_FEN(char* FEN) { for (int k = 0; k < strlen(FEN); k++) { int c = FEN[k]; int index = rank * 8 + file; - Bitboard position = (Bitboard)1 << index; + Bitboard position = BIT << index; if (c > '0' && c <= '8') file += c - '0'; else { @@ -87,8 +98,6 @@ Board parse_FEN(char* FEN) { rank--; file = -1; // So that it becomes 0 break; - case ' ': // TODO: parse everything after - return board; } file++; } @@ -103,7 +112,7 @@ void print_board(Board board) { printf("%i|", rank + 1); for (int file = 0; file < 8; file++) { int index = rank * 8 + file; - Bitboard position = (Bitboard)1 << index; + Bitboard position = BIT << index; int found = 0; for (int piece = 0; piece < 12; piece++) { diff --git a/src/board.h b/src/board.h index c9d8153..11b0c71 100644 --- a/src/board.h +++ b/src/board.h @@ -11,6 +11,7 @@ #define KING 0b1010 typedef U64 Bitboard; +#define BIT (U64)1 typedef struct { Bitboard pieces[12]; @@ -56,6 +57,7 @@ static const char* pieces[] = { }; void precompute_knight_attack_table(); +void precompute_king_attack_table(); void print_bitboard(Bitboard bb); int pop_count(Bitboard bb); void print_board(Board board); @@ -6,7 +6,16 @@ int main() { start_test_section("Bitboards"); unit_test(pop_count(0b01110) == 3, "Pop count of 01110 is 3"); } - + { + start_test_section("Default FEN string"); + Board board = parse_FEN("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); + unit_test(pop_count(board.pieces[PAWN] | board.pieces[PAWN | BLACK]) == 16, "There are 16 pawns total"); + unit_test(pop_count(board.pieces[ROOK]) == 2, "There are 2 white rooks"); + // TODO + unit_test(board.side == WHITE, "Side to move is white"); + unit_test(board.castling_rights == 0, "Both sides can castle"); + unit_test(board.en_passant_square == 0, "No en passant move is avaialble"); + } { start_test_section("Test knight attacks"); Bitboard attacks[64]; @@ -19,25 +28,33 @@ int main() { } unit_test(max_attacks == 8, "Max amount of knight attacks should be 8"); + unit_test( + attacks[b7] == ((BIT << d8) | (BIT << d6) | (BIT << c5) | (BIT << a5)), + "Knight on b7 attacks only d8, d6, c5, a5" + ); + } + { + start_test_section("Test king attacks"); + Bitboard attacks[64]; + precompute_king_attack_table(attacks); + + int max_attacks = 0; + for (int i = 0; i < 64; i++) { + int attack_count = pop_count(attacks[i]); + if (attack_count > max_attacks) max_attacks = attack_count; + } + unit_test(max_attacks == 8, "Max amount of king attacks should be 8"); + { U64 bit = 1; unit_test( - attacks[b7] == ((bit << d8) | (bit << d6) | (bit << c5) | (bit << a5)), - "Knight on b7 attacks only d8, d6, c5, a5" + attacks[h2] == ((BIT << h1) | (BIT << g1) | (BIT << g2) | (BIT << g3) | (BIT << h3)), + "King on h2 attacks only h1, g1, g2, g3, h3" ); } } - { - start_test_section("Default FEN string"); - Board board = parse_FEN("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); - unit_test(pop_count(board.pieces[PAWN] | board.pieces[PAWN | BLACK]) == 16, "There are 16 pawns total"); - unit_test(pop_count(board.pieces[ROOK]) == 2, "There are 2 white rooks"); - // TODO - unit_test(board.side == WHITE, "Side to move is white"); - unit_test(board.castling_rights == 0, "Everyone can castle"); - unit_test(board.en_passant_square == 0, "No en passant move is avaialble"); - } + report(); return 0; |