Implement basic move evaluation
It ain't much but it's honest work
This commit is contained in:
@@ -264,6 +264,7 @@ impl PieceType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct Piece {
|
pub struct Piece {
|
||||||
pub color: Color,
|
pub color: Color,
|
||||||
pub piece_type: PieceType,
|
pub piece_type: PieceType,
|
||||||
@@ -292,6 +293,7 @@ impl Piece {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct Board {
|
pub struct Board {
|
||||||
state: HashMap<Position, Piece>,
|
state: HashMap<Position, Piece>,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,19 @@
|
|||||||
use crate::board;
|
use crate::board;
|
||||||
use rand::seq::IteratorRandom;
|
use crate::rand::Rng;
|
||||||
|
|
||||||
|
impl board::PieceType {
|
||||||
|
fn value(&self) -> f32 {
|
||||||
|
match self {
|
||||||
|
board::PieceType::Pawn => 1.0,
|
||||||
|
board::PieceType::Knight => 3.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Move_ {
|
||||||
|
pub source: board::Position,
|
||||||
|
pub target: board::Position,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Engine {
|
pub struct Engine {
|
||||||
board: board::Board,
|
board: board::Board,
|
||||||
@@ -43,16 +57,38 @@ impl Engine {
|
|||||||
self.board.relocate(source, target)
|
self.board.relocate(source, target)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn choose_move(
|
pub fn evaluate_position(&self, board: &board::Board) -> f32 {
|
||||||
|
board
|
||||||
|
.iter()
|
||||||
|
.map(|(_, piece)| match piece.color {
|
||||||
|
board::Color::White => 1.0,
|
||||||
|
board::Color::Black => -1.0,
|
||||||
|
} * piece.piece_type.value())
|
||||||
|
.sum()
|
||||||
|
}
|
||||||
|
pub fn evaluate_move(
|
||||||
&self,
|
&self,
|
||||||
color: &board::Color,
|
color: &board::Color,
|
||||||
) -> Option<(board::Position, board::Position)> {
|
move_: &Move_,
|
||||||
self.board
|
) -> Result<f32, ()> {
|
||||||
|
let mut board = self.board.clone();
|
||||||
|
board.relocate(&move_.source, move_.target.clone())?;
|
||||||
|
Ok(match color {
|
||||||
|
board::Color::White => 1.0,
|
||||||
|
board::Color::Black => -1.0,
|
||||||
|
} * self.evaluate_position(&board))
|
||||||
|
}
|
||||||
|
pub fn choose_move(&self, color: &board::Color) -> Option<Move_> {
|
||||||
|
let all_moves = self
|
||||||
|
.board
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|(source, piece)| {
|
.filter_map(|(source, piece)| {
|
||||||
if &piece.color == color {
|
if &piece.color == color {
|
||||||
if let Ok(targets) = self.get_legal_moves(source) {
|
if let Ok(targets) = self.get_legal_moves(source) {
|
||||||
Some(targets.map(|target| (source.clone(), target)))
|
Some(targets.map(|target| Move_ {
|
||||||
|
source: source.clone(),
|
||||||
|
target,
|
||||||
|
}))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@@ -60,7 +96,21 @@ impl Engine {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.flatten()
|
.flatten();
|
||||||
.choose(&mut rand::thread_rng())
|
let mut rng = rand::thread_rng();
|
||||||
|
Some(
|
||||||
|
all_moves
|
||||||
|
.map(|move_| {
|
||||||
|
(
|
||||||
|
self.evaluate_move(color, &move_).unwrap()
|
||||||
|
+ rng.gen::<f32>() * 0.1,
|
||||||
|
move_,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.max_by(|(score1, _), (score2, _)| {
|
||||||
|
score1.partial_cmp(score2).unwrap()
|
||||||
|
})?
|
||||||
|
.1,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -258,8 +258,8 @@ impl Ui {
|
|||||||
format!("Couldn't parse color code {}", color_char)
|
format!("Couldn't parse color code {}", color_char)
|
||||||
})?,
|
})?,
|
||||||
) {
|
) {
|
||||||
Some((source, target)) => {
|
Some(move_) => {
|
||||||
Ok(format!("{},{}", source, target))
|
Ok(format!("{},{}", move_.source, move_.target))
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
Err(format!("No move possible for {}", color_char))
|
Err(format!("No move possible for {}", color_char))
|
||||||
|
|||||||
Reference in New Issue
Block a user