use crate::{board::Board, piece::Piece}; use rand::prelude::*; use std::io; use std::io::prelude::*; pub trait Agent { fn next_move(&mut self, board: &Board) -> Option<(usize, usize)>; fn name(&self) -> &'static str; fn color(&self) -> Piece; } pub struct ManualAgent { color: Piece, } impl Agent for ManualAgent { fn next_move(&mut self, _: &Board) -> Option<(usize, usize)> { let stdin = io::stdin(); let mut input = String::new(); loop { input.clear(); stdin.lock().read_line(&mut input).ok()?; let got = input .split_whitespace() .map(str::parse) .map(Result::ok) .collect::>>() .and_then(|x| -> Option<[usize; 2]> { x.try_into().ok() }) .map(|x| (x[0], x[1])); if got.is_some() { return got; } } } fn name(&self) -> &'static str { "Manual Agent" } fn color(&self) -> Piece { self.color } } impl ManualAgent { #[allow(dead_code)] pub const fn new(color: Piece) -> Self { Self { color } } } pub struct RandomAgent { color: Piece, } impl Agent for RandomAgent { fn next_move(&mut self, board: &Board) -> Option<(usize, usize)> { board.possible_moves(self.color).choose(&mut rand::rng()) } fn name(&self) -> &'static str { "Random Agent" } fn color(&self) -> Piece { self.color } } impl RandomAgent { #[allow(dead_code)] pub const fn new(color: Piece) -> Self { Self { color } } }