69 lines
1.8 KiB
Rust
69 lines
1.8 KiB
Rust
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<impl Iterator<Item = board::Position> + '_, ()> {
|
|
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())
|
|
}
|
|
}
|