summaryrefslogtreecommitdiff
path: root/ai/src/eval.rs
diff options
context:
space:
mode:
authorMicha White <botahamec@outlook.com>2023-09-27 09:41:01 -0400
committerMicha White <botahamec@outlook.com>2023-09-27 09:41:01 -0400
commitf7a7bf20a99b1d52ef5f936705611ce24a1006b7 (patch)
tree1fd1c71d1e94d664f9f6c74e7610eb94b0c68f49 /ai/src/eval.rs
parent89a1d6b488f83d121e55d8a6c08efe01649bb692 (diff)
Edited some of the crates
Diffstat (limited to 'ai/src/eval.rs')
-rw-r--r--ai/src/eval.rs145
1 files changed, 0 insertions, 145 deletions
diff --git a/ai/src/eval.rs b/ai/src/eval.rs
deleted file mode 100644
index a3265bf..0000000
--- a/ai/src/eval.rs
+++ /dev/null
@@ -1,145 +0,0 @@
-use std::{mem::MaybeUninit, num::NonZeroU8, ops::Neg};
-
-use model::{CheckersBitBoard, Move, PieceColor, PossibleMoves};
-
-use crate::transposition_table::TranspositionTableRef;
-
-const KING_WORTH: u32 = 2;
-
-fn eval_position(board: CheckersBitBoard) -> f32 {
- let light_pieces = board.pieces_bits() & !board.color_bits();
- let dark_pieces = board.pieces_bits() & board.color_bits();
-
- let light_peasants = light_pieces & !board.king_bits();
- let dark_peasants = dark_pieces & !board.king_bits();
-
- let light_kings = light_pieces & board.king_bits();
- let dark_kings = dark_pieces & board.king_bits();
-
- // if we assume the black player doesn't exist, how good is this for white?
- let light_eval =
- (light_peasants.count_ones() as f32) + ((light_kings.count_ones() * KING_WORTH) as f32);
- let dark_eval =
- (dark_peasants.count_ones() as f32) + ((dark_kings.count_ones() * KING_WORTH) as f32);
-
- // avoiding a divide by zero error
- if dark_eval + light_eval != 0.0 {
- (dark_eval - light_eval) / (dark_eval + light_eval)
- } else {
- 0.0
- }
-}
-
-fn eval_jumps(
- mut alpha: f32,
- beta: f32,
- board: CheckersBitBoard,
- table: TranspositionTableRef,
-) -> f32 {
- // todo stop checking for jumps twice, but also don't look for slides if there are no jumps
- if PossibleMoves::has_jumps(board) {
- // todo check if this is useful
- // todo make a board for the other player's turn reusable
-
- let turn = board.turn();
- let mut best_eval = f32::NEG_INFINITY;
- let moves = PossibleMoves::moves(board);
-
- if moves.is_empty() {
- return -1.0;
- }
-
- for current_move in moves {
- let board = unsafe { current_move.apply_to(board) };
- let current_eval = if board.turn() != turn {
- -eval_jumps(-beta, -alpha, board, table)
- } else {
- eval_jumps(alpha, beta, board, table)
- };
-
- table.insert(board, current_eval, unsafe { NonZeroU8::new_unchecked(1) });
-
- if current_eval >= beta {
- return beta;
- }
-
- if best_eval < current_eval {
- best_eval = current_eval;
- }
- if alpha < best_eval {
- alpha = best_eval;
- }
- }
-
- best_eval
- } else if board.turn() == PieceColor::Dark {
- eval_position(board)
- } else {
- -eval_position(board)
- }
-}
-
-unsafe fn sort_moves(
- a: &Move,
- b: &Move,
- board: CheckersBitBoard,
- table: TranspositionTableRef,
-) -> std::cmp::Ordering {
- let a_entry = table.get_any_depth(a.apply_to(board)).unwrap_or_default();
- let b_entry = table.get_any_depth(b.apply_to(board)).unwrap_or_default();
- a_entry.total_cmp(&b_entry)
-}
-
-pub fn negamax(
- depth: u8,
- mut alpha: f32,
- beta: f32,
- board: CheckersBitBoard,
- table: TranspositionTableRef,
-) -> f32 {
- if depth < 1 {
- if board.turn() == PieceColor::Dark {
- eval_position(board)
- } else {
- -eval_position(board)
- }
- } else {
- if let Some(entry) = table.get(board, depth) {
- return entry;
- }
-
- let turn = board.turn();
- let mut best_eval = f32::NEG_INFINITY;
- let mut moves: Vec<Move> = PossibleMoves::moves(board).into_iter().collect();
- moves.sort_unstable_by(|a, b| unsafe { sort_moves(a, b, board, table) });
-
- if moves.is_empty() {
- return -1.0;
- }
-
- for current_move in moves {
- let board = unsafe { current_move.apply_to(board) };
- let current_eval = if board.turn() == turn {
- negamax(depth - 1, alpha, beta, board, table)
- } else {
- -negamax(depth - 1, -beta, -alpha, board, table)
- };
-
- if best_eval < current_eval {
- best_eval = current_eval;
- }
-
- if alpha < best_eval {
- alpha = best_eval;
- }
-
- if alpha >= beta {
- return best_eval;
- }
- }
-
- table.insert(board, best_eval, unsafe { NonZeroU8::new_unchecked(depth) });
-
- best_eval
- }
-}