From 43dc24718c442ef45f6cecf5790df0ab84a72cfc Mon Sep 17 00:00:00 2001 From: eug-vs Date: Thu, 23 Feb 2023 13:21:57 +0300 Subject: refactor: apply clippy suggestions --- src/attacks.rs | 52 +++++++++++++++----------- src/bitboard.rs | 8 ++-- src/board/io.rs | 2 +- src/board/mod.rs | 59 ++++++++++++++++-------------- src/board/zobrist.rs | 25 ++++++------- src/grossmeister/mod.rs | 2 +- src/grossmeister/move_generation.rs | 23 +++++------- src/grossmeister/search.rs | 73 ++++++++++++++++--------------------- src/main.rs | 6 +-- src/moves.rs | 6 +-- 10 files changed, 123 insertions(+), 133 deletions(-) (limited to 'src') diff --git a/src/attacks.rs b/src/attacks.rs index d0f2ddd..f666bae 100644 --- a/src/attacks.rs +++ b/src/attacks.rs @@ -49,6 +49,12 @@ pub struct Attacks { pub ray_attacks: [AttackTable; 8], } +impl Default for Attacks { + fn default() -> Self { + Self::new() + } +} + #[allow(unused)] impl Attacks { pub fn new() -> Self { @@ -97,34 +103,36 @@ impl Attacks { fn precompute_knight_attacks() -> AttackTable { let mut attacks = [0; 64]; - for index in 0..64 { - let square = 1u64 << index; - attacks[index] = - ((square & NOT_A_FILE & NOT_B_FILE) << 6) | - ((square & NOT_G_FILE & NOT_H_FILE) << 10) | - ((square & NOT_A_FILE) << 15) | - ((square & NOT_H_FILE) << 17) | - ((square & NOT_G_FILE & NOT_H_FILE) >> 6) | - ((square & NOT_A_FILE & NOT_B_FILE) >> 10) | - ((square & NOT_H_FILE) >> 15) | - ((square & NOT_A_FILE) >> 17); + + for (index, bitboard) in attacks.iter_mut().enumerate() { + let square_bb = Square::from(index as u8).to_bitboard(); + *bitboard = + ((square_bb & NOT_A_FILE & NOT_B_FILE) << 6) | + ((square_bb & NOT_G_FILE & NOT_H_FILE) << 10) | + ((square_bb & NOT_A_FILE) << 15) | + ((square_bb & NOT_H_FILE) << 17) | + ((square_bb & NOT_G_FILE & NOT_H_FILE) >> 6) | + ((square_bb & NOT_A_FILE & NOT_B_FILE) >> 10) | + ((square_bb & NOT_H_FILE) >> 15) | + ((square_bb & NOT_A_FILE) >> 17); } attacks } fn precompute_king_attacks() -> AttackTable { let mut attacks = [0; 64]; - for index in 0..64 { - let square = 1u64 << index; - attacks[index] = - ((square & NOT_A_FILE) >> 1) | - ((square & NOT_A_FILE) << 7) | - ((square & NOT_A_FILE) >> 9) | - ((square & NOT_H_FILE) << 1) | - ((square & NOT_H_FILE) >> 7) | - ((square & NOT_H_FILE) << 9) | - (square << 8) | - (square >> 8); + + for (index, bitboard) in attacks.iter_mut().enumerate() { + let square_bb = Square::from(index as u8).to_bitboard(); + *bitboard = + ((square_bb & NOT_A_FILE) >> 1) | + ((square_bb & NOT_A_FILE) << 7) | + ((square_bb & NOT_A_FILE) >> 9) | + ((square_bb & NOT_H_FILE) << 1) | + ((square_bb & NOT_H_FILE) >> 7) | + ((square_bb & NOT_H_FILE) << 9) | + (square_bb << 8) | + (square_bb >> 8); } attacks } diff --git a/src/bitboard.rs b/src/bitboard.rs index ad21664..4fb5b30 100644 --- a/src/bitboard.rs +++ b/src/bitboard.rs @@ -5,7 +5,7 @@ pub type Bitboard = u64; pub trait BitboardFns { /// Print bitboard on the screen - fn print(self, title: &str) -> (); + fn print(self, title: &str); /// Return bitboard cardinality, aka number of elements in the set fn pop_count(self) -> u8; @@ -43,7 +43,7 @@ const DE_BRUJIN_SEQUENCE: [u8; 64] = [ ]; impl BitboardFns for Bitboard { - fn print(self, title: &str) -> () { + fn print(self, title: &str) { println!("\n {}", title); for rank in (0..8).rev() { print!("{}|", rank + 1); @@ -55,7 +55,7 @@ impl BitboardFns for Bitboard { } } } - return println!(" a b c d e f g h"); + println!(" a b c d e f g h"); } fn pop_count(mut self) -> u8 { @@ -64,7 +64,7 @@ impl BitboardFns for Bitboard { count += 1; self &= self - 1; } - return count; + count } diff --git a/src/board/io.rs b/src/board/io.rs index ca75c8c..67aa096 100644 --- a/src/board/io.rs +++ b/src/board/io.rs @@ -8,7 +8,7 @@ const PIECE_CHARS: [&str; 12] = [ /// Input/Output operations with Board pub trait IO { - fn print(&self) -> (); + fn print(&self); #[allow(non_snake_case)] fn from_FEN(fen: String) -> Self; diff --git a/src/board/mod.rs b/src/board/mod.rs index 579488b..aab3136 100644 --- a/src/board/mod.rs +++ b/src/board/mod.rs @@ -32,6 +32,13 @@ pub struct Board { attacks: Attacks, } +impl Default for Board { + fn default() -> Self { + Board::new() + } + +} + impl Board { pub fn new() -> Self { let default_fen = String::from("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); @@ -68,7 +75,7 @@ impl Board { .iter() .enumerate() .find(|(_, bitboard)| *bitboard & square_bb > 0) - .and_then(|(pt, _)| Some(Piece::from(pt))) + .map(|(pt, _)| Piece::from(pt)) } pub fn ep_bitboard(&self) -> Bitboard { @@ -143,7 +150,7 @@ impl Board { self.zobrist_toggle_piece(source_piece, mov.target); } } - Piece::from(source_piece) + source_piece }, None => { self.print(); @@ -290,22 +297,19 @@ impl Board { } // Return captured piece to target square - match captured_piece { - Some(target_piece) => { - match mov.kind { - // Return pawn captured by En Passant pawn if needed - MoveKind::EnPassant => { - let original_dead_pawn_bb = Square::from_coords(mov.source.rank(), mov.target.file()).to_bitboard(); - self.piece_sets[target_piece as usize] |= original_dead_pawn_bb; - self.occupancy |= original_dead_pawn_bb; - }, - _ => { - self.piece_sets[target_piece as usize] |= move_target_bb; - self.occupancy |= move_target_bb; - }, - } - }, - None => {} + if let Some(target_piece) = captured_piece { + match mov.kind { + // Return pawn captured by En Passant pawn if needed + MoveKind::EnPassant => { + let original_dead_pawn_bb = Square::from_coords(mov.source.rank(), mov.target.file()).to_bitboard(); + self.piece_sets[target_piece as usize] |= original_dead_pawn_bb; + self.occupancy |= original_dead_pawn_bb; + }, + _ => { + self.piece_sets[target_piece as usize] |= move_target_bb; + self.occupancy |= move_target_bb; + }, + } } @@ -381,16 +385,15 @@ mod tests { 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); - let initial_board = board.clone(); + let initial_board = board; board.print(); let black_move = Move { source: Square::F7, target: Square::F5, kind: MoveKind::Quiet }; println!("\n{:?}", black_move); - match board.make_move(black_move) { - Some(..) => panic!("No piece should be captured"), - None => {}, - }; + if let Some(..) = board.make_move(black_move) { + panic!("No piece should be captured"); + } board.print(); @@ -423,7 +426,7 @@ mod tests { fn unmake_move() { let fen = String::from("q1b2k2/5p1p/4p1pb/pPPp4/3N4/3nPB2/P2QKnR1/1R6 w - - 0 25"); let mut board = Board::from_FEN(fen); - let initial_board = board.clone(); + let initial_board = board; let mov = Move { source: Square::D2, target: Square::A5, kind: MoveKind::Capture }; @@ -442,9 +445,9 @@ mod tests { fn is_square_attacked() { let board = Board::new(); - assert_eq!(board.is_square_attacked(Square::E2, Color::White), true); - assert_eq!(board.is_square_attacked(Square::E2, Color::Black), false); - assert_eq!(board.is_square_attacked(Square::E4, Color::White), false); - assert_eq!(board.is_square_attacked(Square::B6, Color::Black), true); + assert!(board.is_square_attacked(Square::E2, Color::White)); + assert!(!board.is_square_attacked(Square::E2, Color::Black)); + assert!(!board.is_square_attacked(Square::E4, Color::White)); + assert!(board.is_square_attacked(Square::B6, Color::Black)); } } diff --git a/src/board/zobrist.rs b/src/board/zobrist.rs index 5286a73..88a2fb7 100644 --- a/src/board/zobrist.rs +++ b/src/board/zobrist.rs @@ -18,12 +18,12 @@ pub trait Zobrist { /// Compute store zobrist hash of the current position /// https://www.chessprogramming.org/Zobrist_Hashing - fn compute_hash(&mut self) -> (); + fn compute_hash(&mut self); - fn zobrist_toggle_piece(&mut self, piece_type: Piece, square: Square) -> (); - fn zobrist_toggle_castling_right(&mut self, color: Color, side: CastlingSide) -> (); - fn zobrist_toggle_ep_square(&mut self, ep_square: Square) -> (); - fn zobrist_toggle_color(&mut self) -> (); + fn zobrist_toggle_piece(&mut self, piece_type: Piece, square: Square); + fn zobrist_toggle_castling_right(&mut self, color: Color, side: CastlingSide); + fn zobrist_toggle_ep_square(&mut self, ep_square: Square); + fn zobrist_toggle_color(&mut self); } impl Zobrist for Board { @@ -32,7 +32,7 @@ impl Zobrist for Board { [(); ZOBRIST_SEED_SIZE].map(|_| rng.gen()) } - fn compute_hash(&mut self) -> () { + fn compute_hash(&mut self) { self.hash = 0; for piece_id in 0..self.piece_sets.len() { @@ -48,9 +48,8 @@ impl Zobrist for Board { } } - match self.ep_target { - Some(square) => self.zobrist_toggle_ep_square(square), - None => {}, + if let Some(square) = self.ep_target { + self.zobrist_toggle_ep_square(square); } if self.color() == Color::Black { @@ -58,19 +57,19 @@ impl Zobrist for Board { } } - fn zobrist_toggle_piece(&mut self, piece_type: Piece, square: Square) -> () { + fn zobrist_toggle_piece(&mut self, piece_type: Piece, square: Square) { self.hash ^= self.zobrist_seed[piece_type as usize * TOTAL_SQUARES + square as usize]; } - fn zobrist_toggle_castling_right(&mut self, color: Color, side: CastlingSide) -> () { + fn zobrist_toggle_castling_right(&mut self, color: Color, side: CastlingSide) { self.hash ^= self.zobrist_seed[(TOTAL_PIECES * TOTAL_SQUARES) + color as usize * 2 + side as usize]; } - fn zobrist_toggle_ep_square(&mut self, ep_square: Square) -> () { + fn zobrist_toggle_ep_square(&mut self, ep_square: Square) { self.hash ^= self.zobrist_seed[(TOTAL_PIECES * TOTAL_SQUARES + TOTAL_CASTLING_RIGHTS) + ep_square.file() as usize]; } - fn zobrist_toggle_color(&mut self) -> () { + fn zobrist_toggle_color(&mut self) { self.hash ^= self.zobrist_seed[ZOBRIST_SEED_SIZE - 1]; } } diff --git a/src/grossmeister/mod.rs b/src/grossmeister/mod.rs index b7c134d..6ed5f17 100644 --- a/src/grossmeister/mod.rs +++ b/src/grossmeister/mod.rs @@ -26,7 +26,7 @@ pub struct Grossmeister { impl Grossmeister { pub fn new(board: Board) -> Self { - return Self { + Self { board, attacks: Attacks::new(), transposition_table: vec![None; TTABLE_SIZE as usize], diff --git a/src/grossmeister/move_generation.rs b/src/grossmeister/move_generation.rs index 25d92c7..c3acc91 100644 --- a/src/grossmeister/move_generation.rs +++ b/src/grossmeister/move_generation.rs @@ -153,7 +153,7 @@ impl Grossmeister { } } } - return moves + moves } /// Evaluate move for move ordering, prioritizing efficient captures @@ -195,25 +195,20 @@ impl Grossmeister { let mut ordered_moves: Vec = moves_with_eval.iter().map(|(m, _)| *m).collect(); // Insert killer moves after winning captures - let equal_capture_index = match moves_with_eval.iter().position(|(m, eval)| m.is_tactical() && *eval == 0.0) { - Some(x) => x, - None => 0, - }; + let equal_capture_index = moves_with_eval + .iter() + .position(|(m, eval)| m.is_tactical() && *eval == 0.0) + .unwrap_or(0); for killer in killer_moves { - match ordered_moves.iter().position(|m| *m == killer) { - Some(index) => { + if let Some(index) = ordered_moves.iter().position(|m| *m == killer) { let mov = ordered_moves.remove(index); ordered_moves.insert(equal_capture_index, mov); - } - None => {} - }; - + } } - match self.transposition() { - Some(transposition) => ordered_moves.insert(0, transposition.mov), - None => {}, + if let Some(transposition) = self.transposition() { + ordered_moves.insert(0, transposition.mov); } ordered_moves diff --git a/src/grossmeister/search.rs b/src/grossmeister/search.rs index 57ce672..3efa9f8 100644 --- a/src/grossmeister/search.rs +++ b/src/grossmeister/search.rs @@ -21,30 +21,27 @@ impl Grossmeister { let mut killer_moves = Vec::new(); let color = self.board.color(); - match self.transposition() { - Some(transposition) => { - if transposition.depth == depth_left { - match transposition.node_type { - NodeType::PV => { // PV-nodes have exact score + if let Some(transposition) = self.transposition() { + if transposition.depth == depth_left { + match transposition.node_type { + NodeType::PV => { // PV-nodes have exact score + principal_variation.push(transposition.mov); + return (transposition.score, principal_variation); + } + NodeType::Cut => { + if transposition.score >= beta { principal_variation.push(transposition.mov); - return (transposition.score, principal_variation); - } - NodeType::Cut => { - if transposition.score >= beta { - principal_variation.push(transposition.mov); - return (beta, principal_variation); - } + return (beta, principal_variation); } - NodeType::All => { - if transposition.score <= alpha { - principal_variation.push(transposition.mov); - return (alpha, principal_variation); - } + } + NodeType::All => { + if transposition.score <= alpha { + principal_variation.push(transposition.mov); + return (alpha, principal_variation); } } } } - None => {}, } if depth_left == 0 { @@ -57,9 +54,9 @@ impl Grossmeister { let mut should_pv_search = true; let mut legal_move_found = false; for mov in moves { - let ep_target_before = self.board.ep_target.clone(); - let castling_rights_before = self.board.castling_rights.clone(); - let hash_before = self.board.hash.clone(); + let ep_target_before = self.board.ep_target; + let castling_rights_before = self.board.castling_rights; + let hash_before = self.board.hash; let captured_piece = self.board.make_move(mov); if !self.board.is_king_in_check(color) { @@ -135,10 +132,8 @@ impl Grossmeister { } } - if !legal_move_found { - if self.board.is_king_in_check(color) { - return (-VALUE_WIN, principal_variation); - } + if !legal_move_found && self.board.is_king_in_check(color) { + return (-VALUE_WIN, principal_variation); } (alpha, principal_variation) @@ -161,18 +156,14 @@ impl Grossmeister { } // If we are not in check, we can only search tactical moves - moves = moves - .iter() - .filter(|m| m.is_tactical()) - .map(|m| *m) - .collect() + moves.retain(|m| m.is_tactical()) } let mut legal_move_found = false; for mov in moves { - let ep_target_before = self.board.ep_target.clone(); - let castling_rights_before = self.board.castling_rights.clone(); - let hash_before = self.board.hash.clone(); + let ep_target_before = self.board.ep_target; + let castling_rights_before = self.board.castling_rights; + let hash_before = self.board.hash; let captured_piece = self.board.make_move(mov); if !self.board.is_king_in_check(color) { @@ -191,10 +182,8 @@ impl Grossmeister { } } - if !legal_move_found { - if self.board.is_king_in_check(color) { - return -VALUE_WIN - } + if !legal_move_found && self.board.is_king_in_check(color) { + return -VALUE_WIN } alpha @@ -252,7 +241,7 @@ impl Grossmeister { continue; } - if search_result.1.len() > 0 { + if !search_result.1.is_empty() { depth += 1; gradual_widening_counter = 0; alpha = search_result.0 - window_size; @@ -265,7 +254,7 @@ impl Grossmeister { } match result { - Some(r) => return r, + Some(r) => r, None => panic!("Could not find a move in time"), } } @@ -287,9 +276,9 @@ impl Grossmeister { } for mov in moves { - let ep_target_before = self.board.ep_target.clone(); - let castling_rights_before = self.board.castling_rights.clone(); - let hash_before = self.board.hash.clone(); + let ep_target_before = self.board.ep_target; + let castling_rights_before = self.board.castling_rights; + let hash_before = self.board.hash; let captured_piece = self.board.make_move(mov); // King can not be in check after our own move if !self.board.is_king_in_check(color) { diff --git a/src/main.rs b/src/main.rs index bb244ca..e7633bc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -43,9 +43,9 @@ fn computer_move(gm: &mut Grossmeister, time_left: &mut Duration) { // Ponder for some time println!("Pondering, assume opponent move from PV: {:?}", pv[1]); - let ep_target_before = gm.board.ep_target.clone(); - let castling_rights_before = gm.board.castling_rights.clone(); - let hash_before = gm.board.hash.clone(); + let ep_target_before = gm.board.ep_target; + let castling_rights_before = gm.board.castling_rights; + let hash_before = gm.board.hash; let captured_piece = gm.board.make_move(pv[1]); gm.iterative_deepening(max_depth, Duration::from_secs(3), false); gm.board.unmake_move(pv[1], captured_piece, ep_target_before, castling_rights_before, hash_before); diff --git a/src/moves.rs b/src/moves.rs index 858fe43..e27d74c 100644 --- a/src/moves.rs +++ b/src/moves.rs @@ -25,10 +25,6 @@ impl Move { /// Tactical move is a move that changes material score pub fn is_tactical(&self) -> bool { - match self.kind { - MoveKind::Capture => true, - MoveKind::EnPassant => true, - _ => false, - } + matches!(self.kind, MoveKind::Capture | MoveKind::EnPassant) } } -- cgit v1.2.3