Move make/unmake and History on Game

This commit is contained in:
stefiosif
2024-09-15 18:38:32 +03:00
parent 3383435af7
commit f128b35252
8 changed files with 172 additions and 159 deletions

View File

@@ -1,7 +1,16 @@
use crate::board::fen::from_fen;
use crate::{
board::fen::from_fen,
movegen::r#move::{Move, MoveType},
};
use String as FenError;
use super::board::{Board, Color};
use super::{
bitboard::square_to_bitboard,
board::{Board, Color, PieceType},
history::{History, MoveParameters},
square::Square,
state::Castle,
};
impl PartialEq for Game {
fn eq(&self, other: &Self) -> bool {
@@ -14,12 +23,14 @@ impl PartialEq for Game {
#[derive(Debug, Eq)]
pub struct Game {
pub board: Board,
pub history: History,
}
impl Game {
pub const fn new() -> Self {
Self {
board: Board::new(),
history: History::new(),
}
}
@@ -30,6 +41,118 @@ impl Game {
pub const fn current_player(&self) -> Color {
self.board.state.current_player()
}
pub fn make_move(&mut self, mv: &Move) {
let board = &mut self.board;
let color = board.state.current_player();
let pawn_move = board.is_pawn_move(mv.src);
let mut en_passant_square = None;
self.history
.push_move_parameters(MoveParameters::build(board, mv));
match &mv.move_type {
MoveType::Quiet => {
board.move_piece(mv.src, mv.dst);
}
MoveType::Capture => {
board.move_piece(mv.src, mv.dst);
board.remove_opponent_piece(mv.dst);
}
MoveType::EnPassant => {
board.move_piece(mv.src, mv.dst);
board.remove_pawn_enpassant(mv.dst, color);
}
MoveType::DoublePush => {
board.move_piece(mv.src, mv.dst);
en_passant_square = match color {
Color::White => Some(mv.src + 8),
Color::Black => Some(mv.src.saturating_sub(8)),
};
}
MoveType::Promotion(promote) => {
board.remove_own_piece(mv.src);
board.promote_piece(mv.dst, promote);
}
MoveType::PromotionCapture(promote) => {
board.remove_own_piece(mv.src);
board.remove_opponent_piece(mv.dst);
board.promote_piece(mv.dst, promote);
}
MoveType::Castle => {
board.move_piece(mv.src, mv.dst);
board.move_rook_castle(mv.dst);
board.state.set_castling_ability(color, Castle::None);
}
}
Board::update_game_state(&mut board.state, mv, color, pawn_move, en_passant_square);
}
pub fn unmake_move(&mut self) {
let board = &mut self.board;
let move_parameters =
std::mem::take(&mut self.history.pop_move_parameters()).unwrap_or_default();
let color_before_move = board.state.change_side();
board.state.revert_full_move(color_before_move);
board.state.en_passant_square = move_parameters.en_passant_square;
if let Some(new_castling_ability) = move_parameters.castling_ability {
board.state.castling_ability = new_castling_ability;
}
if let Some(new_halfmove_clock) = move_parameters.halfmove_clock {
board.state.halfmove_clock = new_halfmove_clock;
}
let mv = move_parameters.mv.unwrap();
match &mv.move_type {
MoveType::Quiet | MoveType::DoublePush => {
board.move_piece(mv.dst, mv.src);
}
MoveType::Capture | MoveType::Promotion(_) | MoveType::PromotionCapture(_) => {
if let (Some(captured_piece_type), Some(promoted_piece_type)) = (
move_parameters.captured_piece,
move_parameters.promoted_piece,
) {
let (own_pieces, opponent_pieces) = board.all_pieces();
opponent_pieces[captured_piece_type].bitboard |= square_to_bitboard(mv.dst);
own_pieces[promoted_piece_type].bitboard &= !square_to_bitboard(mv.dst);
own_pieces[PieceType::Pawn].bitboard |= square_to_bitboard(mv.src);
} else if let Some(captured_piece_type) = move_parameters.captured_piece {
board.move_piece(mv.dst, mv.src);
let opponent_pieces = board.opponent_pieces();
opponent_pieces[captured_piece_type].bitboard |= square_to_bitboard(mv.dst);
} else if let Some(promoted_piece_type) = move_parameters.promoted_piece {
let own_pieces = board.own_pieces();
own_pieces[promoted_piece_type].bitboard &= !square_to_bitboard(mv.dst);
own_pieces[PieceType::Pawn].bitboard |= square_to_bitboard(mv.src);
}
}
MoveType::EnPassant => {
board.move_piece(mv.dst, mv.src);
let enemy_pawn_square = match color_before_move {
Color::White => mv.dst - 8,
Color::Black => mv.dst + 8,
};
let opponent_pieces = board.opponent_pieces();
opponent_pieces[PieceType::Pawn].bitboard |= square_to_bitboard(enemy_pawn_square);
}
MoveType::Castle => {
board.move_piece(mv.dst, mv.src);
let (rook_src, rook_dst) = match mv.dst {
Square::C1 | Square::C8 => (mv.dst - 2, mv.dst + 1),
Square::G1 | Square::G8 => (mv.dst + 1, mv.dst - 1),
_ => return,
};
let own_pieces = board.own_pieces();
own_pieces[PieceType::Rook].bitboard &= !square_to_bitboard(rook_dst);
own_pieces[PieceType::Rook].bitboard |= square_to_bitboard(rook_src);
}
}
}
}
impl Default for Game {