From c6abe49f50306e96c58ce7fce7fcee070b463557 Mon Sep 17 00:00:00 2001 From: Lemmy <10430540+TierynnB@users.noreply.github.com> Date: Sat, 24 Aug 2024 17:03:29 +1000 Subject: [PATCH] pushing for initial release --- src/board.rs | 31 ++++++++++++++++++++++++------- src/conversion.rs | 2 +- src/search.rs | 23 +++++++++++++++-------- src/uci.rs | 21 ++++++++++----------- 4 files changed, 50 insertions(+), 27 deletions(-) diff --git a/src/board.rs b/src/board.rs index a7ff469..3d61d41 100644 --- a/src/board.rs +++ b/src/board.rs @@ -32,7 +32,7 @@ pub struct Board { pub side_to_move: i8, pub hash_of_previous_positions: Vec, pub ply_record: Vec, - pub running_evaluation: i32, + running_evaluation: i32, pub player_colour: i8, } @@ -221,9 +221,10 @@ impl Board { piece_type: i8, piece_colour: i8, ) { - let mut value = get_piece_square_value(location, piece_type, piece_colour); + // running eval is always from whites perspective + // let mut value = get_piece_square_value(location, piece_type, piece_colour); - value += match piece_type { + let value = match piece_type { PAWN => 82, KNIGHT => 337, BISHOP => 365, @@ -231,21 +232,37 @@ impl Board { QUEEN => 1025, _ => 0, }; - if piece_colour == self.player_colour { + if piece_colour == WHITE { self.running_evaluation -= value; } else { self.running_evaluation += value; } // println!("running_evaluation: {}", self.running_evaluation); } + pub fn get_running_evaluation(&self) -> i32 { + // if white to move, return running evaluation, else return -running evaluation + if self.side_to_move == WHITE { + return self.running_evaluation; + } else { + return -self.running_evaluation; + } + } + pub fn set_running_evaluation(&mut self, running_evaluation: i32) { + // if white to move, return running evaluation, else return -running evaluation + if self.side_to_move == WHITE { + self.running_evaluation = running_evaluation; + } else { + self.running_evaluation = -running_evaluation; + } + } pub fn add_piece_to_evaluation( &mut self, location: (usize, usize), piece_type: i8, piece_colour: i8, ) { - let mut value = get_piece_square_value(location, piece_type, piece_colour); - value += match piece_type { + // let mut value = get_piece_square_value(location, piece_type, piece_colour); + let value = match piece_type { PAWN => 82, KNIGHT => 337, BISHOP => 365, @@ -254,7 +271,7 @@ impl Board { _ => 0, }; - if piece_colour == self.player_colour { + if piece_colour == WHITE { self.running_evaluation += value; } else { self.running_evaluation -= value; diff --git a/src/conversion.rs b/src/conversion.rs index 1b72294..f70fa0a 100644 --- a/src/conversion.rs +++ b/src/conversion.rs @@ -134,7 +134,7 @@ pub fn convert_fen_to_board(fen: &str) -> Board { } // update running eval - board.running_evaluation = evaluate::evaluate(&board); + board.set_running_evaluation(evaluate::evaluate(&board)); return board; } diff --git a/src/search.rs b/src/search.rs index 890b2fd..77eed9f 100644 --- a/src/search.rs +++ b/src/search.rs @@ -59,13 +59,11 @@ impl SearchEngine { ) -> i32 { // the move needs to record its own evaluation if depth == 0 { - let running_evaluation = board.running_evaluation; - // if board.side_to_move != WHITE { - // running_evaluation *= -1; - // } + let running_evaluation = board.get_running_evaluation(); + return running_evaluation; }; - + let side_to_move = board.side_to_move; // generate moves for current depth of board let mut moves_for_current_depth = generate_pseudo_legal_moves(board, board.side_to_move, 1); order_moves(&mut moves_for_current_depth); @@ -73,9 +71,11 @@ impl SearchEngine { let mut max_eval = -1000; for generated_move in moves_for_current_depth.iter() { board.make_move(generated_move); + self.nodes += 1; let eval = self.minimax(board, depth - 1, false, alpha, beta); + board.un_make_move(generated_move); max_eval = std::cmp::max(max_eval, eval); alpha = std::cmp::max(alpha, eval); @@ -91,9 +91,11 @@ impl SearchEngine { for generated_move in moves_for_current_depth.iter() { board.make_move(generated_move); self.nodes += 1; + let eval = self.minimax(board, depth - 1, true, alpha, beta); + board.un_make_move(generated_move); - min_eval = std::cmp::max(min_eval, eval); + min_eval = std::cmp::min(min_eval, eval); beta = std::cmp::min(beta, eval); if beta <= alpha { break; @@ -123,8 +125,11 @@ impl SearchEngine { continue; } - // print_board(board); - let score = self.minimax(board, depth, true, i32::MIN, i32::MAX); + let mut score = self.minimax(board, depth, true, i32::MIN, i32::MAX); + println!( + "colour: {}, root move: {}, eval: {}", + current_side, generated_move.notation_move, score + ); if score > best_score { best_score = score; @@ -138,7 +143,9 @@ impl SearchEngine { board.un_make_move(generated_move); // print_board(board); } + best_moves.sort_by(|a, b| b.best_score.cmp(&a.best_score)); + return best_moves; } diff --git a/src/uci.rs b/src/uci.rs index 90447b3..1464269 100644 --- a/src/uci.rs +++ b/src/uci.rs @@ -64,6 +64,7 @@ impl CommunicationManager { "isready" => CommandTypes::IsReady, "position" => CommandTypes::Position, "go" => CommandTypes::Go, + "search" => CommandTypes::Search, "quit" => CommandTypes::Quit, "printstate" | "show" | "print" => CommandTypes::PrintState, "evaluate" => CommandTypes::Evaluate, @@ -126,7 +127,7 @@ impl CommunicationManager { println!( "{}, {}", evaluate(&self.board), - self.board.running_evaluation + self.board.get_running_evaluation() ); } pub fn bench(&mut self) { @@ -143,13 +144,6 @@ impl CommunicationManager { nodes += self.engine.nodes; time_taken_micros += self.engine.start.elapsed().as_micros(); time_taken_seconds += self.engine.start.elapsed().as_secs_f32(); - - // println!( - // "nodes: {}, time:{:?}, nodes per second: {}", - // self.engine.nodes, - // self.engine.start.elapsed().as_micros(), - // self.engine.nodes as f32 / self.engine.start.elapsed().as_secs_f32() - // ); } println!( @@ -160,11 +154,14 @@ impl CommunicationManager { ); } pub fn search(&mut self, command_text: &str) { - match command_text.split_ascii_whitespace().next() { + let mut command_text_split = command_text.split_ascii_whitespace(); + let _search_token = command_text_split.next().expect("no token"); + + match command_text_split.next() { None => println!("no more commands"), Some(arg_2) => { self.engine = SearchEngine::new(); - let depth: i8 = arg_2.parse().expect("Invalid depth value"); + let depth: i8 = arg_2.parse::().expect("Invalid depth value"); let outcome = self.engine.search(&mut self.board, depth); println!( "nodes: {}, time:{:?}, nodes per second: {}", @@ -172,6 +169,8 @@ impl CommunicationManager { self.engine.start.elapsed().as_micros(), self.engine.nodes as f32 / self.engine.start.elapsed().as_secs_f32() ); + + // get random move from best moves with matching top score. println!( "best move {}, score {}", outcome[0].best_move.notation_move, outcome[0].best_score @@ -261,7 +260,7 @@ impl CommunicationManager { _ => {} } } - let moves = self.engine.search(&mut self.board, 3); + let moves = self.engine.search(&mut self.board, 5); // for bestmoves in &moves { // println!( // "move: {}, score: {}",