diff --git a/src/agent.rs b/src/agent.rs index 07de042..f6878b1 100644 --- a/src/agent.rs +++ b/src/agent.rs @@ -1,5 +1,5 @@ use crate::{ - board::{Board, BOARD_SIZE}, + board::Board, piece::Piece, }; use rand::prelude::*; @@ -59,14 +59,7 @@ pub struct RandomAgent { impl Agent for RandomAgent { fn next_move(&mut self, board: &Board) -> Option<(usize, usize)> { - (0..BOARD_SIZE) - .flat_map(|i| { - (0..BOARD_SIZE) - .map(|j| (i, j)) - .collect::>() - }) - .flat_map(|(i, j)| board.what_if(i, j, self.color).map(|_| (i, j))) - .choose(&mut rand::rng()) + board.possible_moves(self.color).choose(&mut rand::rng()) } fn name(&self) -> &'static str { diff --git a/src/board.rs b/src/board.rs index 70a8029..b585f7e 100644 --- a/src/board.rs +++ b/src/board.rs @@ -74,6 +74,14 @@ impl Board { self } + pub fn possible_moves(&self, color: Piece) -> Box + '_> { + Box::new( + (0..BOARD_SIZE) + .flat_map(|i| (0..BOARD_SIZE).map(move |j| (i, j))) + .filter(move |(i, j)| self.what_if(*i, *j, color).is_some()), + ) + } + /// Returns a mutable reference to a place on the [`Board`] /// at (i, j) pub const fn get_mut(&mut self, i: usize, j: usize) -> &mut Option { diff --git a/src/complexagent.rs b/src/complexagent.rs index 0d9e930..98d89a6 100644 --- a/src/complexagent.rs +++ b/src/complexagent.rs @@ -1,8 +1,4 @@ -use crate::{ - agent::Agent, - board::{Board, BOARD_SIZE}, - piece::Piece, -}; +use crate::{agent::Agent, board::Board, piece::Piece}; pub struct ComplexAgent { color: Piece, @@ -22,7 +18,10 @@ impl Move { if i == 0 { return; } - self.next_move = problem_space(&self.board, !self.color); + + if self.next_move.is_empty() { + self.next_move = problem_space(&self.board, !self.color).collect(); + } self.next_move .iter_mut() .for_each(|x| x.populate_next_moves(i - 1)); @@ -47,37 +46,33 @@ impl Move { } } -fn problem_space(board: &Board, color: Piece) -> Vec { - (0..BOARD_SIZE) - .flat_map(|i| { - (0..BOARD_SIZE) - .map(|j| (i, j)) - .collect::>() - }) - .flat_map(|(i, j)| board.what_if(i, j, color).map(|x| (i, j, x))) - .map(|(i, j, (board, captured))| Move { - i, - j, - captured, - color, - board, - next_move: Vec::new(), - }) - .collect() +fn problem_space(board: &Board, color: Piece) -> Box + '_> { + Box::new( + board + .possible_moves(color) + .flat_map(move |(i, j)| board.what_if(i, j, color).map(|x| (i, j, x))) + .map(move |(i, j, (board, captured))| Move { + i, + j, + captured, + color, + board, + next_move: Vec::new(), + }), + ) } impl Agent for ComplexAgent { fn next_move(&mut self, board: &Board) -> Option<(usize, usize)> { const LOOPS: usize = 5; problem_space(board, self.color) - .into_iter() .map(|mut x| { x.populate_next_moves(LOOPS); x }) .map(|m| ((m.i, m.j), m.value(self.color))) - .max_by_key(|&(_, c)| c) - .map(|(x, _)| x) + .max_by_key(|a| a.1) + .map(|a| a.0) } fn name(&self) -> &'static str { diff --git a/src/main.rs b/src/main.rs index 789a103..5c9bb14 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,3 @@ -use agent::{ManualAgent, RandomAgent}; -use complexagent::ComplexAgent; use game::Game; use piece::Piece; @@ -11,10 +9,10 @@ mod misc; mod piece; fn main() { - let player1 = ComplexAgent::new(Piece::Black); - // let player2 = ComplexAgent::new(Piece::White); - let player2 = ManualAgent::new(Piece::White); - // let player2 = RandomAgent::new(Piece::White); + let player1 = complexagent::ComplexAgent::new(Piece::Black); + // let player2 = complexagent::ComplexAgent::new(Piece::White); + let player2 = agent::ManualAgent::new(Piece::White); + // let player2 = agent::RandomAgent::new(Piece::White); let mut game = Game::new(Box::new(player1), Box::new(player2)); game.game_loop(); }