aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/attacks.rs49
-rw-r--r--src/bitboard.rs4
-rw-r--r--src/board.rs27
3 files changed, 51 insertions, 29 deletions
diff --git a/src/attacks.rs b/src/attacks.rs
index 73f3d73..d5bc8a3 100644
--- a/src/attacks.rs
+++ b/src/attacks.rs
@@ -307,14 +307,21 @@ mod tests {
use super::*;
+ static DEFAULT_OCCUPANCY: Bitboard =
+ 1 << Square::B7 as usize |
+ 1 << Square::B1 as usize |
+ 1 << Square::C2 as usize |
+ 1 << Square::F3 as usize;
+
#[test]
fn test_pawn_attacks() {
let attacks = Attacks::precompute_pawn_attacks();
let square = Square::E4 as usize;
-
let white_attacks = attacks[Color::White as usize][square];
+
+ print(white_attacks, "Pawn e4");
+
assert_eq!(white_attacks, 1 << Square::D5 as usize | 1 << Square::F5 as usize);
- print(white_attacks);
assert_eq!(attacks[Color::White as usize][Square::H4 as usize], 1 << Square::G5 as usize);
assert_eq!(attacks[Color::White as usize][Square::A4 as usize], 1 << Square::B5 as usize);
@@ -337,6 +344,8 @@ mod tests {
let attacks = Attacks::precompute_knight_attacks();
let e4_attacks = attacks[Square::E4 as usize];
+ print(e4_attacks, "Knight e4");
+
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);
@@ -352,12 +361,14 @@ mod tests {
assert_eq!(pop_count(attacks[Square::G1 as usize]), 3);
assert_eq!(pop_count(attacks[Square::H8 as usize]), 2);
- print(e4_attacks);
}
#[test]
fn test_king_attacks() {
let attacks = Attacks::precompute_king_attacks();
+
+ print(attacks[Square::E4 as usize], "King e4");
+
assert_eq!(pop_count(attacks[Square::E4 as usize]), 8);
assert_eq!(pop_count(attacks[Square::A1 as usize]), 3);
@@ -369,7 +380,6 @@ mod tests {
assert_eq!(pop_count(attacks[Square::E8 as usize]), 5);
assert_eq!(pop_count(attacks[Square::A4 as usize]), 5);
assert_eq!(pop_count(attacks[Square::H4 as usize]), 5);
- print(attacks[Square::E4 as usize]);
}
#[test]
@@ -402,19 +412,17 @@ mod tests {
attacks[5][square] |
attacks[6][square] |
attacks[7][square];
- print(bitboard);
+ print(bitboard, "Rays from e4");
}
#[test]
fn test_bishop_attacks() {
let attacks = Attacks::new();
let square = Square::E4 as u8;
- let occupancy =
- 1 << Square::B7 as usize |
- 1 << Square::B1 as usize |
- 1 << Square::C2 as usize |
- 1 << Square::F3 as usize;
- let bb = attacks.bishop(occupancy, square);
+ let bb = attacks.bishop(DEFAULT_OCCUPANCY, square);
+
+ print(DEFAULT_OCCUPANCY, "Occupancy");
+ print(bb, "Bishop e4");
assert_ne!(bb & 1 << Square::C2 as u8, 0);
assert_eq!(bb & 1 << Square::B1 as u8, 0);
@@ -423,8 +431,6 @@ mod tests {
assert_ne!(bb & 1 << Square::H7 as u8, 0);
assert_ne!(bb & 1 << Square::B7 as u8, 0);
assert_eq!(bb & 1 << Square::A8 as u8, 0);
-
- print(bb);
}
#[test]
@@ -439,6 +445,9 @@ mod tests {
1 << Square::F3 as usize;
let bb = attacks.rook(occupancy, square);
+ print(occupancy, "Occupancy");
+ print(bb, "Rook e4");
+
assert_ne!(bb & 1 << Square::E8 as u8, 0);
assert_ne!(bb & 1 << Square::E7 as u8, 0);
assert_ne!(bb & 1 << Square::E6 as u8, 0);
@@ -449,22 +458,14 @@ mod tests {
assert_ne!(bb & 1 << Square::A4 as u8, 0);
assert_ne!(bb & 1 << Square::H4 as u8, 0);
assert_eq!(bb & 1 << Square::E4 as u8, 0);
-
- print(bb);
}
#[test]
fn test_queen_attacks() {
let attacks = Attacks::new();
let square = Square::E4 as u8;
- let occupancy =
- 1 << Square::B7 as usize |
- 1 << Square::B1 as usize |
- 1 << Square::C2 as usize |
- 1 << Square::E3 as usize |
- 1 << Square::F3 as usize;
- let bb = attacks.queen(occupancy, square);
- print(occupancy);
- print(bb);
+ let bb = attacks.queen(DEFAULT_OCCUPANCY, square);
+ print(DEFAULT_OCCUPANCY, "Occupancy");
+ print(bb, "Queen e4");
}
}
diff --git a/src/bitboard.rs b/src/bitboard.rs
index 1d6d0bc..6312dd8 100644
--- a/src/bitboard.rs
+++ b/src/bitboard.rs
@@ -4,8 +4,8 @@ pub type Bitboard = u64;
/// Print bitboard on screen in the same way squares appear in memory
/// (i.e the board is actually flipped along X)
#[allow(dead_code)]
-pub fn print(bb: Bitboard) {
- println!();
+pub fn print(bb: Bitboard, title: &str) {
+ println!("\n {}", title);
for rank in (0..8).rev() {
print!("{}|", rank + 1);
for file in 0..8 {
diff --git a/src/board.rs b/src/board.rs
index 241412e..b76356f 100644
--- a/src/board.rs
+++ b/src/board.rs
@@ -3,6 +3,9 @@ use crate::bitboard::Bitboard;
#[derive(Debug)]
pub struct Board {
pub pieces: [Bitboard; 12],
+
+ pub occupancy: Bitboard,
+ pub ply: u16,
}
@@ -80,7 +83,21 @@ impl Board {
}
}
- Self { pieces }
+ let mut board = Self { pieces, occupancy: 0, ply: 0 };
+ board.update_occupancy();
+ board
+ }
+
+ fn update_occupancy(&mut self) {
+ self.occupancy = 0;
+ // TODO: reduce
+ for piece in self.pieces {
+ self.occupancy |= piece;
+ }
+ }
+
+ fn empty(&self) -> Bitboard {
+ !self.occupancy
}
pub fn print(&self) {
@@ -130,7 +147,7 @@ pub enum Square {
#[cfg(test)]
mod tests {
use super::*;
- use crate::bitboard::{pop_count, bitscan};
+ use crate::bitboard::{pop_count, bitscan, print};
#[test]
fn test_square_enum() {
@@ -144,6 +161,9 @@ mod tests {
let fen = String::from("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1");
let board = Board::from_FEN(fen);
+ board.print();
+ print(board.empty(), "Empty squares");
+
assert_eq!(pop_count(board.pieces[PieceTypes::Pawn as usize]), 8);
assert_eq!(pop_count(board.pieces[PieceTypes::Knight as usize]), 2);
assert_eq!(pop_count(board.pieces[PieceTypes::Bishop as usize]), 2);
@@ -161,6 +181,7 @@ mod tests {
assert_eq!(bitscan(board.pieces[PieceTypes::King as usize]), Square::E1 as u8);
assert_eq!(bitscan(board.pieces[PieceTypes::QueenBlack as usize]), Square::D8 as u8);
- board.print();
+ assert_eq!(pop_count(board.occupancy), 32);
+ assert_eq!(pop_count(board.empty()), 32);
}
}