diff options
| author | Micha White <botahamec@outlook.com> | 2023-09-27 09:41:01 -0400 |
|---|---|---|
| committer | Micha White <botahamec@outlook.com> | 2023-09-27 09:41:01 -0400 |
| commit | f7a7bf20a99b1d52ef5f936705611ce24a1006b7 (patch) | |
| tree | 1fd1c71d1e94d664f9f6c74e7610eb94b0c68f49 /ai/src/eval.rs | |
| parent | 89a1d6b488f83d121e55d8a6c08efe01649bb692 (diff) | |
Edited some of the crates
Diffstat (limited to 'ai/src/eval.rs')
| -rw-r--r-- | ai/src/eval.rs | 145 |
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 - } -} |
