use crate::game::{Board, Cell}; use crate::player::Player; pub struct Engine { players: Vec>, turn: usize, board: Board, x: usize, } impl Engine { pub fn new(p1: Box, p2: Box) -> Engine { let board = Board::new(); Engine { players: vec![p1, p2], turn: 0, board: board, x: 0, } } pub fn run(&mut self) -> Result<(), Box> { loop { // setup new game for players self.players[self.x].start_new_game(Cell::X)?; self.players[(self.x + 1) % 2].start_new_game(Cell::O)?; // reset board self.board.reset(); self.turn = self.x; // run game self.run_single_game()?; // switch sides self.x = (self.x + 1) % 2; } } fn run_single_game(&mut self) -> Result<(), Box> { loop { // request move from player, fail if there is error let m = self.players[self.turn].request_move(&self.board)?; let next = (self.turn + 1) % 2; if !self.board.is_valid_move(&m) { continue; } // apply move self.board.apply(m)?; // check if there is a winner if let Some(_winner) = self.board.has_winner() { self.players[self.turn].message("You win!")?; self.players[next].message("You loose!")?; break; } if !self.board.valid_moves_available() { self.players[self.turn].message("It's a draw!")?; self.players[next].message("It's a draw!")?; break; } self.turn = next } Ok(()) } }