use crate::game::{Board, Cell}; use crate::player::{Player, PlayerConsole}; pub struct Engine { players: Vec>, turn: usize, board: Board, x: usize, } impl Engine { pub fn new() -> Engine { // TODO: accept players as args let p1 = PlayerConsole::new("Gopher"); let p2 = PlayerConsole::new("Rustacean"); let board = Board::new(); Engine { players: vec![Box::new(p1), Box::new(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 { println!("{}", self.board); // request move from player, fail if there is error let m = self.players[self.turn].request_move(&self.board)?; if !self.board.is_valid_move(&m) { println!("invalid move"); continue; } // apply move self.board.apply(m)?; // check if there is a winner if let Some(_winner) = self.board.has_winner() { println!("{} wins!", self.players[self.turn].name()); println!("{}", self.board); break; } if !self.board.valid_moves_available() { println!("It's a draw!"); println!("{}", self.board); break; } self.turn = (self.turn + 1) % 2 } Ok(()) } }