aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreug-vs <eugene@eug-vs.xyz>2022-09-14 02:59:36 +0300
committereug-vs <eugene@eug-vs.xyz>2022-09-14 02:59:36 +0300
commitf7901374649cd76ac52a6c881c79dc8d64e00981 (patch)
tree4bc0f4aaa5c36b9618f70362f4b13f816216c11d
parent87514fc685ea45241dbb00471388638e0be1b229 (diff)
downloadj1chess-f7901374649cd76ac52a6c881c79dc8d64e00981.tar.gz
feat: compute knight attack table
-rw-r--r--src/board.c32
-rw-r--r--src/board.h34
-rw-r--r--src/main.c31
-rw-r--r--src/types.h1
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);
diff --git a/src/main.c b/src/main.c
index 75d3bb7..2e95970 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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;