diff --git a/src/app.rs b/src/app.rs index 1489571..93b88a7 100644 --- a/src/app.rs +++ b/src/app.rs @@ -117,7 +117,7 @@ impl App { // if the selected Color is Black, we need to switch the Game if let Some(color) = self.selected_color { if color == PieceColor::Black { - self.game.is_bot_starting = true; + self.game.bot.is_bot_starting = true; self.game.bot_move(); self.game.player_turn = PieceColor::Black; } @@ -125,14 +125,14 @@ impl App { } pub fn restart(&mut self) { - let is_bot_starting = self.game.is_bot_starting; - let engine = self.game.engine.clone(); + let is_bot_starting = self.game.bot.is_bot_starting; + let engine = self.game.bot.engine.clone(); let game_is_against_bot = self.game.is_game_against_bot; self.game = Game::default(); - self.game.engine = engine; + self.game.bot.engine = engine; self.game.is_game_against_bot = game_is_against_bot; if is_bot_starting { - self.game.is_bot_starting = true; + self.game.bot.is_bot_starting = true; self.game.bot_move(); self.game.player_turn = PieceColor::Black; } diff --git a/src/game/bot.rs b/src/game/bot.rs new file mode 100644 index 0000000..908762f --- /dev/null +++ b/src/game/bot.rs @@ -0,0 +1,30 @@ +use uci::Engine; + +pub struct Bot { + // the chess engine + pub engine: Option, + /// Used to indicate if a bot move is following + pub bot_will_move: bool, + // if the bot is starting, meaning the player is black + pub is_bot_starting: bool, +} + +impl Default for Bot { + fn default() -> Self { + Self { + engine: None, + bot_will_move: false, + is_bot_starting: false, + } + } +} + +impl Bot { + pub fn clone(&self) -> Self { + Self { + engine: self.engine.clone(), + bot_will_move: self.bot_will_move, + is_bot_starting: self.is_bot_starting, + } + } +} diff --git a/src/game/game.rs b/src/game/game.rs index 2f16a50..cca7fb5 100644 --- a/src/game/game.rs +++ b/src/game/game.rs @@ -1,4 +1,4 @@ -use super::{coord::Coord, game_board::GameBoard, ui::UI}; +use super::{bot::Bot, coord::Coord, game_board::GameBoard, ui::UI}; use crate::{ constants::DisplayMode, pieces::{PieceColor, PieceMove, PieceType}, @@ -11,6 +11,12 @@ pub struct Game { pub game_board: GameBoard, // The struct to handle UI related stuff pub ui: UI, + // if the game is against a bot + pub is_game_against_bot: bool, + // The bot + pub bot: Bot, + // the display mode + pub display_mode: DisplayMode, // the player turn pub player_turn: PieceColor, // if the game is a draw @@ -19,16 +25,6 @@ pub struct Game { pub is_checkmate: bool, // if we are doing a promotion pub is_promotion: bool, - // the chess engine - pub engine: Option, - // if the game is against a bot - pub is_game_against_bot: bool, - // the display mode - pub display_mode: DisplayMode, - /// Used to indicate if a bot move is following - pub bot_will_move: bool, - // if the bot is starting, meaning the player is black - pub is_bot_starting: bool, } impl Default for Game { @@ -36,15 +32,13 @@ impl Default for Game { Self { game_board: GameBoard::default(), ui: UI::default(), + is_game_against_bot: false, + bot: Bot::default(), + display_mode: DisplayMode::DEFAULT, player_turn: PieceColor::White, is_draw: false, is_checkmate: false, is_promotion: false, - engine: None, - is_game_against_bot: false, - display_mode: DisplayMode::DEFAULT, - bot_will_move: false, - is_bot_starting: false, } } } @@ -54,15 +48,13 @@ impl Game { Self { game_board, ui: UI::default(), + is_game_against_bot: false, + bot: Bot::default(), + display_mode: DisplayMode::DEFAULT, player_turn, is_draw: false, is_checkmate: false, is_promotion: false, - engine: None, - is_game_against_bot: false, - display_mode: DisplayMode::DEFAULT, - bot_will_move: false, - is_bot_starting: false, } } @@ -72,15 +64,13 @@ impl Game { Self { game_board: self.game_board.clone(), ui: self.ui.clone(), + is_game_against_bot: self.is_game_against_bot, + bot: self.bot.clone(), + display_mode: self.display_mode, player_turn: self.player_turn, is_draw: self.is_draw, is_checkmate: self.is_checkmate, is_promotion: self.is_promotion, - engine: self.engine.clone(), - is_game_against_bot: self.is_game_against_bot, - display_mode: self.display_mode, - bot_will_move: self.bot_will_move, - is_bot_starting: self.is_bot_starting, } } @@ -96,7 +86,7 @@ impl Game { pub fn set_engine(&mut self, engine_path: &str) { self.is_game_against_bot = true; - self.engine = match Engine::new(engine_path) { + self.bot.engine = match Engine::new(engine_path) { Ok(engine) => Some(engine), _ => panic!("An error occcured with the selected chess engine path: {engine_path} Make sure you specified the right path using chess-tui -e"), } @@ -146,7 +136,7 @@ impl Game { self.ui.unselect_cell(); self.switch_player_turn(); self.is_draw = self.game_board.is_draw(self.player_turn); - if (!self.is_game_against_bot || self.is_bot_starting) + if (!self.is_game_against_bot || self.bot.is_bot_starting) && (!self.game_board.is_latest_move_promotion() || self.game_board.is_draw(self.player_turn) || self.game_board.is_checkmate(self.player_turn)) @@ -161,7 +151,7 @@ impl Game { self.is_checkmate = self.game_board.is_checkmate(self.player_turn); self.is_promotion = self.game_board.is_latest_move_promotion(); if !self.is_checkmate { - self.bot_will_move = true; + self.bot.bot_will_move = true; } } } @@ -200,10 +190,10 @@ impl Game { We use the UCI protocol to communicate with the chess engine */ pub fn bot_move(&mut self) { - let engine = self.engine.clone().expect("Missing the chess engine"); + let engine = self.bot.engine.clone().expect("Missing the chess engine"); let fen_position = self .game_board - .fen_position(self.is_bot_starting, self.player_turn); + .fen_position(self.bot.is_bot_starting, self.player_turn); engine.set_position(&(fen_position as String)).unwrap(); let best_move = engine.bestmove(); @@ -237,7 +227,7 @@ impl Game { self.game_board.board[to_y as usize][to_x as usize] = Some((promotion_piece.unwrap(), self.player_turn)); } - if self.is_bot_starting { + if self.bot.is_bot_starting { self.game_board.flip_the_board(); } } diff --git a/src/game/mod.rs b/src/game/mod.rs index fe540ac..67aa5d8 100644 --- a/src/game/mod.rs +++ b/src/game/mod.rs @@ -1,4 +1,5 @@ pub mod board; +pub mod bot; pub mod coord; pub mod game; pub mod game_board; diff --git a/src/game/ui.rs b/src/game/ui.rs index 7ed5579..b073e92 100644 --- a/src/game/ui.rs +++ b/src/game/ui.rs @@ -386,7 +386,7 @@ impl UI { let mut last_move_to = Coord::undefined(); if !game.game_board.move_history.is_empty() { last_move = game.game_board.move_history.last(); - if game.is_game_against_bot && !game.is_bot_starting { + if game.is_game_against_bot && !game.bot.is_bot_starting { last_move_from = last_move.map(|m| m.from).unwrap(); last_move_to = last_move.map(|m| m.to).unwrap(); } else { diff --git a/src/handler.rs b/src/handler.rs index 600e0ec..218b347 100644 --- a/src/handler.rs +++ b/src/handler.rs @@ -127,7 +127,7 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> { app.selected_color = None; if app.game.is_game_against_bot { app.game.is_game_against_bot = false; - app.game.is_bot_starting = false; + app.game.bot.is_bot_starting = false; } app.go_to_home(); app.game.game_board.reset(); diff --git a/src/main.rs b/src/main.rs index 1b5f0ff..03b995f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -77,10 +77,10 @@ fn main() -> AppResult<()> { Event::Mouse(mouse_event) => handle_mouse_events(mouse_event, &mut app)?, Event::Resize(_, _) => {} } - if app.game.bot_will_move { + if app.game.bot.bot_will_move { app.game.bot_move(); app.game.switch_player_turn(); - app.game.bot_will_move = false; + app.game.bot.bot_will_move = false; // need to be centralised app.game.is_checkmate = app.game.game_board.is_checkmate(app.game.player_turn); app.game.is_draw = app.game.game_board.is_draw(app.game.player_turn); diff --git a/src/ui/main_ui.rs b/src/ui/main_ui.rs index a310dbc..6789ba1 100644 --- a/src/ui/main_ui.rs +++ b/src/ui/main_ui.rs @@ -25,7 +25,7 @@ pub fn render(app: &mut App, frame: &mut Frame) { if app.current_page == Pages::Solo { render_game_ui(frame, app, main_area); } else if app.current_page == Pages::Bot { - if app.game.engine.is_none() { + if app.game.bot.engine.is_none() { match &app.chess_engine_path { Some(path) => { app.game.set_engine(path); diff --git a/tests/fen.rs b/tests/fen.rs index 264f533..63babe3 100644 --- a/tests/fen.rs +++ b/tests/fen.rs @@ -43,7 +43,7 @@ mod tests { // Move the king to replicate a third time the same position assert_eq!( game.game_board - .fen_position(game.is_bot_starting, game.player_turn), + .fen_position(game.bot.is_bot_starting, game.player_turn), "2k4R/8/4K3/8/8/8/8/8 b - - 0 0" ); } @@ -106,7 +106,7 @@ mod tests { // Move the king to replicate a third time the same position assert_eq!( game.game_board - .fen_position(game.is_bot_starting, game.player_turn), + .fen_position(game.bot.is_bot_starting, game.player_turn), "2k4R/8/4K3/8/2P5/8/8/8 b - c3 0 0" ); } @@ -166,7 +166,7 @@ mod tests { // Move the king to replicate a third time the same position assert_eq!( game.game_board - .fen_position(game.is_bot_starting, game.player_turn), + .fen_position(game.bot.is_bot_starting, game.player_turn), "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR b kq - 0 0" ); }