Add move generation for castling

This commit is contained in:
2024-06-12 00:16:21 +03:00
parent 1f7cbbe577
commit a0959bf6b9
3 changed files with 165 additions and 6 deletions

View File

@@ -5,7 +5,7 @@ use crate::attack::{
get_bishop_attacks, get_king_attacks, get_knight_attacks, get_pawn_attacks, get_queen_attacks,
get_rook_attacks,
};
use crate::game::State;
use crate::game::{CastlingRights, State};
#[derive(Debug, PartialEq, Eq)]
pub struct Board {
@@ -128,7 +128,82 @@ impl Board {
Kind::Bishop => bishop_pseudo_moves(pieces, all_occupancies, own_occupancies),
Kind::Rook => rook_pseudo_moves(pieces, all_occupancies, own_occupancies),
Kind::Queen => queen_pseudo_moves(pieces, all_occupancies, own_occupancies),
Kind::King => king_pseudo_moves(pieces, own_occupancies),
Kind::King => king_pseudo_moves(
pieces,
all_occupancies,
own_occupancies,
self.castling_ability(color),
color,
),
}
}
fn castling_ability(&self, color: Color) -> CastlingRights {
match (
self.castling_from_fen(color),
self.castling_pseudo_safety(color),
) {
(CastlingRights::Both, _) => self.castling_pseudo_safety(color),
(CastlingRights::Short, CastlingRights::Short) => CastlingRights::Short,
(CastlingRights::Long, CastlingRights::Long) => CastlingRights::Long,
_ => CastlingRights::None,
}
}
const fn castling_from_fen(&self, color: Color) -> CastlingRights {
let castling_fen = self.state.get_castling_ability();
let black_king_and_queen = (castling_fen >> 2) & 0b11 == 0b11;
let black_king = (castling_fen >> 3) & 1 == 1;
let black_queen = (castling_fen >> 2) & 1 == 1;
let white_king_and_queen = castling_fen & 0b11 == 0b11;
let white_king = (castling_fen >> 1) & 1 == 1;
let white_queen = castling_fen & 1 == 1;
match color {
Color::White => match (white_king_and_queen, white_king, white_queen) {
(true, _, _) => CastlingRights::Both,
(_, true, _) => CastlingRights::Short,
(_, _, true) => CastlingRights::Long,
_ => CastlingRights::None,
},
Color::Black => match (black_king_and_queen, black_king, black_queen) {
(true, _, _) => CastlingRights::Both,
(_, true, _) => CastlingRights::Short,
(_, _, true) => CastlingRights::Long,
_ => CastlingRights::None,
},
}
}
fn castling_pseudo_safety(&self, color: Color) -> CastlingRights {
match color {
Color::White => {
if self.is_attacked(4, Color::Black) {
return CastlingRights::None;
}
let d1_attacked = self.is_attacked(3, Color::Black);
let f1_attacked = self.is_attacked(5, Color::Black);
match (d1_attacked, f1_attacked) {
(true, true) => CastlingRights::None,
(true, false) => CastlingRights::Short,
(false, true) => CastlingRights::Long,
(false, false) => CastlingRights::Both,
}
}
Color::Black => {
if self.is_attacked(60, Color::White) {
return CastlingRights::None;
}
let d8_attacked = self.is_attacked(59, Color::White);
let f8_attacked = self.is_attacked(61, Color::White);
match (d8_attacked, f8_attacked) {
(true, true) => CastlingRights::None,
(true, false) => CastlingRights::Short,
(false, true) => CastlingRights::Long,
(false, false) => CastlingRights::Both,
}
}
}
}
}