aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreug-vs <eugene@eug-vs.xyz>2022-09-14 05:43:13 +0300
committereug-vs <eugene@eug-vs.xyz>2022-09-14 05:43:13 +0300
commit2dfa7cecdacacf7ef84e1ca768db6d636e225a0c (patch)
treed3573f22aabe6567c15a489aabe4d01792d76a50
parent9bbba5c582ea2dcbf5f22503127765999f06264c (diff)
downloadj1chess-2dfa7cecdacacf7ef84e1ca768db6d636e225a0c.tar.gz
feat: compute pawn attack table
-rw-r--r--src/board.c15
-rw-r--r--src/board.h6
-rw-r--r--src/main.c43
3 files changed, 44 insertions, 20 deletions
diff --git a/src/board.c b/src/board.c
index a0b1bb7..0c133a8 100644
--- a/src/board.c
+++ b/src/board.c
@@ -37,9 +37,18 @@ void precompute_king_attack_table(Bitboard attacks[64]) {
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;
+ (position & notAFile) << 7 | (position << 8) | (position & notHFile) << 9 |
+ (position & notAFile) >> 1 | (position & notHFile) << 1 |
+ (position & notAFile) >> 9 | (position >> 8) | (position & notHFile) >> 7;
+ }
+}
+
+void precompute_pawn_attack_table(Bitboard attacks[64], BYTE color) {
+ for (int index = 0; index < 64; index++) {
+ U64 position = BIT << index;
+
+ if (color == WHITE) attacks[index] = (position & notAFile) << 7 | (position & notHFile) << 9;
+ else attacks[index] = (position & notAFile) >> 9 | (position & notHFile) >> 7;
}
}
diff --git a/src/board.h b/src/board.h
index 11b0c71..cf89794 100644
--- a/src/board.h
+++ b/src/board.h
@@ -56,9 +56,11 @@ 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);
Board parse_FEN(char* FEN);
+
+void precompute_knight_attack_table(Bitboard table[64]);
+void precompute_king_attack_table(Bitboard table[64]);
+void precompute_pawn_attack_table(Bitboard table[64], BYTE color);
diff --git a/src/main.c b/src/main.c
index c8c82cf..d6aa2b8 100644
--- a/src/main.c
+++ b/src/main.c
@@ -2,12 +2,11 @@
#include "board.h"
int main() {
- {
- start_test_section("Bitboards");
+ start_test_section("Bitboards"); {
unit_test(pop_count(0b01110) == 3, "Pop count of 01110 is 3");
}
- {
- start_test_section("Default FEN string");
+
+ 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");
@@ -16,8 +15,8 @@ int main() {
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");
+
+ start_test_section("Test knight attacks"); {
Bitboard attacks[64];
precompute_knight_attack_table(attacks);
@@ -33,8 +32,8 @@ int main() {
"Knight on b7 attacks only d8, d6, c5, a5"
);
}
- {
- start_test_section("Test king attacks");
+
+ start_test_section("Test king attacks"); {
Bitboard attacks[64];
precompute_king_attack_table(attacks);
@@ -45,16 +44,30 @@ int main() {
}
unit_test(max_attacks == 8, "Max amount of king attacks should be 8");
- {
- U64 bit = 1;
- unit_test(
- attacks[h2] == ((BIT << h1) | (BIT << g1) | (BIT << g2) | (BIT << g3) | (BIT << h3)),
- "King on h2 attacks only h1, g1, g2, g3, h3"
- );
- }
+ unit_test(
+ 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("Test pawn attacks"); {
+ Bitboard white_attacks[64];
+ Bitboard black_attacks[64];
+ precompute_pawn_attack_table(white_attacks, WHITE);
+ precompute_pawn_attack_table(black_attacks, BLACK);
+
+ int is_same = 0;
+ int max_attacks = 0;
+ for (int i = 0; i < 64; i++) {
+ int attack_count = pop_count(white_attacks[i]);
+ if (attack_count > max_attacks) max_attacks = attack_count;
+ if (white_attacks[i] == black_attacks[i]) is_same = 1;
+ }
+ unit_test(max_attacks == 2, "Max amount of pawn attacks should be 2");
+ unit_test(is_same == 0, "Black and white pawns always move differently");
+ unit_test(white_attacks[g2] == (BIT << h3 | BIT << f3), "White pawn on g2 attacks only h3 and f3");
+ }
report();
return 0;