[board] Move position flags to a Flags struct in its own module

This commit is contained in:
Eryn Wells 2024-01-13 11:15:09 -08:00
parent 7c80c61690
commit 953c2f1522
3 changed files with 82 additions and 40 deletions

View file

@ -0,0 +1,73 @@
// Eryn Wells <eryn@erynwells.me>
use super::position::BoardSide;
use crate::piece::Color;
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub(super) struct Flags(u8);
impl Flags {
#[inline]
pub(super) fn player_has_right_to_castle_flag_offset(color: Color, side: BoardSide) -> u8 {
((color as u8) << 1) + side as u8
}
pub(super) fn player_has_right_to_castle(&self, color: Color, side: BoardSide) -> bool {
(self.0 & (1 << Self::player_has_right_to_castle_flag_offset(color, side))) != 0
}
pub(super) fn set_player_has_right_to_castle_flag(&mut self, color: Color, side: BoardSide) {
self.0 |= 1 << Self::player_has_right_to_castle_flag_offset(color, side);
}
pub(super) fn clear_player_has_right_to_castle_flag(&mut self, color: Color, side: BoardSide) {
self.0 &= !(1 << Self::player_has_right_to_castle_flag_offset(color, side));
}
}
impl Default for Flags {
fn default() -> Self {
Flags(0b00001111)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::Color;
#[test]
fn castle_flags() {
assert_eq!(
Flags::player_has_right_to_castle_flag_offset(Color::White, BoardSide::King),
0
);
assert_eq!(
Flags::player_has_right_to_castle_flag_offset(Color::White, BoardSide::Queen),
1
);
assert_eq!(
Flags::player_has_right_to_castle_flag_offset(Color::Black, BoardSide::King),
2
);
assert_eq!(
Flags::player_has_right_to_castle_flag_offset(Color::Black, BoardSide::Queen),
3
);
}
#[test]
fn defaults() {
let mut flags: Flags = Default::default();
assert!(flags.player_has_right_to_castle(Color::White, BoardSide::King));
assert!(flags.player_has_right_to_castle(Color::White, BoardSide::Queen));
assert!(flags.player_has_right_to_castle(Color::Black, BoardSide::King));
assert!(flags.player_has_right_to_castle(Color::Black, BoardSide::Queen));
flags.clear_player_has_right_to_castle_flag(Color::White, BoardSide::Queen);
assert!(flags.player_has_right_to_castle(Color::White, BoardSide::King));
assert!(!flags.player_has_right_to_castle(Color::White, BoardSide::Queen));
assert!(flags.player_has_right_to_castle(Color::Black, BoardSide::King));
assert!(flags.player_has_right_to_castle(Color::Black, BoardSide::Queen));
}
}

View file

@ -1,6 +1,7 @@
// Eryn Wells <eryn@erynwells.me> // Eryn Wells <eryn@erynwells.me>
mod diagram_formatter; mod diagram_formatter;
mod flags;
mod pieces; mod pieces;
mod position; mod position;

View file

@ -1,6 +1,6 @@
// Eryn Wells <eryn@erynwells.me> // Eryn Wells <eryn@erynwells.me>
use super::Pieces; use super::{flags::Flags, Pieces};
use crate::{ use crate::{
bitboard::BitBoard, bitboard::BitBoard,
moves::Moves, moves::Moves,
@ -38,7 +38,7 @@ pub struct Position {
/// 1. white can castle queen-side /// 1. white can castle queen-side
/// 2. black can castle king-side /// 2. black can castle king-side
/// 3. black can castle queen-side /// 3. black can castle queen-side
flags: u8, flags: Flags,
/// Composite bitboards for all the pieces of a particular color. /// Composite bitboards for all the pieces of a particular color.
pieces_per_color: [BitBoard; 2], pieces_per_color: [BitBoard; 2],
@ -51,7 +51,7 @@ impl Position {
pub fn empty() -> Position { pub fn empty() -> Position {
Position { Position {
color_to_move: Color::White, color_to_move: Color::White,
flags: 0b00001111, flags: Default::default(),
pieces_per_color: [BitBoard::empty(); 2], pieces_per_color: [BitBoard::empty(); 2],
pieces_per_type: [ pieces_per_type: [
[ [
@ -96,7 +96,7 @@ impl Position {
Position { Position {
color_to_move: Color::White, color_to_move: Color::White,
flags: 0b00001111, flags: Default::default(),
pieces_per_color: [ pieces_per_color: [
white_pieces.iter().fold(BitBoard::empty(), |a, b| a | *b), white_pieces.iter().fold(BitBoard::empty(), |a, b| a | *b),
black_pieces.iter().fold(BitBoard::empty(), |a, b| a | *b), black_pieces.iter().fold(BitBoard::empty(), |a, b| a | *b),
@ -119,20 +119,16 @@ impl Position {
/// 3. In the course of castling on that side, the king must not pass /// 3. In the course of castling on that side, the king must not pass
/// through a square that an enemy piece can see /// through a square that an enemy piece can see
pub(crate) fn player_has_right_to_castle(&self, color: Color, side: BoardSide) -> bool { pub(crate) fn player_has_right_to_castle(&self, color: Color, side: BoardSide) -> bool {
(self.flags & (1 << Self::player_has_right_to_castle_flag_offset(color, side))) != 0 self.flags.player_has_right_to_castle(color, side)
} }
fn set_player_has_right_to_castle_flag(&mut self, color: Color, side: BoardSide) { fn set_player_has_right_to_castle_flag(&mut self, color: Color, side: BoardSide) {
self.flags |= 1 << Self::player_has_right_to_castle_flag_offset(color, side); self.flags.set_player_has_right_to_castle_flag(color, side);
} }
fn clear_player_has_right_to_castle_flag(&mut self, color: Color, side: BoardSide) { fn clear_player_has_right_to_castle_flag(&mut self, color: Color, side: BoardSide) {
self.flags &= !(1 << Self::player_has_right_to_castle_flag_offset(color, side)); self.flags
} .clear_player_has_right_to_castle_flag(color, side);
#[inline]
fn player_has_right_to_castle_flag_offset(color: Color, side: BoardSide) -> u8 {
((color as u8) << 1) + side as u8
} }
pub fn place_piece(&mut self, piece: Piece, square: Square) -> Result<(), PiecePlacementError> { pub fn place_piece(&mut self, piece: Piece, square: Square) -> Result<(), PiecePlacementError> {
@ -277,34 +273,6 @@ mod tests {
} }
#[test] #[test]
fn castle_flags() {
assert_eq!(
Position::player_has_right_to_castle_flag_offset(Color::White, BoardSide::King),
0
);
assert_eq!(
Position::player_has_right_to_castle_flag_offset(Color::White, BoardSide::Queen),
1
);
assert_eq!(
Position::player_has_right_to_castle_flag_offset(Color::Black, BoardSide::King),
2
);
assert_eq!(
Position::player_has_right_to_castle_flag_offset(Color::Black, BoardSide::Queen),
3
);
let mut pos = Position::starting();
assert!(pos.player_has_right_to_castle(Color::White, BoardSide::King));
assert!(pos.player_has_right_to_castle(Color::White, BoardSide::Queen));
assert!(pos.player_has_right_to_castle(Color::Black, BoardSide::King));
assert!(pos.player_has_right_to_castle(Color::Black, BoardSide::Queen));
pos.clear_player_has_right_to_castle_flag(Color::White, BoardSide::Queen);
assert!(pos.player_has_right_to_castle(Color::White, BoardSide::King));
assert!(!pos.player_has_right_to_castle(Color::White, BoardSide::Queen));
assert!(pos.player_has_right_to_castle(Color::Black, BoardSide::King));
assert!(pos.player_has_right_to_castle(Color::Black, BoardSide::Queen));
} }
} }