diff options
author | eug-vs <eugene@eug-vs.xyz> | 2022-09-14 02:59:36 +0300 |
---|---|---|
committer | eug-vs <eugene@eug-vs.xyz> | 2022-09-14 02:59:36 +0300 |
commit | f7901374649cd76ac52a6c881c79dc8d64e00981 (patch) | |
tree | 4bc0f4aaa5c36b9618f70362f4b13f816216c11d | |
parent | 87514fc685ea45241dbb00471388638e0be1b229 (diff) | |
download | j1chess-f7901374649cd76ac52a6c881c79dc8d64e00981.tar.gz |
feat: compute knight attack table
-rw-r--r-- | src/board.c | 32 | ||||
-rw-r--r-- | src/board.h | 34 | ||||
-rw-r--r-- | src/main.c | 31 | ||||
-rw-r--r-- | src/types.h | 1 |
4 files changed, 81 insertions, 17 deletions
diff --git a/src/board.c b/src/board.c index bc5855f..59b6043 100644 --- a/src/board.c +++ b/src/board.c @@ -1,10 +1,32 @@ +#include <stdio.h> #include "board.h" -BYTE notation_to_index(char file, int rank) { - return (rank - 1) * 8 + (file - 'a'); +int pop_count(Bitboard bb){ + if (bb == 0) return 0; + return pop_count(bb >> 1) + (bb & 1); } -void index_to_notation(BYTE index, char notation[2]) { - notation[0] = (index & 0b0111) + 'a'; - notation[1] = (index >> 3) + '1'; +void print_bitboard(Bitboard bb) { + for (U64 index = 0; index < 64; index++) { + printf("%lu", (bb >> index) & 1); + if ((index + 1) % 8 == 0) printf("\n"); + } + printf("\n\n"); +} + + +void precompute_knight_attack_table(Bitboard attacks[64]) { + for (int index = 0; index < 64; index++) { + U64 position = (U64)1 << index; + + attacks[index] = + ((position & notAFile & notBFile) << 6) | + ((position & notGFile & notHFile) << 10) | + ((position & notAFile) << 15) | + ((position & notHFile) << 17) | + ((position & notGFile & notHFile) >> 6) | + ((position & notAFile & notBFile) >> 10) | + ((position & notHFile) >> 15) | + ((position & notAFile) >> 17); + } } diff --git a/src/board.h b/src/board.h index f7e89f2..154878c 100644 --- a/src/board.h +++ b/src/board.h @@ -10,7 +10,7 @@ #define QUEEN 0b1000 #define KING 0b1010 -typedef QWORD Bitboard; +typedef U64 Bitboard; typedef struct { Bitboard pieces[12]; @@ -19,6 +19,33 @@ typedef struct { BYTE en_passant_square; } Board; +enum enumSquare { + a1, b1, c1, d1, e1, f1, g1, h1, + a2, b2, c2, d2, e2, f2, g2, h2, + a3, b3, c3, d3, e3, f3, g3, h3, + a4, b4, c4, d4, e4, f4, g4, h4, + a5, b5, c5, d5, e5, f5, g5, h5, + a6, b6, c6, d6, e6, f6, g6, h6, + a7, b7, c7, d7, e7, f7, g7, h7, + a8, b8, c8, d8, e8, f8, g8, h8 +}; + +#define notAFile 0xFEFEFEFEFEFEFEFE +#define notBFile 0xFDFDFDFDFDFDFDFD +#define notGFile 0xBFBFBFBFBFBFBFBF +#define notHFile 0x7F7F7F7F7F7F7F7F + +static const char* notation[64] = { + "a1", "b1", "c1", "d1", "e1", "f1", "g1", "h1", + "a2", "b2", "c2", "d2", "e2", "f2", "g2", "h2", + "a3", "b3", "c3", "d3", "e3", "f3", "g3", "h3", + "a4", "b4", "c4", "d4", "e4", "f4", "g4", "h4", + "a5", "b5", "c5", "d5", "e5", "f5", "g5", "h5", + "a6", "b6", "c6", "d6", "e6", "f6", "g6", "h6", + "a7", "b7", "c7", "d7", "e7", "f7", "g7", "h7", + "a8", "b8", "c8", "d8", "e8", "f8", "g8", "h8" +}; + static const char* pieces[] = { "♟︎", "♙", "♞", "♘", @@ -28,5 +55,6 @@ static const char* pieces[] = { "♚", "♔", }; -void index_to_notation(BYTE index, char notation[2]); -BYTE notation_to_index(char file, int rank); +void precompute_knight_attack_table(); +void print_bitboard(Bitboard bb); +int pop_count(Bitboard bb); @@ -1,17 +1,30 @@ #include "unittest.h" #include "board.h" -void test_notations() { - printf("%u\n", notation_to_index('e', 4)); - unit_test(notation_to_index('e', 4) == 28, "Notation e4 is index 28"); +int main() { + { // Pop count + unit_test(pop_count(0b01110) == 3, "Pop count of 01110 is 3"); + } - char notation[2] = "x0"; - index_to_notation(28, notation); - unit_test(notation[0] == 'e' && notation [1] == '4', "Index 28 is notation e4"); -} + { // Test knight attacks + Bitboard attacks[64]; + precompute_knight_attack_table(attacks); -int main() { - test_notations(); + 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 knight attacks should be 8"); + + { // Knight on b7 attack table + U64 bit = 1; + unit_test( + attacks[b7] == ((bit << d8) | (bit << d6) | (bit << c5) | (bit << a5)), + "Knight on b7 attacks d8, d6, c5, a5" + ); + } + } report(); return 0; diff --git a/src/types.h b/src/types.h index 4f95bb3..371d8b8 100644 --- a/src/types.h +++ b/src/types.h @@ -1,5 +1,6 @@ typedef unsigned char BYTE; typedef unsigned short WORD; typedef unsigned long QWORD; +typedef unsigned long U64; |