Skip to content

Commit

Permalink
fixed perft
Browse files Browse the repository at this point in the history
  • Loading branch information
TierynnB committed Aug 31, 2024
1 parent 7149236 commit 8ff72d4
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 44 deletions.
41 changes: 35 additions & 6 deletions src/board.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,11 +252,34 @@ impl Board {
// even if rook moves by itself, set rook not moved to false
if move_to_do.from_piece == ROOK {
if move_to_do.from_colour == WHITE {
self.can_castle_a1 = false;
self.can_castle_h1 = false;
if move_to_do.from == (7, 0) {
self.can_castle_a1 = false;
} else if move_to_do.from == (7, 7) {
self.can_castle_h1 = false;
}
} else if move_to_do.from_colour == BLACK {
self.can_castle_a8 = false;
self.can_castle_h8 = false;
if move_to_do.from == (0, 0) {
self.can_castle_a8 = false;
} else if move_to_do.from == (0, 7) {
self.can_castle_h8 = false;
}
}
}

// if rook is captured by another piece, cant castle anymore
if move_to_do.to_piece == ROOK {
if move_to_do.to_colour == WHITE {
if move_to_do.to == (7, 0) {
self.can_castle_a1 = false;
} else if move_to_do.to == (7, 7) {
self.can_castle_h1 = false;
}
} else if move_to_do.to_colour == BLACK {
if move_to_do.to == (0, 0) {
self.can_castle_a8 = false;
} else if move_to_do.to == (0, 7) {
self.can_castle_h8 = false;
}
}
}

Expand Down Expand Up @@ -664,6 +687,12 @@ pub fn print_board(board: &Board) {

println!("game ply: {}", board.ply);
println!("to move: {}", board.side_to_move);
println!("is white in check:{}", evaluate::is_in_check(board, WHITE, None));
println!("is black in check:{}", evaluate::is_in_check(board, BLACK, None));
println!(
"is white in check:{}",
evaluate::is_in_check(board, WHITE, None)
);
println!(
"is black in check:{}",
evaluate::is_in_check(board, BLACK, None)
);
}
2 changes: 1 addition & 1 deletion src/evaluate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pub fn is_in_check(
) -> bool {
let opponent_colour = if side_to_check == WHITE { BLACK } else { WHITE };
let king_location = board.get_king_location(side_to_check);

for (row_index, row) in board.colour_array.iter().enumerate() {
for (column_index, square_colour) in row.iter().enumerate() {
if square_colour != &opponent_colour {
Expand Down
15 changes: 12 additions & 3 deletions src/moveGen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -667,6 +667,7 @@ pub fn generate_king_moves(
square: (usize, usize),
side_to_generate_for: i8,
board: &Board,
is_in_check: bool,
) -> Vec<Move> {
// when castling, take into account that the king is moving through the squares, not teleporting
// only for those squares castling still possible
Expand Down Expand Up @@ -704,8 +705,12 @@ pub fn generate_king_moves(
}
}

// castling
// if in check, don't generate castling
if is_in_check {
return moves;
}

// castling
if side_to_generate_for == WHITE {
if board.can_castle_a1
&& board.is_square_empty("b1")
Expand Down Expand Up @@ -809,7 +814,11 @@ pub fn generate_king_moves(
return moves;
}

pub fn generate_pseudo_legal_moves(board: &Board, side_to_generate_for: i8) -> Vec<Move> {
pub fn generate_pseudo_legal_moves(
board: &Board,
side_to_generate_for: i8,
is_in_check: bool,
) -> Vec<Move> {
let mut moves: Vec<Move> = vec![];
// println!("square: {}", 1);
// println!("side_to_generate_for: {}", side_to_generate_for);
Expand All @@ -828,7 +837,7 @@ pub fn generate_pseudo_legal_moves(board: &Board, side_to_generate_for: i8) -> V
3 => generate_bishop_moves(location, side_to_generate_for, board),
4 => generate_rook_moves(location, side_to_generate_for, board),
5 => generate_queen_moves(location, side_to_generate_for, board),
6 => generate_king_moves(location, side_to_generate_for, board),
6 => generate_king_moves(location, side_to_generate_for, board, is_in_check),
_ => vec![],
};

Expand Down
59 changes: 26 additions & 33 deletions src/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ use crate::moves::*;
use std::time::Instant;
pub struct MoveNode {
pub move_notation: String,
pub nodes: i32,
pub nodes: i128,
}
pub struct BestMoves {
pub best_move: Move,
pub best_score: i32,
}
pub struct SearchEngine {
pub nodes: i32,
pub nodes: i128,
pub start: Instant,
pub move_nodes: Vec<MoveNode>,
pub depth: i8,
Expand Down Expand Up @@ -58,19 +58,19 @@ impl SearchEngine {
) -> i32 {
// the move needs to record its own evaluation
if depth == 0 {
self.nodes += 1;
return evaluate::evaluate(&board);
};

// generate moves for current depth of board
let mut moves_for_current_depth = generate_pseudo_legal_moves(board, board.side_to_move);
let mut moves_for_current_depth =
generate_pseudo_legal_moves(board, board.side_to_move, false);
order_moves(&mut moves_for_current_depth);
if maximizing_player {
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);
Expand All @@ -81,13 +81,11 @@ impl SearchEngine {
}
}
return max_eval;

// and best outcome for minimising player (enemy)
} else {
let mut min_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, true, alpha, beta);

Expand All @@ -112,8 +110,12 @@ impl SearchEngine {
self.nodes = 0;
self.start = Instant::now();
let current_side = board.side_to_move;

let currently_in_check = evaluate::is_in_check(board, current_side, None);

// generate moves for current depth of board
let mut moves_for_current_depth = generate_pseudo_legal_moves(board, board.side_to_move);
let mut moves_for_current_depth =
generate_pseudo_legal_moves(board, board.side_to_move, currently_in_check);
order_moves(&mut moves_for_current_depth);
for generated_move in moves_for_current_depth.iter() {
board.make_move(generated_move);
Expand Down Expand Up @@ -155,56 +157,47 @@ impl SearchEngine {
return (best_move, best_moves);
}

pub fn perft(&mut self, board: &mut Board, depth: i8, first_call: bool, print_all_moves: bool) {
pub fn perft(&mut self, board: &mut Board, depth: i8, first_call: bool) -> i128 {
let mut nodes_per_root_move: i128 = 0;
let mut nodes: i128 = 0;
if depth == 0 {
return;
return 1;
}
// println!("ply {} side {}", board.ply, board.side_to_move);
let current_side = board.side_to_move;

let moves_for_current_depth = generate_pseudo_legal_moves(board, board.side_to_move);

let currently_in_check = evaluate::is_in_check(board, current_side, None);

let moves_for_current_depth =
generate_pseudo_legal_moves(board, board.side_to_move, currently_in_check);

for generated_move in moves_for_current_depth.iter() {
board.make_move(generated_move);

if evaluate::is_in_check(
board,
current_side,
generated_move.castling_intermediary_square,
) {
board.un_make_move(generated_move);

continue;
}

if !first_call {
self.nodes += 1;
} else if depth == 1 {
self.nodes += 1;
} else {
self.nodes = 0;
}

// println!("root move: {}", generated_move.notation_move);
self.perft(board, depth - 1, false);

nodes_per_root_move = self.perft(board, depth - 1, false);
nodes += nodes_per_root_move;
board.un_make_move(generated_move);

if first_call {
// update root node here with number
self.move_nodes.push(MoveNode {
move_notation: generated_move.notation_move.clone(),
nodes: self.nodes,
nodes: nodes_per_root_move,
});
self.nodes = 0;
}
}
if first_call {
self.nodes = 0;
for move_node in self.move_nodes.iter() {
self.nodes += move_node.nodes;
self.nodes += nodes;
}
}

return nodes;
}

pub fn bench() {
Expand Down
3 changes: 2 additions & 1 deletion src/uci.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,14 +229,15 @@ impl CommunicationManager {
.parse()
.expect("Invalid depth value");
self.engine = SearchEngine::new();
self.engine.perft(&mut self.board, depth, true);
let nodes = self.engine.perft(&mut self.board, depth, true);
// println!("total nodes: {}", self.engine.nodes);
// println!("root moves: {}", self.engine.move_nodes.len());
for root in self.engine.move_nodes.iter() {
println!("{} - {}", root.move_notation, root.nodes);
}
println!("total nodes: {}", self.engine.nodes);
println!("root moves: {}", self.engine.move_nodes.len());
println!("perft nodes: {}", nodes);
println!()
}
pub fn enable_uci(&mut self) {
Expand Down

0 comments on commit 8ff72d4

Please sign in to comment.