Fix move generator bugs related to castling, enpassant, promotion
This commit is contained in:
54
src/board.rs
54
src/board.rs
@@ -4,7 +4,7 @@ use crate::attack::{
|
||||
get_bishop_attacks, get_king_attacks, get_knight_attacks, get_pawn_attacks, get_queen_attacks,
|
||||
get_rook_attacks,
|
||||
};
|
||||
use crate::game::State;
|
||||
use crate::game::{Castle, State};
|
||||
use crate::movegen::{
|
||||
bishop_pseudo_moves, king_pseudo_moves, knight_pseudo_moves, pawn_pseudo_moves,
|
||||
queen_pseudo_moves, rook_pseudo_moves,
|
||||
@@ -88,12 +88,12 @@ impl Board {
|
||||
|
||||
pub fn is_attacked(&self, sq: usize, opponent_color: Color) -> bool {
|
||||
let all_occupancies = self.get_all_occupancies();
|
||||
let enemy = match opponent_color {
|
||||
Color::Black => &self.black_pieces,
|
||||
Color::White => &self.white_pieces,
|
||||
let (enemy, own_color) = match opponent_color {
|
||||
Color::Black => (&self.black_pieces, Color::White),
|
||||
Color::White => (&self.white_pieces, Color::Black),
|
||||
};
|
||||
|
||||
enemy[Kind::Pawn.idx()].bitboard & get_pawn_attacks(sq, opponent_color) != 0
|
||||
enemy[Kind::Pawn.idx()].bitboard & get_pawn_attacks(sq, own_color) != 0
|
||||
|| enemy[Kind::Knight.idx()].bitboard & get_knight_attacks(sq) != 0
|
||||
|| enemy[Kind::Bishop.idx()].bitboard & get_bishop_attacks(all_occupancies, sq) != 0
|
||||
|| enemy[Kind::Rook.idx()].bitboard & get_rook_attacks(all_occupancies, sq) != 0
|
||||
@@ -156,14 +156,18 @@ impl Board {
|
||||
|
||||
pub fn make_move(&mut self, mv: Move, color: Color) -> bool {
|
||||
self.update_board_state(&mv, color);
|
||||
self.state.update_castling_state(mv.source as u8, color);
|
||||
self.state.change_side();
|
||||
|
||||
let pieces = match color {
|
||||
Color::White => &self.white_pieces,
|
||||
Color::Black => &self.black_pieces,
|
||||
};
|
||||
|
||||
self.state
|
||||
.update_castling_state_quiet(mv.source as u8, color);
|
||||
self.state
|
||||
.update_castling_state_capture(mv.target as u8, Color::opponent_color(color));
|
||||
self.state.change_side();
|
||||
|
||||
let own_king_square = pieces[Kind::King.idx()].bitboard.trailing_zeros() as usize;
|
||||
self.is_move_legit(own_king_square, Color::opponent_color(color))
|
||||
}
|
||||
@@ -191,7 +195,10 @@ impl Board {
|
||||
}
|
||||
MoveType::DoublePush => {
|
||||
Board::move_piece(mv.source as u8, mv.target as u8, own_pieces);
|
||||
let en_passant = Some(mv.source as u8 + 8);
|
||||
let en_passant = match color {
|
||||
Color::White => Some((mv.source + 8) as u8),
|
||||
Color::Black => Some((mv.source - 8) as u8),
|
||||
};
|
||||
self.state.set_en_passant_target_square(en_passant);
|
||||
}
|
||||
MoveType::Promotion(promote) => {
|
||||
@@ -209,6 +216,7 @@ impl Board {
|
||||
Board::move_piece(mv.source as u8, mv.target as u8, own_pieces);
|
||||
Board::move_rook_castle(mv.target as u8, own_pieces);
|
||||
self.state.set_en_passant_target_square(None);
|
||||
self.state.set_castling_ability(color, Castle::None)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -230,13 +238,7 @@ impl Board {
|
||||
_ => return,
|
||||
};
|
||||
|
||||
for p in pieces.iter_mut() {
|
||||
if p.bitboard & 1_u64 << rook_source != 0 {
|
||||
p.bitboard &= !(1_u64 << rook_source);
|
||||
p.bitboard |= 1_u64 << rook_target;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Board::move_piece(rook_source, rook_target, pieces);
|
||||
}
|
||||
|
||||
fn promote_piece(square: u8, pieces: &mut [Piece; 6], promote: Promote) {
|
||||
@@ -464,28 +466,6 @@ mod tests {
|
||||
let mv = Move::new_with_type(4, 6, MoveType::Castle);
|
||||
game.board.make_move(mv, Color::White);
|
||||
assert_eq!(game, from_fen(FEN_CASTLE[1])?);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_perftree_snapshots() -> Result<(), String> {
|
||||
init_attacks();
|
||||
|
||||
let mut game = from_fen("rnbqkbnr/ppppp1pp/5p2/7Q/8/4P3/PPPP1PPP/RNB1KBNR w KQkq - 0 1")?;
|
||||
for mv in game.board.pseudo_moves_all(Color::Black) {
|
||||
if game.board.make_move_and_reset(mv, Color::Black) {
|
||||
println!("{:?}", mv)
|
||||
}
|
||||
}
|
||||
|
||||
let mut game = from_fen("rnbqkbnr/1ppppppp/p7/8/Q7/2P5/PP1PPPPP/RNB1KBNR w KQkq - 0 1")?;
|
||||
for mv in game.board.pseudo_moves_all(Color::Black) {
|
||||
if game.board.make_move_and_reset(mv, Color::Black) {
|
||||
println!("{:?}", mv)
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
37
src/game.rs
37
src/game.rs
@@ -78,26 +78,37 @@ impl State {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_castling_state(&mut self, square: u8, color: Color) {
|
||||
if square == 0 || square == 7 {
|
||||
match (color, self.get_castling_ability(color)) {
|
||||
(_, Castle::Both) => self.set_castling_ability(color, Castle::Long),
|
||||
(_, Castle::Short) => self.set_castling_ability(color, Castle::None),
|
||||
pub fn update_castling_state_quiet(&mut self, source: u8, color: Color) {
|
||||
self.update_castling_state_capture(source, color);
|
||||
|
||||
match (source, color) {
|
||||
(4, Color::White) => self.set_castling_ability(color, Castle::None),
|
||||
(60, Color::Black) => self.set_castling_ability(color, Castle::None),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_castling_state_capture(&mut self, target: u8, color: Color) {
|
||||
let (short_square, long_square) = match color {
|
||||
Color::White => (7, 0),
|
||||
Color::Black => (63, 56),
|
||||
};
|
||||
|
||||
if target == short_square {
|
||||
match self.get_castling_ability(color) {
|
||||
Castle::Both => self.set_castling_ability(color, Castle::Long),
|
||||
Castle::Short => self.set_castling_ability(color, Castle::None),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
if square == 56 || square == 63 {
|
||||
match (color, self.get_castling_ability(color)) {
|
||||
(_, Castle::Both) => self.set_castling_ability(color, Castle::Short),
|
||||
(_, Castle::Short) => self.set_castling_ability(color, Castle::None),
|
||||
if target == long_square {
|
||||
match self.get_castling_ability(color) {
|
||||
Castle::Both => self.set_castling_ability(color, Castle::Short),
|
||||
Castle::Long => self.set_castling_ability(color, Castle::None),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
if square == 4 || square == 60 {
|
||||
self.set_castling_ability(color, Castle::None)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn change_side(&mut self) {
|
||||
|
||||
@@ -50,7 +50,7 @@ fn white_pawn_quiet_moves(pawns: Bitboard, occupancies: Bitboard) -> Vec<Move> {
|
||||
let to = single_push_targets.trailing_zeros();
|
||||
let from = to - 8;
|
||||
|
||||
if from as u64 & 0xff000000000000 != 0 {
|
||||
if 1_u64 << from as u64 & 0xff000000000000 != 0 {
|
||||
moves.extend([
|
||||
Move::new_with_type(from, to, MoveType::Promotion(Promote::Knight)),
|
||||
Move::new_with_type(from, to, MoveType::Promotion(Promote::Bishop)),
|
||||
@@ -82,7 +82,7 @@ fn black_pawn_quiet_moves(pawns: Bitboard, occupancies: Bitboard) -> Vec<Move> {
|
||||
let to = single_push_targets.trailing_zeros();
|
||||
let from = to + 8;
|
||||
|
||||
if from as u64 & 0xff000000000000 != 0 {
|
||||
if 1_u64 << from as u64 & 0xff00 != 0 {
|
||||
moves.extend([
|
||||
Move::new_with_type(from, to, MoveType::Promotion(Promote::Knight)),
|
||||
Move::new_with_type(from, to, MoveType::Promotion(Promote::Bishop)),
|
||||
@@ -119,7 +119,7 @@ fn white_pawn_capture_moves(
|
||||
let from = w_pawns_capture_east.trailing_zeros();
|
||||
let to = from + 9;
|
||||
|
||||
if from as u64 & 0xff000000000000 != 0 {
|
||||
if 1_u64 << to as u64 & 0xff00000000000000 != 0 {
|
||||
moves.extend([
|
||||
Move::new_with_type(from, to, MoveType::PromotionCapture(Promote::Knight)),
|
||||
Move::new_with_type(from, to, MoveType::PromotionCapture(Promote::Bishop)),
|
||||
@@ -135,7 +135,7 @@ fn white_pawn_capture_moves(
|
||||
let from = w_pawns_capture_west.trailing_zeros();
|
||||
let to = from + 7;
|
||||
|
||||
if from as u64 & 0xff000000000000 != 0 {
|
||||
if 1_u64 << to as u64 & 0xff00000000000000 != 0 {
|
||||
moves.extend([
|
||||
Move::new_with_type(from, to, MoveType::PromotionCapture(Promote::Knight)),
|
||||
Move::new_with_type(from, to, MoveType::PromotionCapture(Promote::Bishop)),
|
||||
@@ -150,13 +150,14 @@ fn white_pawn_capture_moves(
|
||||
|
||||
if let Some(en_passant_square) = en_passant_square {
|
||||
let attacked_from = get_pawn_attacks(en_passant_square as usize, Color::Black);
|
||||
let result = attacked_from & pawns;
|
||||
if result != 0 {
|
||||
let mut result = attacked_from & pawns;
|
||||
while result != 0 {
|
||||
moves.push(Move::new_with_type(
|
||||
result.trailing_zeros(),
|
||||
en_passant_square as u32,
|
||||
MoveType::EnPassant,
|
||||
));
|
||||
result &= result - 1;
|
||||
}
|
||||
};
|
||||
moves
|
||||
@@ -174,7 +175,7 @@ fn black_pawn_capture_moves(
|
||||
while b_pawns_capture_east != 0 {
|
||||
let from = b_pawns_capture_east.trailing_zeros();
|
||||
let to = from - 7;
|
||||
if from as u64 & 0xff00 != 0 {
|
||||
if 1_u64 << to as u64 & 0xff != 0 {
|
||||
moves.extend([
|
||||
Move::new_with_type(from, to, MoveType::PromotionCapture(Promote::Knight)),
|
||||
Move::new_with_type(from, to, MoveType::PromotionCapture(Promote::Bishop)),
|
||||
@@ -190,7 +191,7 @@ fn black_pawn_capture_moves(
|
||||
while b_pawns_capture_west != 0 {
|
||||
let from = b_pawns_capture_west.trailing_zeros();
|
||||
let to = from - 9;
|
||||
if from as u64 & 0xff00 != 0 {
|
||||
if 1_u64 << to as u64 & 0xff != 0 {
|
||||
moves.extend([
|
||||
Move::new_with_type(from, to, MoveType::PromotionCapture(Promote::Knight)),
|
||||
Move::new_with_type(from, to, MoveType::PromotionCapture(Promote::Bishop)),
|
||||
@@ -205,13 +206,14 @@ fn black_pawn_capture_moves(
|
||||
|
||||
if let Some(en_passant_square) = en_passant_square {
|
||||
let attacked_from = get_pawn_attacks(en_passant_square as usize, Color::White);
|
||||
let result = attacked_from & pawns;
|
||||
if result != 0 {
|
||||
let mut result = attacked_from & pawns;
|
||||
while result != 0 {
|
||||
moves.push(Move::new_with_type(
|
||||
result.trailing_zeros(),
|
||||
en_passant_square as u32,
|
||||
MoveType::EnPassant,
|
||||
));
|
||||
result &= result - 1;
|
||||
}
|
||||
};
|
||||
moves
|
||||
@@ -373,11 +375,16 @@ fn king_castling_moves(board: &Board, color: Color, all_occupancies: Bitboard) -
|
||||
add_move_if_empty_path(path_short, king_to_short);
|
||||
add_move_if_empty_path(path_long, king_to_long);
|
||||
}
|
||||
(Castle::Both, Castle::Short) | (Castle::Short, Castle::Short) => {
|
||||
|
||||
(Castle::Both, Castle::Short)
|
||||
| (Castle::Short, Castle::Short)
|
||||
| (Castle::Short, Castle::Both) => {
|
||||
add_move_if_empty_path(path_short, king_to_short);
|
||||
}
|
||||
(Castle::Both, Castle::Long) | (Castle::Long, Castle::Long) => {
|
||||
add_move_if_empty_path(path_long, king_to_long)
|
||||
(Castle::Both, Castle::Long)
|
||||
| (Castle::Long, Castle::Long)
|
||||
| (Castle::Long, Castle::Both) => {
|
||||
add_move_if_empty_path(path_long, king_to_long);
|
||||
}
|
||||
_ => (),
|
||||
};
|
||||
@@ -386,7 +393,7 @@ fn king_castling_moves(board: &Board, color: Color, all_occupancies: Bitboard) -
|
||||
|
||||
fn king_and_adj_square_safety(board: &Board, color: Color) -> Castle {
|
||||
let (king_at, opponent_color) = match color {
|
||||
Color::White => (3, Color::Black),
|
||||
Color::White => (4, Color::Black),
|
||||
Color::Black => (60, Color::White),
|
||||
};
|
||||
|
||||
@@ -394,12 +401,12 @@ fn king_and_adj_square_safety(board: &Board, color: Color) -> Castle {
|
||||
return Castle::None;
|
||||
}
|
||||
|
||||
let short_attacked = board.is_attacked(king_at - 1, opponent_color);
|
||||
let long_attacked = board.is_attacked(king_at + 1, opponent_color);
|
||||
let short_attacked = board.is_attacked(king_at + 1, opponent_color);
|
||||
let long_attacked = board.is_attacked(king_at - 1, opponent_color);
|
||||
match (short_attacked, long_attacked) {
|
||||
(true, true) => Castle::None,
|
||||
(true, false) => Castle::Short,
|
||||
(false, true) => Castle::Long,
|
||||
(true, false) => Castle::Long,
|
||||
(false, true) => Castle::Short,
|
||||
(false, false) => Castle::Both,
|
||||
}
|
||||
}
|
||||
@@ -495,7 +502,7 @@ mod tests {
|
||||
];
|
||||
let mut actual = new_game.board.pseudo_moves(Color::White, Kind::Bishop);
|
||||
actual.sort();
|
||||
assert_eq!(expected, actual);
|
||||
assert_eq!(expected, actual);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -594,16 +601,4 @@ mod tests {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_random() -> Result<(), String> {
|
||||
init_attacks();
|
||||
let game = from_fen("rnbqkbnr/ppppp1pp/5p2/7Q/8/4P3/PPPP1PPP/RNB1KBNR w KQkq - 0 1")?;
|
||||
|
||||
for mv in game.board.pseudo_moves_all(Color::Black) {
|
||||
println!("{:?}", mv);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
196
src/perft.rs
196
src/perft.rs
@@ -1,14 +1,13 @@
|
||||
use crate::game::Game;
|
||||
|
||||
pub fn perft_driver(game: &mut Game, nodes: &mut u64, depth: u8) {
|
||||
pub fn driver(game: &mut Game, nodes: &mut u64, depth: u8) {
|
||||
if depth == 0 {
|
||||
*nodes += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
let pseudo_moves =
|
||||
game.board.pseudo_moves_all(game.board.state.next_turn());
|
||||
|
||||
let pseudo_moves = game.board.pseudo_moves_all(game.board.state.next_turn());
|
||||
|
||||
for mv in pseudo_moves {
|
||||
let original_board = game.board.clone();
|
||||
if !game.board.make_move(mv, game.board.state.next_turn()) {
|
||||
@@ -16,20 +15,22 @@ pub fn perft_driver(game: &mut Game, nodes: &mut u64, depth: u8) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// print_perftree(mv.source, mv.target, depth, nodes);
|
||||
print_perftree(mv.source, mv.target, depth, nodes);
|
||||
|
||||
perft_driver(game, nodes, depth - 1);
|
||||
driver(game, nodes, depth - 1);
|
||||
game.board = original_board;
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn print_perftree(source: u32, target: u32, depth: u8, nodes: &mut u64) {
|
||||
println!(
|
||||
"{}{} - depth: {}",
|
||||
square_to_notation(source as u8),
|
||||
square_to_notation(target as u8),
|
||||
depth
|
||||
);
|
||||
// println!(
|
||||
// "{}{} - depth: {} - nodes: {}",
|
||||
// square_to_notation(source as u8),
|
||||
// square_to_notation(target as u8),
|
||||
// depth,
|
||||
// nodes
|
||||
// );
|
||||
|
||||
if depth == MAX_DEPTH {
|
||||
println!(
|
||||
"{}{} {}",
|
||||
@@ -39,16 +40,15 @@ pub fn perft_driver(game: &mut Game, nodes: &mut u64, depth: u8) {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const MAX_DEPTH: u8 = 4;
|
||||
const MAX_DEPTH: u8 = 3;
|
||||
|
||||
pub fn perftree_script() {
|
||||
let fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
|
||||
let fen = "r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - 0 1";
|
||||
let mut game = crate::fen::from_fen(fen).unwrap();
|
||||
let (mut nodes, depth): (u64, u8) = (0, MAX_DEPTH);
|
||||
perft_driver(&mut game, &mut nodes, depth);
|
||||
driver(&mut game, &mut nodes, depth);
|
||||
println!();
|
||||
println!("{}", nodes)
|
||||
}
|
||||
@@ -81,7 +81,7 @@ pub fn square_to_notation(square: u8) -> &'static str {
|
||||
mod tests {
|
||||
use crate::{attack::init_attacks, fen::from_fen};
|
||||
|
||||
use super::perft_driver;
|
||||
use super::driver;
|
||||
|
||||
// Examples from https://www.chessprogramming.org/Perft_Results
|
||||
const FEN_PERFT: [&str; 6] = [
|
||||
@@ -93,164 +93,90 @@ mod tests {
|
||||
"r4rk1/1pp1qppp/p1np1n2/2b1p1B1/2B1P1b1/P1NP1N2/1PP1QPPP/R4RK1 w - - 0 10",
|
||||
];
|
||||
|
||||
#[test]
|
||||
fn test_perft_driver_1() -> Result<(), String> {
|
||||
fn perft(fen: &str, depth: u8) -> Result<u64, String> {
|
||||
init_attacks();
|
||||
|
||||
let mut game = from_fen(FEN_PERFT[0])?;
|
||||
let (mut nodes, depth): (u64, u8) = (0, 1);
|
||||
perft_driver(&mut game, &mut nodes, depth);
|
||||
assert_eq!(nodes , 20);
|
||||
let mut game = from_fen(fen)?;
|
||||
let mut nodes = 0;
|
||||
driver(&mut game, &mut nodes, depth);
|
||||
|
||||
let mut game = from_fen(FEN_PERFT[0])?;
|
||||
let (mut nodes, depth): (u64, u8) = (0, 2);
|
||||
perft_driver(&mut game, &mut nodes, depth);
|
||||
assert_eq!(nodes, 400);
|
||||
Ok(nodes)
|
||||
}
|
||||
|
||||
let mut game = from_fen(FEN_PERFT[0])?;
|
||||
let (mut nodes, depth): (u64, u8) = (0, 3);
|
||||
perft_driver(&mut game, &mut nodes, depth);
|
||||
assert_eq!(nodes, 8902);
|
||||
#[test]
|
||||
fn test_perft_1() -> Result<(), String> {
|
||||
init_attacks();
|
||||
|
||||
let mut game = from_fen(FEN_PERFT[0])?;
|
||||
let (mut nodes, depth): (u64, u8) = (0, 4);
|
||||
perft_driver(&mut game, &mut nodes, depth);
|
||||
assert_eq!(nodes, 197281);
|
||||
assert_eq!(perft(FEN_PERFT[0], 1)?, 20);
|
||||
assert_eq!(perft(FEN_PERFT[0], 2)?, 400);
|
||||
assert_eq!(perft(FEN_PERFT[0], 3)?, 8902);
|
||||
assert_eq!(perft(FEN_PERFT[0], 4)?, 197281);
|
||||
assert_eq!(perft(FEN_PERFT[0], 5)?, 4865609);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_perft_driver_2() -> Result<(), String> {
|
||||
fn test_perft_2() -> Result<(), String> {
|
||||
init_attacks();
|
||||
|
||||
let mut game = from_fen(FEN_PERFT[1])?;
|
||||
let (mut nodes, depth): (u64, u8) = (0, 1);
|
||||
perft_driver(&mut game, &mut nodes, depth);
|
||||
assert_eq!(nodes, 48);
|
||||
|
||||
let mut game = from_fen(FEN_PERFT[1])?;
|
||||
let (mut nodes, depth): (u64, u8) = (0, 2);
|
||||
perft_driver(&mut game, &mut nodes, depth);
|
||||
assert_eq!(nodes, 2039);
|
||||
|
||||
// let mut game = from_fen(FEN_PERFT[1])?;
|
||||
// let (mut nodes, depth): (u64, u8) = (0, 3);
|
||||
// perft_driver(&mut game, &mut nodes, depth);
|
||||
// assert_eq!(nodes, 97862);
|
||||
|
||||
// let mut game = from_fen(FEN_PERFT[1])?;
|
||||
// let (mut nodes, depth): (u64, u8) = (0, 4);
|
||||
// perft_driver(&mut game, &mut nodes, depth);
|
||||
// assert_eq!(nodes, 4085603);
|
||||
assert_eq!(perft(FEN_PERFT[1], 1)?, 48);
|
||||
assert_eq!(perft(FEN_PERFT[1], 2)?, 2039);
|
||||
assert_eq!(perft(FEN_PERFT[1], 3)?, 97862);
|
||||
assert_eq!(perft(FEN_PERFT[1], 4)?, 4085603);
|
||||
assert_eq!(perft(FEN_PERFT[1], 5)?, 193690690);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_perft_driver_3() -> Result<(), String> {
|
||||
fn test_perft_3() -> Result<(), String> {
|
||||
init_attacks();
|
||||
|
||||
// let mut game = from_fen(FEN_PERFT[2])?;
|
||||
// let (mut nodes, depth): (u64, u8) = (0, 1);
|
||||
// perft_driver(&mut game, &mut nodes, depth);
|
||||
// assert_eq!(nodes, 14);
|
||||
|
||||
// let mut game = from_fen(FEN_PERFT[2])?;
|
||||
// let (mut nodes, depth): (u64, u8) = (0, 2);
|
||||
// perft_driver(&mut game, &mut nodes, depth);
|
||||
// assert_eq!(nodes, 191);
|
||||
|
||||
// let mut game = from_fen(FEN_PERFT[2])?;
|
||||
// let (mut nodes, depth): (u64, u8) = (0, 3);
|
||||
// perft_driver(&mut game, &mut nodes, depth);
|
||||
// assert_eq!(nodes, 2812);
|
||||
|
||||
// let mut game = from_fen(FEN_PERFT[2])?;
|
||||
// let (mut nodes, depth): (u64, u8) = (0, 4);
|
||||
// perft_driver(&mut game, &mut nodes, depth);
|
||||
// assert_eq!(nodes, 43238);
|
||||
assert_eq!(perft(FEN_PERFT[2], 1)?, 14);
|
||||
assert_eq!(perft(FEN_PERFT[2], 2)?, 191);
|
||||
assert_eq!(perft(FEN_PERFT[2], 3)?, 2812);
|
||||
assert_eq!(perft(FEN_PERFT[2], 4)?, 43238);
|
||||
assert_eq!(perft(FEN_PERFT[2], 5)?, 674624);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_perft_driver_4() -> Result<(), String> {
|
||||
fn test_perft_4() -> Result<(), String> {
|
||||
init_attacks();
|
||||
|
||||
let mut game = from_fen(FEN_PERFT[3])?;
|
||||
let (mut nodes, depth): (u64, u8) = (0, 1);
|
||||
perft_driver(&mut game, &mut nodes, depth);
|
||||
assert_eq!(nodes , 6);
|
||||
|
||||
// let mut game = from_fen(FEN_PERFT[3])?;
|
||||
// let (mut nodes, depth): (u64, u8) = (0, 2);
|
||||
// perft_driver(&mut game, &mut nodes, depth);
|
||||
// assert_eq!(nodes, 264);
|
||||
|
||||
// let mut game = from_fen(FEN_PERFT[3])?;
|
||||
// let (mut nodes, depth): (u64, u8) = (0, 3);
|
||||
// perft_driver(&mut game, &mut nodes, depth);
|
||||
// assert_eq!(nodes, 9467);
|
||||
|
||||
// let mut game = from_fen(FEN_PERFT[3])?;
|
||||
// let (mut nodes, depth): (u64, u8) = (0, 4);
|
||||
// perft_driver(&mut game, &mut nodes, depth);
|
||||
// assert_eq!(nodes, 422333);
|
||||
assert_eq!(perft(FEN_PERFT[3], 1)?, 6);
|
||||
assert_eq!(perft(FEN_PERFT[3], 2)?, 264);
|
||||
assert_eq!(perft(FEN_PERFT[3], 3)?, 9467);
|
||||
assert_eq!(perft(FEN_PERFT[3], 4)?, 422333);
|
||||
assert_eq!(perft(FEN_PERFT[3], 5)?, 15833292);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_perft_driver_5() -> Result<(), String> {
|
||||
fn test_perft_5() -> Result<(), String> {
|
||||
init_attacks();
|
||||
|
||||
// let mut game = from_fen(FEN_PERFT[4])?;
|
||||
// let (mut nodes, depth): (u64, u8) = (0, 1);
|
||||
// perft_driver(&mut game, &mut nodes, depth);
|
||||
// assert_eq!(nodes , 44);
|
||||
|
||||
// let mut game = from_fen(FEN_PERFT[4])?;
|
||||
// let (mut nodes, depth): (u64, u8) = (0, 2);
|
||||
// perft_driver(&mut game, &mut nodes, depth);
|
||||
// assert_eq!(nodes, 1486);
|
||||
|
||||
// let mut game = from_fen(FEN_PERFT[4])?;
|
||||
// let (mut nodes, depth): (u64, u8) = (0, 3);
|
||||
// perft_driver(&mut game, &mut nodes, depth);
|
||||
// assert_eq!(nodes, 62379);
|
||||
|
||||
// let mut game = from_fen(FEN_PERFT[4])?;
|
||||
// let (mut nodes, depth): (u64, u8) = (0, 4);
|
||||
// perft_driver(&mut game, &mut nodes, depth);
|
||||
// assert_eq!(nodes, 2103487);
|
||||
assert_eq!(perft(FEN_PERFT[4], 1)?, 44);
|
||||
assert_eq!(perft(FEN_PERFT[4], 2)?, 1486);
|
||||
assert_eq!(perft(FEN_PERFT[4], 3)?, 62379);
|
||||
assert_eq!(perft(FEN_PERFT[4], 4)?, 2103487);
|
||||
assert_eq!(perft(FEN_PERFT[4], 5)?, 89941194);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_perft_driver_6() -> Result<(), String> {
|
||||
fn test_perft_6() -> Result<(), String> {
|
||||
init_attacks();
|
||||
|
||||
let mut game = from_fen(FEN_PERFT[5])?;
|
||||
let (mut nodes, depth): (u64, u8) = (0, 1);
|
||||
perft_driver(&mut game, &mut nodes, depth);
|
||||
assert_eq!(nodes , 46);
|
||||
|
||||
let mut game = from_fen(FEN_PERFT[5])?;
|
||||
let (mut nodes, depth): (u64, u8) = (0, 2);
|
||||
perft_driver(&mut game, &mut nodes, depth);
|
||||
assert_eq!(nodes, 2079);
|
||||
|
||||
let mut game = from_fen(FEN_PERFT[5])?;
|
||||
let (mut nodes, depth): (u64, u8) = (0, 3);
|
||||
perft_driver(&mut game, &mut nodes, depth);
|
||||
assert_eq!(nodes, 89890);
|
||||
|
||||
let mut game = from_fen(FEN_PERFT[5])?;
|
||||
let (mut nodes, depth): (u64, u8) = (0, 4);
|
||||
perft_driver(&mut game, &mut nodes, depth);
|
||||
assert_eq!(nodes, 3894594);
|
||||
assert_eq!(perft(FEN_PERFT[5], 1)?, 46);
|
||||
assert_eq!(perft(FEN_PERFT[5], 2)?, 2079);
|
||||
assert_eq!(perft(FEN_PERFT[5], 3)?, 89890);
|
||||
assert_eq!(perft(FEN_PERFT[5], 4)?, 3894594);
|
||||
assert_eq!(perft(FEN_PERFT[5], 5)?, 164075551);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user