[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>
mod diagram_formatter;
mod flags;
mod pieces;
mod position;

View file

@ -1,6 +1,6 @@
// Eryn Wells <eryn@erynwells.me>
use super::Pieces;
use super::{flags::Flags, Pieces};
use crate::{
bitboard::BitBoard,
moves::Moves,
@ -38,7 +38,7 @@ pub struct Position {
/// 1. white can castle queen-side
/// 2. black can castle king-side
/// 3. black can castle queen-side
flags: u8,
flags: Flags,
/// Composite bitboards for all the pieces of a particular color.
pieces_per_color: [BitBoard; 2],
@ -51,7 +51,7 @@ impl Position {
pub fn empty() -> Position {
Position {
color_to_move: Color::White,
flags: 0b00001111,
flags: Default::default(),
pieces_per_color: [BitBoard::empty(); 2],
pieces_per_type: [
[
@ -96,7 +96,7 @@ impl Position {
Position {
color_to_move: Color::White,
flags: 0b00001111,
flags: Default::default(),
pieces_per_color: [
white_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
/// through a square that an enemy piece can see
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) {
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) {
self.flags &= !(1 << Self::player_has_right_to_castle_flag_offset(color, side));
}
#[inline]
fn player_has_right_to_castle_flag_offset(color: Color, side: BoardSide) -> u8 {
((color as u8) << 1) + side as u8
self.flags
.clear_player_has_right_to_castle_flag(color, side);
}
pub fn place_piece(&mut self, piece: Piece, square: Square) -> Result<(), PiecePlacementError> {
@ -277,34 +273,6 @@ mod tests {
}
#[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));
}
}