diff options
author | eug-vs <eugene@eug-vs.xyz> | 2023-08-24 02:36:14 +0300 |
---|---|---|
committer | eug-vs <eugene@eug-vs.xyz> | 2023-08-24 02:36:14 +0300 |
commit | 791ba3906d0ec41f328c20a9a1be8eabb12a84c6 (patch) | |
tree | 84c7281df28c92dacbdae7f4aee26f38397d43ab | |
parent | 85fbcdadec3853a92da6d434dbc94bb85bdfdcfe (diff) | |
download | chessnost-791ba3906d0ec41f328c20a9a1be8eabb12a84c6.tar.gz |
perf: use iterator in bitboard serialization
-rw-r--r-- | src/bitboard.rs | 24 | ||||
-rw-r--r-- | src/board/move_generation.rs | 1 | ||||
-rw-r--r-- | src/grossmeister/evaluation.rs | 7 |
3 files changed, 19 insertions, 13 deletions
diff --git a/src/bitboard.rs b/src/bitboard.rs index 056822b..48a60d8 100644 --- a/src/bitboard.rs +++ b/src/bitboard.rs @@ -28,7 +28,7 @@ pub trait BitboardFns { fn bitscan_and_reset(&mut self) -> Square; /// Convert bitboard into the list of squares - fn serialize(self) -> Vec<Square>; + fn serialize(self) -> SquareIterator; /// Return bitboard shifted nort, no wrap occurs fn nort_one(self) -> Self; @@ -109,12 +109,8 @@ impl BitboardFns for Bitboard { square } - fn serialize(mut self) -> Vec<Square> { - let mut serialized = Vec::with_capacity(64); - while self > 0 { - serialized.push(self.bitscan_and_reset()); - } - serialized + fn serialize(self) -> SquareIterator { + SquareIterator(self) } fn nort_one(self) -> Self { @@ -150,6 +146,18 @@ impl BitboardFns for Bitboard { } } +pub struct SquareIterator (Bitboard); +impl Iterator for SquareIterator { + type Item = Square; + + fn next(&mut self) -> Option<Self::Item> { + if self.0 > 0 { + return Some(self.0.bitscan_and_reset()); + } + None + } +} + #[cfg(test)] mod tests { use super::*; @@ -184,7 +192,7 @@ mod tests { #[test] fn test_serialize_bitboard() { let bb = 1 << 4 | 1 << 15 | 1 << 60; - let serialized = bb.serialize(); + let serialized = bb.serialize().collect::<Vec<_>>(); assert_eq!(serialized[0], Square::from(4)); assert_eq!(serialized[1], Square::from(15)); assert_eq!(serialized[2], Square::from(60)); diff --git a/src/board/move_generation.rs b/src/board/move_generation.rs index 98df056..0735309 100644 --- a/src/board/move_generation.rs +++ b/src/board/move_generation.rs @@ -99,7 +99,6 @@ impl Board { if player_pieces[Piece::King as usize].bitscan() == king_home_position { for rook_square in player_pieces[Piece::Rook as usize] .serialize() - .iter() .filter(|rook_square| rook_square.rank() == king_home_position.rank()) { match rook_square.file() { diff --git a/src/grossmeister/evaluation.rs b/src/grossmeister/evaluation.rs index 6669545..b78c49a 100644 --- a/src/grossmeister/evaluation.rs +++ b/src/grossmeister/evaluation.rs @@ -190,7 +190,7 @@ impl Grossmeister { } _ => panic!("Unreachable") }; - total + bitboard.serialize().iter().fold(0., |acc, &square| { + total + bitboard.serialize().fold(0., |acc, square| { let pst_index = match color { Color::White => square.mirror(), Color::Black => square, @@ -280,8 +280,8 @@ impl Grossmeister { Color::White => self.board.piece_sets[Piece::PawnBlack as usize], }; - let pawn_attacked_squares = opponent_pawns.serialize().iter().fold(0u64, |acc, square| { - acc | self.board.attacks.pawn[color.flip() as usize][*square as usize] + let pawn_attacked_squares = opponent_pawns.serialize().fold(0u64, |acc, square| { + acc | self.board.attacks.pawn[color.flip() as usize][square as usize] }); // Exclude squares controlled by enemy pawns from mobility @@ -325,7 +325,6 @@ impl Grossmeister { if *piece == king_home_position.to_bitboard() { for rook_square in player_pieces[Piece::Rook as usize] .serialize() - .iter() .filter(|rook_square| rook_square.rank() == king_home_position.rank()) { match rook_square.file() { |