Compare commits
7 commits
a904e4a5bb
...
3a0541a2c3
Author | SHA1 | Date | |
---|---|---|---|
3a0541a2c3 | |||
b6d27356ac | |||
146e4d34d3 | |||
b505606925 | |||
b3ff8dec49 | |||
484fcf342e | |||
45183c910c |
4 changed files with 55 additions and 14 deletions
|
@ -160,9 +160,9 @@ impl BitBoard {
|
|||
///
|
||||
/// ```
|
||||
/// use chessfriend_bitboard::BitBoard;
|
||||
/// assert_eq!(BitBoard::empty().population_count(), 0);
|
||||
/// assert_eq!(BitBoard::EMPTY.population_count(), 0);
|
||||
/// assert_eq!(BitBoard::new(0b01011110010).population_count(), 6);
|
||||
/// assert_eq!(BitBoard::full().population_count(), 64);
|
||||
/// assert_eq!(BitBoard::FULL.population_count(), 64);
|
||||
/// ```
|
||||
#[must_use]
|
||||
pub const fn population_count(&self) -> u32 {
|
||||
|
@ -211,8 +211,8 @@ impl BitBoard {
|
|||
///
|
||||
/// ```
|
||||
/// use chessfriend_bitboard::BitBoard;
|
||||
/// assert!(!BitBoard::empty().is_single_square(), "Empty bitboards represent no squares");
|
||||
/// assert!(!BitBoard::full().is_single_square(), "Full bitboards represent all the squares");
|
||||
/// assert!(!BitBoard::EMPTY.is_single_square(), "Empty bitboards represent no squares");
|
||||
/// assert!(!BitBoard::FULL.is_single_square(), "Full bitboards represent all the squares");
|
||||
/// assert!(!BitBoard::new(0b010011110101101100).is_single_square(), "This bitboard represents a bunch of squares");
|
||||
/// assert!(BitBoard::new(0b10000000000000).is_single_square());
|
||||
/// ```
|
||||
|
@ -233,6 +233,38 @@ impl BitBoard {
|
|||
}
|
||||
}
|
||||
|
||||
/// Iterate through the occupied squares in a direction specified by a
|
||||
/// compass direction. This method is mose useful for bitboards of slider
|
||||
/// rays so that iteration proceeds in order along the ray's direction.
|
||||
///
|
||||
/// ## Examples
|
||||
///
|
||||
/// ```
|
||||
/// use chessfriend_bitboard::BitBoard;
|
||||
/// use chessfriend_core::{Direction, Square};
|
||||
///
|
||||
/// let ray = BitBoard::ray(Square::E4, Direction::North);
|
||||
/// assert_eq!(
|
||||
/// ray.occupied_squares_direction(Direction::North).collect::<Vec<Square>>(),
|
||||
/// vec![Square::E5, Square::E6, Square::E7, Square::E8]
|
||||
/// );
|
||||
/// ```
|
||||
///
|
||||
#[must_use]
|
||||
pub fn occupied_squares_direction(
|
||||
&self,
|
||||
direction: Direction,
|
||||
) -> Box<dyn Iterator<Item = Square>> {
|
||||
match direction {
|
||||
Direction::North | Direction::NorthEast | Direction::NorthWest | Direction::East => {
|
||||
Box::new(self.occupied_squares_trailing())
|
||||
}
|
||||
Direction::SouthEast | Direction::South | Direction::SouthWest | Direction::West => {
|
||||
Box::new(self.occupied_squares_leading())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn occupied_squares_leading(&self) -> LeadingBitScanner {
|
||||
LeadingBitScanner::new(self.0)
|
||||
|
@ -255,6 +287,12 @@ impl BitBoard {
|
|||
}
|
||||
}
|
||||
|
||||
/// Get the first occupied square in the given direction.
|
||||
///
|
||||
/// ## To-Do
|
||||
///
|
||||
/// - Take `direction` by value instead of reference
|
||||
///
|
||||
#[must_use]
|
||||
pub fn first_occupied_square(&self, direction: &IterationDirection) -> Option<Square> {
|
||||
match direction {
|
||||
|
|
|
@ -46,7 +46,7 @@ impl Board {
|
|||
|
||||
let color = self.unwrap_color(color);
|
||||
|
||||
if !self.has_castling_right_unwrapped(color, wing.into()) {
|
||||
if !self.has_castling_right_unwrapped(color, wing) {
|
||||
return Err(CastleEvaluationError::NoRights { color, wing });
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ impl Score {
|
|||
///
|
||||
/// ```
|
||||
/// use chessfriend_core::score::Score;
|
||||
/// assert_eq!(!Score::MIN, Score::MAX);
|
||||
/// assert_eq!(-Score::MIN, Score::MAX);
|
||||
/// ```
|
||||
///
|
||||
pub const MIN: Score = Score(Value::MIN + 1);
|
||||
|
@ -31,7 +31,7 @@ impl Score {
|
|||
/// The maximum possible value of a score.
|
||||
pub const MAX: Score = Score(Value::MAX);
|
||||
|
||||
const CENTIPAWNS_PER_POINT: f32 = 100.0;
|
||||
pub(crate) const CENTIPAWNS_PER_POINT: f32 = 100.0;
|
||||
|
||||
#[must_use]
|
||||
pub const fn new(value: Value) -> Self {
|
||||
|
|
|
@ -70,18 +70,21 @@ impl Shape {
|
|||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn is_promotable(&self) -> bool {
|
||||
pub const fn is_promotable(&self) -> bool {
|
||||
matches!(self, Self::Knight | Self::Bishop | Self::Rook | Self::Queen)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn score(self) -> Score {
|
||||
pub const fn score(self) -> Score {
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
const CP_PER_PT: i32 = Score::CENTIPAWNS_PER_POINT as i32;
|
||||
|
||||
match self {
|
||||
Shape::Pawn => Score::new(100),
|
||||
Shape::Knight | Shape::Bishop => Score::new(300),
|
||||
Shape::Rook => Score::new(500),
|
||||
Shape::Queen => Score::new(900),
|
||||
Shape::King => Score::new(20000),
|
||||
Shape::Pawn => Score::new(CP_PER_PT),
|
||||
Shape::Knight | Shape::Bishop => Score::new(3 * CP_PER_PT),
|
||||
Shape::Rook => Score::new(5 * CP_PER_PT),
|
||||
Shape::Queen => Score::new(9 * CP_PER_PT),
|
||||
Shape::King => Score::new(200 * CP_PER_PT),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue