diff --git a/position/src/move_generator/king.rs b/position/src/move_generator/king.rs index 1f35af5..bd65151 100644 --- a/position/src/move_generator/king.rs +++ b/position/src/move_generator/king.rs @@ -44,12 +44,17 @@ impl MoveGeneratorInternal for KingMoveGenerator { let color = piece.color(); let square = placed_piece.square(); - let empty_squares = position.empty_squares(); - let opposing_pieces = position.bitboard_for_color(color.other()); + let safe_squares = !position.king_danger(); + let all_king_moves = BitBoard::king_moves(square); - let all_moves = BitBoard::king_moves(square); - let quiet_moves_bb = all_moves & empty_squares; - let capture_moves_bb = all_moves & opposing_pieces; + let empty_squares = position.empty_squares(); + let safe_empty_squares = empty_squares & safe_squares; + + let opposing_pieces = position.bitboard_for_color(color.other()); + let opposing_pieces_on_safe_squares = opposing_pieces & safe_squares; + + let quiet_moves = all_king_moves & safe_empty_squares; + let capture_moves = all_king_moves & opposing_pieces_on_safe_squares; // TODO: Handle checks. Prevent moving a king to a square attacked by a // piece of the opposite color. @@ -66,15 +71,15 @@ impl MoveGeneratorInternal for KingMoveGenerator { let capture_moves = capture_moves_bb.occupied_squares().map(map_to_move); MoveSet::new(placed_piece) - .quiet_moves(quiet_moves_bb, quiet_moves) - .capture_moves(capture_moves_bb, capture_moves) + .quiet_moves(quiet_moves) + .capture_moves(capture_moves) } } #[cfg(test)] mod tests { use super::*; - use crate::{position, r#move::AlgebraicMoveFormatter, PositionBuilder}; + use crate::{assert_move_list, position, r#move::AlgebraicMoveFormatter, PositionBuilder}; use chessfriend_bitboard::bitboard; use chessfriend_core::{piece, Square}; use std::collections::HashSet; @@ -90,7 +95,7 @@ mod tests { bitboard![E5, F5, F4, F3, E3, D3, D4, D5] ); - let expected_moves = [ + let expected_moves: HashSet = HashSet::from_iter([ MoveBuilder::new(piece!(White King), Square::E4, Square::D5).build(), MoveBuilder::new(piece!(White King), Square::E4, Square::E5).build(), MoveBuilder::new(piece!(White King), Square::E4, Square::F5).build(), @@ -99,23 +104,11 @@ mod tests { MoveBuilder::new(piece!(White King), Square::E4, Square::E3).build(), MoveBuilder::new(piece!(White King), Square::E4, Square::D3).build(), MoveBuilder::new(piece!(White King), Square::E4, Square::D4).build(), - ]; + ]); - let mut generated_moves: HashSet = generator.iter().cloned().collect(); + let generated_moves: HashSet = generator.iter().collect(); - for ex_move in expected_moves { - assert!( - generated_moves.remove(&ex_move), - "{:#?} was not generated", - &ex_move - ); - } - - assert!( - generated_moves.is_empty(), - "Moves unexpectedly present: {:#?}", - generated_moves - ); + assert_move_list!(generated_moves, expected_moves, pos); } #[test] @@ -138,7 +131,7 @@ mod tests { MoveBuilder::new(piece!(White King), Square::A1, Square::B2).build(), ]; - let mut generated_moves: HashSet = generator.iter().cloned().collect(); + let mut generated_moves: HashSet = generator.iter().collect(); for ex_move in expected_moves { assert!( @@ -167,27 +160,10 @@ mod tests { assert!(pos.is_king_in_check()); let generator = KingMoveGenerator::new(&pos, Color::Black); - let generated_moves: HashSet = generator.iter().cloned().collect(); + let generated_moves = generator.bitboard(); - let king = piece!(Black King); - let from_square = Square::E7; - let expected_moves = HashSet::from_iter([ - MoveBuilder::new(king, from_square, Square::D6).build(), - MoveBuilder::new(king, from_square, Square::D7).build(), - MoveBuilder::new(king, from_square, Square::D8).build(), - MoveBuilder::new(king, from_square, Square::F6).build(), - MoveBuilder::new(king, from_square, Square::F7).build(), - MoveBuilder::new(king, from_square, Square::F8).build(), - ]); + let expected_moves = bitboard![F8, F7, F6, D6, D7, D8]; - assert_eq!( - generated_moves, - expected_moves, - "Difference: {:?}", - generated_moves - .symmetric_difference(&expected_moves) - .map(|mv| format!("{}", AlgebraicMoveFormatter::new(mv, &pos))) - .collect::>() - ); + assert_eq!(generated_moves, expected_moves); } } diff --git a/position/src/move_generator/pawn.rs b/position/src/move_generator/pawn.rs index 8b9b4cf..401366e 100644 --- a/position/src/move_generator/pawn.rs +++ b/position/src/move_generator/pawn.rs @@ -1,7 +1,7 @@ // Eryn Wells use super::{move_generator_declaration, MoveGeneratorInternal, MoveSet}; -use crate::{MoveBuilder, Position}; +use crate::Position; use chessfriend_bitboard::BitBoard; use chessfriend_core::{Color, Piece, PlacedPiece, Rank, Square}; @@ -16,24 +16,12 @@ impl MoveGeneratorInternal for PawnMoveGenerator { } fn move_set_for_piece(position: &Position, placed_piece: PlacedPiece) -> MoveSet { - let from_square = placed_piece.square(); - - let captures_bitboard = Self::attacks(position, placed_piece); - let quiet_moves_bitboard = Self::pushes(position, placed_piece); - - let quiet_moves = quiet_moves_bitboard.occupied_squares().map(|to_square| { - MoveBuilder::new(*placed_piece.piece(), from_square, to_square).build() - }); - let capture_moves = captures_bitboard.occupied_squares().map(|to_square| { - let captured_piece = position.piece_on_square(to_square).unwrap(); - MoveBuilder::new(*placed_piece.piece(), from_square, to_square) - .capturing(captured_piece) - .build() - }); + let capture_moves = Self::attacks(position, placed_piece); + let quiet_moves = Self::pushes(position, placed_piece); MoveSet::new(placed_piece) - .quiet_moves(quiet_moves_bitboard, quiet_moves) - .capture_moves(captures_bitboard, capture_moves) + .quiet_moves(quiet_moves) + .capture_moves(capture_moves) } } @@ -71,7 +59,10 @@ impl PawnMoveGenerator { #[cfg(test)] mod tests { use super::*; - use crate::{position::DiagramFormatter, test_position, Move}; + use crate::{ + assert_move_list, position::DiagramFormatter, r#move::AlgebraicMoveFormatter, + test_position, Move, MoveBuilder, + }; use chessfriend_core::{piece, Square}; use std::collections::HashSet; @@ -86,7 +77,7 @@ mod tests { MoveBuilder::new(piece!(White Pawn), Square::E2, Square::E4).build(), ]); - let generated_moves: HashSet = generator.iter().cloned().collect(); + let generated_moves: HashSet = generator.iter().collect(); assert_eq!(generated_moves, expected_moves); } @@ -104,9 +95,9 @@ mod tests { ) .build()]); - let generated_moves: HashSet = generator.iter().cloned().collect(); + let generated_moves: HashSet = generator.iter().collect(); - assert_eq!(generated_moves, expected_moves); + assert_move_list!(generated_moves, expected_moves, pos); } #[test] @@ -127,9 +118,9 @@ mod tests { ) .build()]); - let generated_moves: HashSet = generator.iter().cloned().collect(); + let generated_moves: HashSet = generator.iter().collect(); - assert_eq!(generated_moves, expected_moves); + assert_move_list!(generated_moves, expected_moves, pos); } #[test] @@ -141,9 +132,10 @@ mod tests { let generator = PawnMoveGenerator::new(&pos, Color::White); - let generated_moves: HashSet = generator.iter().cloned().collect(); + let generated_moves: HashSet = generator.iter().collect(); + let expected_moves: HashSet = HashSet::new(); - assert_eq!(generated_moves, HashSet::new()); + assert_move_list!(generated_moves, expected_moves, pos); } #[test] @@ -163,7 +155,7 @@ mod tests { .build()], ); - let generated_moves: HashSet = generator.iter().cloned().collect(); + let generated_moves: HashSet = generator.iter().collect(); assert_eq!(generated_moves, expected_moves); } @@ -188,7 +180,7 @@ mod tests { .build(), ]); - let generated_moves: HashSet = generator.iter().cloned().collect(); + let generated_moves: HashSet = generator.iter().collect(); assert_eq!( generated_moves, expected_moves,