Files
rttt/engine/engine.rs
2026-01-04 17:45:57 +03:00

72 lines
1.8 KiB
Rust

use crate::game::{Board, Cell};
use crate::player::Player;
pub struct Engine {
players: Vec<Box<dyn Player>>,
turn: usize,
board: Board,
x: usize,
}
impl Engine {
pub fn new(p1: Box<dyn Player>, p2: Box<dyn Player>) -> Engine {
let board = Board::new();
Engine {
players: vec![p1, p2],
turn: 0,
board: board,
x: 0,
}
}
pub fn run(&mut self) -> Result<(), Box<dyn std::error::Error>> {
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<dyn std::error::Error>> {
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(())
}
}