summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ai/src/lib.rs20
-rw-r--r--cli/src/eval.rs6
-rw-r--r--cli/src/main.rs24
-rw-r--r--model/src/moves.rs14
4 files changed, 61 insertions, 3 deletions
diff --git a/ai/src/lib.rs b/ai/src/lib.rs
index 405c88d..89fd345 100644
--- a/ai/src/lib.rs
+++ b/ai/src/lib.rs
@@ -1,4 +1,5 @@
pub use model::{CheckersBitBoard, Move, PieceColor, PossibleMoves};
+use std::mem::MaybeUninit;
const KING_WORTH: u32 = 2;
@@ -22,7 +23,7 @@ fn eval_position(board: CheckersBitBoard) -> f32 {
if dark_eval + light_eval != 0.0 {
light_eval / (dark_eval + light_eval)
} else {
- 0.0
+ 0.5
}
}
@@ -55,3 +56,20 @@ pub fn eval(depth: usize, mut alpha: f32, beta: f32, board: CheckersBitBoard) ->
best_eval
}
}
+
+pub fn best_move(depth: usize, board: CheckersBitBoard) -> Move {
+ let mut best_eval = 0.0;
+ let mut best_move = MaybeUninit::uninit();
+ for current_move in PossibleMoves::moves(board) {
+ let current_eval = eval(depth - 1, best_eval, 1.0, unsafe {
+ current_move.apply_to(board)
+ });
+ println!("{} {}", current_move, current_eval);
+ if current_eval > best_eval {
+ best_eval = current_eval;
+ best_move = MaybeUninit::new(current_move);
+ }
+ }
+
+ unsafe { best_move.assume_init() }
+}
diff --git a/cli/src/eval.rs b/cli/src/eval.rs
index d078c5f..72fa32a 100644
--- a/cli/src/eval.rs
+++ b/cli/src/eval.rs
@@ -1,4 +1,8 @@
-use ai::CheckersBitBoard;
+use ai::{CheckersBitBoard, Move};
pub fn eval(depth: usize) -> f32 {
ai::eval(depth, 0.0, 1.0, CheckersBitBoard::starting_position())
}
+
+pub fn best_move(depth: usize) -> Move {
+ ai::best_move(depth, CheckersBitBoard::starting_position())
+}
diff --git a/cli/src/main.rs b/cli/src/main.rs
index a550092..d230398 100644
--- a/cli/src/main.rs
+++ b/cli/src/main.rs
@@ -31,6 +31,17 @@ fn main() {
.help("The depth to go to"),
),
)
+ .subcommand(
+ SubCommand::with_name("best")
+ .about("Calculate the best move")
+ .arg(
+ Arg::with_name("depth")
+ .required(true)
+ .short("d")
+ .takes_value(true)
+ .help("The depth to go to"),
+ ),
+ )
.get_matches();
if let Some(matches) = matches.subcommand_matches("perft") {
@@ -59,4 +70,17 @@ fn main() {
)
);
}
+
+ if let Some(matches) = matches.subcommand_matches("best") {
+ println!(
+ "{}",
+ eval::best_move(
+ matches
+ .value_of("depth")
+ .unwrap()
+ .parse()
+ .expect("Error: not a valid number")
+ )
+ )
+ }
}
diff --git a/model/src/moves.rs b/model/src/moves.rs
index 720e11a..f6b1fce 100644
--- a/model/src/moves.rs
+++ b/model/src/moves.rs
@@ -1,4 +1,5 @@
-use crate::CheckersBitBoard;
+use crate::{CheckersBitBoard, SquareCoordinate};
+use std::fmt::{Display, Formatter};
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub enum MoveDirection {
@@ -122,6 +123,17 @@ impl Move {
}
}
+impl Display for Move {
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
+ write!(
+ f,
+ "{}-{}",
+ SquareCoordinate::from_value(self.start as usize),
+ SquareCoordinate::from_value(self.end_position())
+ )
+ }
+}
+
#[cfg(test)]
mod tests {