Refactor project structure to use submodules
This commit is contained in:
3
src/search/mod.rs
Normal file
3
src/search/mod.rs
Normal file
@@ -0,0 +1,3 @@
|
||||
pub mod move_ordering;
|
||||
pub mod perft;
|
||||
pub mod search;
|
||||
138
src/search/perft.rs
Normal file
138
src/search/perft.rs
Normal file
@@ -0,0 +1,138 @@
|
||||
use crate::board::game::Game;
|
||||
|
||||
pub fn driver(game: &mut Game, nodes: &mut u64, depth: u8) {
|
||||
if depth == 0 {
|
||||
*nodes += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
let color = game.board.state.next_turn();
|
||||
let pseudo_moves = game.board.pseudo_moves_all(color);
|
||||
|
||||
for mv in pseudo_moves {
|
||||
let original_board = game.board.clone();
|
||||
game.board.make_move(&mv, color);
|
||||
|
||||
if game.board.king_under_check(color) {
|
||||
game.board = original_board;
|
||||
continue;
|
||||
}
|
||||
|
||||
driver(game, nodes, depth - 1);
|
||||
game.board = original_board;
|
||||
}
|
||||
}
|
||||
|
||||
const MAX_DEPTH: u8 = 3;
|
||||
|
||||
pub fn perftree_script() {
|
||||
let fen = "r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - 0 1";
|
||||
let mut game = crate::board::fen::from_fen(fen).expect("Invalid FEN string");
|
||||
let (mut nodes, depth): (u64, u8) = (0, MAX_DEPTH);
|
||||
driver(&mut game, &mut nodes, depth);
|
||||
}
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub fn _square_to_notation(square: u8) -> &'static str {
|
||||
let mut map: HashMap<u8, &str> = HashMap::new();
|
||||
map.insert(0, "a1"); map.insert(1, "b1"); map.insert(2, "c1"); map.insert(3, "d1");
|
||||
map.insert(4, "e1"); map.insert(5, "f1"); map.insert(6, "g1"); map.insert(7, "h1");
|
||||
map.insert(8, "a2"); map.insert(9, "b2"); map.insert(10, "c2"); map.insert(11, "d2");
|
||||
map.insert(12, "e2"); map.insert(13, "f2"); map.insert(14, "g2"); map.insert(15, "h2");
|
||||
map.insert(16, "a3"); map.insert(17, "b3"); map.insert(18, "c3"); map.insert(19, "d3");
|
||||
map.insert(20, "e3"); map.insert(21, "f3"); map.insert(22, "g3"); map.insert(23, "h3");
|
||||
map.insert(24, "a4"); map.insert(25, "b4"); map.insert(26, "c4"); map.insert(27, "d4");
|
||||
map.insert(28, "e4"); map.insert(29, "f4"); map.insert(30, "g4"); map.insert(31, "h4");
|
||||
map.insert(32, "a5"); map.insert(33, "b5"); map.insert(34, "c5"); map.insert(35, "d5");
|
||||
map.insert(36, "e5"); map.insert(37, "f5"); map.insert(38, "g5"); map.insert(39, "h5");
|
||||
map.insert(40, "a6"); map.insert(41, "b6"); map.insert(42, "c6"); map.insert(43, "d6");
|
||||
map.insert(44, "e6"); map.insert(45, "f6"); map.insert(46, "g6"); map.insert(47, "h6");
|
||||
map.insert(48, "a7"); map.insert(49, "b7"); map.insert(50, "c7"); map.insert(51, "d7");
|
||||
map.insert(52, "e7"); map.insert(53, "f7"); map.insert(54, "g7"); map.insert(55, "h7");
|
||||
map.insert(56, "a8"); map.insert(57, "b8"); map.insert(58, "c8"); map.insert(59, "d8");
|
||||
map.insert(60, "e8"); map.insert(61, "f8"); map.insert(62, "g8"); map.insert(63, "h8");
|
||||
map.get(&square).expect("Invalid square")
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{board::fen::from_fen, movegen::attack::init_attacks};
|
||||
|
||||
use super::driver;
|
||||
|
||||
// Examples from https://www.chessprogramming.org/Perft_Results
|
||||
const FEN_PERFT: [&str; 6] = [
|
||||
"rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
|
||||
"r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - 0 1",
|
||||
"8/2p5/3p4/KP5r/1R3p1k/8/4P1P1/8 w - - 0 1",
|
||||
"r3k2r/Pppp1ppp/1b3nbN/nP6/BBP1P3/q4N2/Pp1P2PP/R2Q1RK1 w kq - 0 1",
|
||||
"rnbq1k1r/pp1Pbppp/2p5/8/2B5/8/PPP1NnPP/RNBQK2R w KQ - 1 8",
|
||||
"r4rk1/1pp1qppp/p1np1n2/2b1p1B1/2B1P1b1/P1NP1N2/1PP1QPPP/R4RK1 w - - 0 10",
|
||||
];
|
||||
|
||||
fn perft(fen: &str, depth: u8) -> Result<u64, String> {
|
||||
init_attacks();
|
||||
|
||||
let mut game = from_fen(fen)?;
|
||||
let mut nodes = 0;
|
||||
driver(&mut game, &mut nodes, depth);
|
||||
|
||||
Ok(nodes)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_perft_1() -> Result<(), String> {
|
||||
init_attacks();
|
||||
|
||||
assert_eq!(perft(FEN_PERFT[0], 5)?, 4865609);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_perft_2() -> Result<(), String> {
|
||||
init_attacks();
|
||||
|
||||
assert_eq!(perft(FEN_PERFT[1], 5)?, 193690690);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_perft_3() -> Result<(), String> {
|
||||
init_attacks();
|
||||
|
||||
assert_eq!(perft(FEN_PERFT[2], 5)?, 674624);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_perft_4() -> Result<(), String> {
|
||||
init_attacks();
|
||||
|
||||
assert_eq!(perft(FEN_PERFT[3], 5)?, 15833292);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_perft_5() -> Result<(), String> {
|
||||
init_attacks();
|
||||
|
||||
assert_eq!(perft(FEN_PERFT[4], 5)?, 89941194);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_perft_6() -> Result<(), String> {
|
||||
init_attacks();
|
||||
|
||||
assert_eq!(perft(FEN_PERFT[5], 5)?, 164075551);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
42
src/search/search.rs
Normal file
42
src/search/search.rs
Normal file
@@ -0,0 +1,42 @@
|
||||
use crate::board::game::Game;
|
||||
|
||||
pub fn search(game: &mut Game, depth: u8) {
|
||||
if depth == 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
let color = game.board.state.next_turn();
|
||||
let pseudo_moves = game.board.pseudo_moves_all(color);
|
||||
|
||||
for mv in pseudo_moves {
|
||||
let original_board = game.board.clone();
|
||||
game.board.make_move(&mv, color);
|
||||
|
||||
if game.board.king_under_check(color) {
|
||||
game.board = original_board;
|
||||
continue;
|
||||
}
|
||||
|
||||
search(game, depth - 1);
|
||||
game.board = original_board;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::board::fen::from_fen;
|
||||
|
||||
const FEN_QUIET: [&str; 2] = [
|
||||
"rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
|
||||
"rnbqkbnr/ppp2ppp/4p3/3pN3/3P4/8/PPP1PPPP/RNBQKB1R w KQkq - 0 1",
|
||||
];
|
||||
|
||||
#[test]
|
||||
fn test_search() -> Result<(), String> {
|
||||
let _game = from_fen(FEN_QUIET[0])?;
|
||||
|
||||
//TODO:
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user