Add move generation for castling
This commit is contained in:
79
src/board.rs
79
src/board.rs
@@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user