othello/src/agent.rs
2025-02-08 22:49:52 -05:00

78 lines
1.6 KiB
Rust

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::<Option<Vec<_>>>()
.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 }
}
}