rules: fix castling issue
This commit is contained in:
parent
659094b269
commit
25b1164644
47
src/rules.rs
47
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<i8>, 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]
|
||||
|
|
Reference in a new issue