Refactor project structure to use submodules

This commit is contained in:
stefiosif
2024-08-14 21:58:20 +03:00
parent 69cabd5b58
commit ed711f905d
21 changed files with 121 additions and 89 deletions

3
src/search/mod.rs Normal file
View File

@@ -0,0 +1,3 @@
pub mod move_ordering;
pub mod perft;
pub mod search;

138
src/search/perft.rs Normal file
View 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
View 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(())
}
}