aboutsummaryrefslogtreecommitdiff
path: root/src/board/mod.rs
diff options
context:
space:
mode:
authoreug-vs <eugene@eug-vs.xyz>2023-02-21 17:49:51 +0300
committereug-vs <eugene@eug-vs.xyz>2023-02-23 14:01:03 +0300
commitf60c573ba71207c18a28413e3940a4e21b07c73f (patch)
tree3e50e9ea6cd0129414db92cd50805ebeb65a4676 /src/board/mod.rs
parent69f3c48fb99d96f3fbc4ab49f5fb6d1d8e90e270 (diff)
downloadchessnost-f60c573ba71207c18a28413e3940a4e21b07c73f.tar.gz
refactor: create grossmeister module
Diffstat (limited to 'src/board/mod.rs')
-rw-r--r--src/board/mod.rs83
1 files changed, 26 insertions, 57 deletions
diff --git a/src/board/mod.rs b/src/board/mod.rs
index e6a6446..579488b 100644
--- a/src/board/mod.rs
+++ b/src/board/mod.rs
@@ -1,12 +1,10 @@
use crate::{bitboard::{Bitboard, BitboardFns}, moves::{Move, MoveKind}, attacks::Attacks, square::Square, board::io::IO};
-use self::{ttable::{TranspositionTable, TTABLE_SIZE}, zobrist::{ZobristSeed, Zobrist}, piece::Piece, color::Color};
+use self::{zobrist::{ZobristSeed, Zobrist}, piece::Piece, color::Color};
pub mod io;
pub mod color;
pub mod piece;
mod zobrist;
-mod engine;
-mod ttable;
#[derive(Debug, Clone, Copy)]
pub enum CastlingSide {
@@ -14,7 +12,9 @@ pub enum CastlingSide {
Queen,
}
-#[derive(Debug, Clone, PartialEq)]
+/// Chess board is an main interface to the internal game state.
+/// Board defines rules of the game and manages players actions.
+#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Board {
pub ply: u16,
pub piece_sets: [Bitboard; 12],
@@ -27,10 +27,8 @@ pub struct Board {
pub occupancy: Bitboard,
/// Zobrist hash of the current position
pub hash: u64,
-
- // TODO: remove
- transposition_table: TranspositionTable,
zobrist_seed: ZobristSeed,
+
attacks: Attacks,
}
@@ -49,22 +47,22 @@ impl Board {
self.occupancy = self.piece_sets.iter().fold(0, |acc, bitboard| acc | bitboard)
}
- fn empty(&self) -> Bitboard {
+ pub fn empty(&self) -> Bitboard {
!self.occupancy
}
- fn pieces_by_color(&self, color: Color) -> &[Bitboard] {
+ pub fn pieces_by_color(&self, color: Color) -> &[Bitboard] {
match color {
Color::White => &self.piece_sets[0..6],
Color::Black => &self.piece_sets[6..12],
}
}
- fn color_occupancy(&self, color: Color) -> Bitboard {
+ pub fn color_occupancy(&self, color: Color) -> Bitboard {
self.pieces_by_color(color).iter().fold(0, |acc, bitboard| acc | bitboard)
}
- fn piece_by_square(&self, square: Square) -> Option<Piece> {
+ pub fn piece_by_square(&self, square: Square) -> Option<Piece> {
let square_bb = square.to_bitboard();
self.piece_sets
.iter()
@@ -73,6 +71,21 @@ impl Board {
.and_then(|(pt, _)| Some(Piece::from(pt)))
}
+ pub fn ep_bitboard(&self) -> Bitboard {
+ let color = self.color();
+ match self.ep_target {
+ Some(square) => {
+ let rank = square.rank();
+ if (rank == 2 && color == Color::Black) || (rank == 5 && color == Color::White) {
+ square.to_bitboard()
+ } else {
+ 0
+ }
+ }
+ None => 0,
+ }
+ }
+
/// *Blindlessly* apply a move without any validation
/// Legality test should still be performed
pub fn make_move(&mut self, mov: Move) -> Option<Piece> {
@@ -302,7 +315,7 @@ impl Board {
self.ply -= 1;
}
- fn is_square_attacked(&self, square: Square, attacker_color: Color) -> bool {
+ pub fn is_square_attacked(&self, square: Square, attacker_color: Color) -> bool {
for (piece_type, piece) in self.pieces_by_color(attacker_color).iter().enumerate() {
match Piece::from(piece_type) {
Piece::Queen => {
@@ -341,7 +354,7 @@ impl Board {
false
}
- fn is_king_in_check(&self, color: Color) -> bool {
+ pub fn is_king_in_check(&self, color: Color) -> bool {
let king_bb = match color {
Color::White => self.piece_sets[Piece::King as usize],
Color::Black => self.piece_sets[Piece::KingBlack as usize],
@@ -365,31 +378,6 @@ mod tests {
}
#[test]
- fn generate_pseudolegal_moves_starting_position() {
- let mut board = Board::new();
- let moves = board.generate_pseudolegal_moves();
- board.ply += 1;
- let black_moves = board.generate_pseudolegal_moves();
-
- assert_eq!(moves.len(), 20);
- assert_eq!(black_moves.len(), 20);
-
- for mov in moves {
- mov.print();
- }
- }
-
- #[test]
- fn mobility() {
- let board = Board::new();
- let white = board.mobility(Color::White);
- let black = board.mobility(Color::Black);
-
- assert_eq!(white, 20.);
- assert_eq!(black, 20.);
- }
-
- #[test]
fn make_move() {
let fen = String::from("q1b2k2/5p1p/4p1pb/pPPp4/3N4/3nPB2/P2QKnR1/1R6 w - - 0 25");
let mut board = Board::from_FEN(fen);
@@ -459,23 +447,4 @@ mod tests {
assert_eq!(board.is_square_attacked(Square::E4, Color::White), false);
assert_eq!(board.is_square_attacked(Square::B6, Color::Black), true);
}
-
- #[test]
- fn moved_king_castle() {
- let fen = String::from("4k2r/ppp1n3/8/4R1Pp/5P2/q1P5/P1P1BP2/1K1R4 b - - 2 22");
- let mut board = Board::from_FEN(fen);
- board.ply += 1;
-
- // Shuffle kings around, returning to the same position
- board.make_move(Move { source: Square::E8, target: Square::F8, kind: MoveKind::Quiet });
- board.make_move(Move { source: Square::B1, target: Square::A1, kind: MoveKind::Quiet });
- board.make_move(Move { source: Square::F8, target: Square::E8, kind: MoveKind::Quiet });
- board.make_move(Move { source: Square::A1, target: Square::B1, kind: MoveKind::Quiet });
-
- let moves = board.generate_pseudolegal_moves();
-
- let castle = moves.iter().find(|m| **m == Move { source: Square::E8, target: Square::G8, kind: MoveKind::Castle });
- println!("{:?}", board.castling_rights);
- assert!(castle.is_none(), "Castle should not be allowed after king has moved");
- }
}