aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/attacks.rs99
-rw-r--r--src/bitboard.rs1
-rw-r--r--src/board.rs6
-rw-r--r--src/main.rs1
4 files changed, 104 insertions, 3 deletions
diff --git a/src/attacks.rs b/src/attacks.rs
new file mode 100644
index 0000000..ece87b6
--- /dev/null
+++ b/src/attacks.rs
@@ -0,0 +1,99 @@
+use crate::bitboard::Bitboard;
+
+static NOT_A_FILE: Bitboard = 0xFEFEFEFEFEFEFEFE;
+static NOT_B_FILE: Bitboard = 0xFDFDFDFDFDFDFDFD;
+static NOT_G_FILE: Bitboard = 0xBFBFBFBFBFBFBFBF;
+static NOT_H_FILE: Bitboard = 0x7F7F7F7F7F7F7F7F;
+
+type AttackTable = [Bitboard; 64];
+
+#[derive(Debug)]
+pub struct Attacks {
+ pub knight: AttackTable,
+ pub king: AttackTable,
+}
+
+impl Attacks {
+ pub fn new() -> Self {
+ let mut knight = [0; 64];
+ let mut king = [0; 64];
+ Self::precompute_knight_attacks(&mut knight);
+ Self::precompute_king_attacks(&mut king);
+ Self { knight, king }
+ }
+
+ fn precompute_knight_attacks(attacks: &mut AttackTable) {
+ for index in 0..64 {
+ let position = 1u64 << index;
+ attacks[index] =
+ ((position & NOT_A_FILE & NOT_B_FILE) << 6) |
+ ((position & NOT_G_FILE & NOT_H_FILE) << 10) |
+ ((position & NOT_A_FILE) << 15) |
+ ((position & NOT_H_FILE) << 17) |
+ ((position & NOT_G_FILE & NOT_H_FILE) >> 6) |
+ ((position & NOT_A_FILE & NOT_B_FILE) >> 10) |
+ ((position & NOT_H_FILE) >> 15) |
+ ((position & NOT_A_FILE) >> 17);
+ }
+ }
+
+ fn precompute_king_attacks(attacks: &mut AttackTable) {
+ for index in 0..64 {
+ let position = 1u64 << index;
+ attacks[index] =
+ ((position & NOT_A_FILE) >> 1) |
+ ((position & NOT_A_FILE) << 7) |
+ ((position & NOT_A_FILE) >> 9) |
+ ((position & NOT_H_FILE) << 1) |
+ ((position & NOT_H_FILE) >> 7) |
+ ((position & NOT_H_FILE) << 9) |
+ (position << 8) |
+ (position >> 8);
+ }
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use crate::{bitboard::pop_count, board::Square};
+
+ use super::*;
+
+ #[test]
+ fn test_knight_attacks() {
+ let attacks = Attacks::new();
+ let e4_attacks = attacks.knight[Square::E4 as usize];
+
+ assert_ne!(e4_attacks & 1 << Square::G5 as usize, 0);
+ assert_ne!(e4_attacks & 1 << Square::G3 as usize, 0);
+ assert_ne!(e4_attacks & 1 << Square::C5 as usize, 0);
+ assert_ne!(e4_attacks & 1 << Square::C3 as usize, 0);
+ assert_ne!(e4_attacks & 1 << Square::D2 as usize, 0);
+ assert_ne!(e4_attacks & 1 << Square::F2 as usize, 0);
+ assert_ne!(e4_attacks & 1 << Square::D6 as usize, 0);
+ assert_ne!(e4_attacks & 1 << Square::F6 as usize, 0);
+
+ assert_eq!(e4_attacks & 1 << Square::E5 as usize, 0);
+ assert_eq!(e4_attacks & 1 << Square::D4 as usize, 0);
+ assert_eq!(e4_attacks & 1 << Square::A1 as usize, 0);
+
+ assert_eq!(pop_count(attacks.knight[Square::G1 as usize]), 3);
+ assert_eq!(pop_count(attacks.knight[Square::H8 as usize]), 2);
+ }
+
+ #[test]
+ fn test_king_attacks() {
+ let attacks = Attacks::new();
+ assert_eq!(pop_count(attacks.king[Square::E4 as usize]), 8);
+
+ assert_eq!(pop_count(attacks.king[Square::A1 as usize]), 3);
+ assert_eq!(pop_count(attacks.king[Square::A8 as usize]), 3);
+ assert_eq!(pop_count(attacks.king[Square::H1 as usize]), 3);
+ assert_eq!(pop_count(attacks.king[Square::H8 as usize]), 3);
+
+ assert_eq!(pop_count(attacks.king[Square::E1 as usize]), 5);
+ assert_eq!(pop_count(attacks.king[Square::E8 as usize]), 5);
+ assert_eq!(pop_count(attacks.king[Square::A4 as usize]), 5);
+ assert_eq!(pop_count(attacks.king[Square::H4 as usize]), 5);
+ }
+}
diff --git a/src/bitboard.rs b/src/bitboard.rs
index 4a1ef50..6481863 100644
--- a/src/bitboard.rs
+++ b/src/bitboard.rs
@@ -1,3 +1,4 @@
+/// Finite set of up to 64 bits representing chess board squares
pub type Bitboard = u64;
/// Print bitboard on screen in the same way squares appear in memory
diff --git a/src/board.rs b/src/board.rs
index 991820a..13f86ec 100644
--- a/src/board.rs
+++ b/src/board.rs
@@ -6,7 +6,7 @@ pub struct Board {
}
-enum PieceTypes {
+pub enum PieceTypes {
Pawn,
PawnBlack,
Knight,
@@ -107,14 +107,14 @@ impl Board {
}
-enum Color {
+pub enum Color {
White,
Black,
}
/// Aliases to board square indexes
#[allow(dead_code)]
-enum Square {
+pub enum Square {
A1, B1, C1, D1, E1, F1, G1, H1,
A2, B2, C2, D2, E2, F2, G2, H2,
A3, B3, C3, D3, E3, F3, G3, H3,
diff --git a/src/main.rs b/src/main.rs
index 11ac972..dc04d4b 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,5 +1,6 @@
mod bitboard;
mod board;
+mod attacks;
fn main() {
println!("Hello, world!");