use crate::board; use rand::seq::IteratorRandom; pub struct Engine { board: board::Board, } impl Engine { pub fn new() -> Self { let mut board = board::Board::new(); board.reset(); Engine { board, } } pub fn get_state(&self) -> &board::Board { &self.board } pub fn set_state(&mut self, board: board::Board) { self.board = board; } pub fn get_legal_moves( &self, position: &board::Position, ) -> Result + '_, ()> { if self.board.occupied(position) { Ok(self .board .find_moves(position) .unwrap() .chain(self.board.find_captures(position).unwrap())) } else { Err(()) } } pub fn make_move( &mut self, source: &board::Position, target: board::Position, ) -> Result<(), ()> { if !self.get_legal_moves(source)?.any(|pos| pos == target) { Err(()) } else { // We checked that there is a piece at source in get_legal_moves self.board.relocate(source, target) } } pub fn choose_move( &self, color: &board::Color, ) -> Option<(board::Position, board::Position)> { self.board .iter() .filter_map(|(source, piece)| { if &piece.color == color { if let Ok(targets) = self.get_legal_moves(source) { Some(targets.map(|target| (source.clone(), target))) } else { None } } else { None } }) .flatten() .choose(&mut rand::thread_rng()) } }