From 25b1164644a0e17fc745f94b994dc098e9c5265b Mon Sep 17 00:00:00 2001 From: dece Date: Sat, 6 Jun 2020 01:27:19 +0200 Subject: [PATCH] rules: fix castling issue --- src/rules.rs | 47 ++++++++++++++++++++--------------------------- 1 file changed, 20 insertions(+), 27 deletions(-) diff --git a/src/rules.rs b/src/rules.rs index a7b04ac..333618e 100644 --- a/src/rules.rs +++ b/src/rules.rs @@ -39,8 +39,7 @@ pub const CASTLING_BL_MASK: u8 = 0b00001100; pub const CASTLING_K_MASK: u8 = 0b00000101; pub const CASTLING_Q_MASK: u8 = 0b00001010; pub const CASTLING_MASK: u8 = 0b00001111; -pub const CASTLING_SIDES: [(std::ops::RangeInclusive, u8); 2] = - [(5..=6, CASTLING_K_MASK), (2..=3, CASTLING_Q_MASK)]; +pub const CASTLING_SIDES: [(i8, u8); 2] = [(5i8, CASTLING_K_MASK), (3i8, CASTLING_Q_MASK)]; pub const START_WH_K_POS: Pos = pos("e1"); pub const START_BL_K_POS: Pos = pos("e8"); @@ -404,27 +403,19 @@ fn get_king_moves( (7, CASTLING_BL_MASK) }; - // Check for castling if the king is on its castling rank (R1) and is not in check (R4). + // Check for castling if the king is on its castling rank (R1) + // and is not in check (R4) if - *r == castling_rank && // Part of R1 for the king. - !is_attacked(board, game_state, at) // R4 + *r == castling_rank && + !is_attacked(board, game_state, at) { // Check for both castling sides. - for (path, castling_side_mask) in CASTLING_SIDES.iter() { + for (through_f, castling_side_mask) in CASTLING_SIDES.iter() { // Check for castling availability for this color and side. - if ((game_state.castling & castling_color_mask) | castling_side_mask) != 0 { + if (game_state.castling & castling_color_mask & castling_side_mask) != 0 { // R3, R5, R6: check that files on the way are empty and not attacked. - let mut clear_path = true; - for through_f in path.to_owned() { - let p = (through_f, castling_rank); - if !is_empty(board, &p) || is_illegal(board, game_state, &(*at, p, None)) { - clear_path = false; - break; - } - } - - // If the path is clear, the castling can be done. - if clear_path { + let p = (*through_f, castling_rank); + if is_empty(board, &p) && !is_illegal(board, game_state, &(*at, p, None)) { let castle = CASTLING_K_MASK & castling_color_mask; let m = get_castle_move(castle); if can_register(commit, board, game_state, &m) { @@ -512,10 +503,10 @@ mod tests { #[test] fn test_get_castle() { - assert_eq!(get_castle(&parse_move("e1a1")), Some(CASTLING_WH_Q)); - assert_eq!(get_castle(&parse_move("e1h1")), Some(CASTLING_WH_K)); - assert_eq!(get_castle(&parse_move("e8a8")), Some(CASTLING_BL_Q)); - assert_eq!(get_castle(&parse_move("e8h8")), Some(CASTLING_BL_K)); + assert_eq!(get_castle(&parse_move("e1c1")), Some(CASTLING_WH_Q)); + assert_eq!(get_castle(&parse_move("e1g1")), Some(CASTLING_WH_K)); + assert_eq!(get_castle(&parse_move("e8c8")), Some(CASTLING_BL_Q)); + assert_eq!(get_castle(&parse_move("e8g8")), Some(CASTLING_BL_K)); assert_eq!(get_castle(&parse_move("d2d4")), None); } @@ -555,14 +546,14 @@ mod tests { clear_square(&mut b, &pos("f8")); clear_square(&mut b, &pos("g8")); // White queen-side castling. - apply_move_to(&mut b, &mut gs, &parse_move("e1a1")); + apply_move_to(&mut b, &mut gs, &parse_move("e1c1")); assert!(is_piece(get_square(&b, &pos("c1")), SQ_WH_K)); assert!(is_piece(get_square(&b, &pos("d1")), SQ_WH_R)); assert!(is_empty(&b, &pos("a1"))); assert!(is_empty(&b, &pos("e1"))); assert_eq!(gs.castling, CASTLING_BL_MASK); // Black king-side castling. - apply_move_to(&mut b, &mut gs, &parse_move("e8h8")); + apply_move_to(&mut b, &mut gs, &parse_move("e8g8")); assert!(is_piece(get_square(&b, &pos("g8")), SQ_BL_K)); assert!(is_piece(get_square(&b, &pos("f8")), SQ_BL_R)); assert!(is_empty(&b, &pos("h8"))); @@ -713,7 +704,6 @@ mod tests { #[test] fn test_get_king_moves() { let mut gs = GameState::new(); - return; // FIXME // King can move 1 square in any direction. let mut b = new_empty(); @@ -740,14 +730,17 @@ mod tests { #[test] fn test_filter_illegal_moves() { let mut b = new_empty(); - let gs = GameState::new(); + let mut gs = GameState::new(); // Place white's king on first rank. set_square(&mut b, &pos("e1"), SQ_WH_K); // Place black rook in second rank: king can only move left or right. set_square(&mut b, &pos("h2"), SQ_BL_R); + // No castling available. + gs.castling = 0; + // 5 moves in absolute but only 2 are legal. let all_wh_moves = get_piece_moves(&b, &pos("e1"), &gs, true); - assert_eq!(all_wh_moves.len(), 2); // 5 moves in absolute but only 2 are legal. + assert_eq!(all_wh_moves.len(), 2); } #[test]