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

View File

@@ -1,16 +1,16 @@
use u64 as Bitboard;
use crate::attack::{
use crate::board::bitboard::{have_common_bit, lsb};
use crate::board::state::State;
use crate::movegen::attack::{
fetch_bishop_attacks, fetch_king_attacks, fetch_knight_attacks, fetch_pawn_attacks,
fetch_queen_attacks, fetch_rook_attacks,
};
use crate::bitboard::{have_common_bit, lsb};
use crate::movegen::{
use crate::movegen::movegen::{
bishop_pseudo_moves, king_pseudo_moves, knight_pseudo_moves, pawn_pseudo_moves,
queen_pseudo_moves, rook_pseudo_moves,
};
use crate::r#move::Move;
use crate::state::State;
use crate::movegen::r#move::Move;
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct Board {
@@ -247,7 +247,7 @@ impl Color {
#[cfg(test)]
mod tests {
use crate::{attack::init_attacks, fen::from_fen};
use crate::{board::fen::from_fen, movegen::attack::init_attacks};
use super::*;

View File

@@ -1,6 +1,6 @@
use crate::board::{Board, Color, Piece, PieceType};
use crate::game::Game;
use crate::state::{Castle, State};
use crate::board::board::{Board, Color, Piece, PieceType};
use crate::board::game::Game;
use crate::board::state::{Castle, State};
use String as FenError;
pub fn from_fen(fen: &str) -> Result<Game, FenError> {

View File

@@ -1,6 +1,8 @@
use crate::{board::Board, fen::from_fen};
use crate::board::fen::from_fen;
use String as FenError;
use super::board::Board;
#[derive(Debug, PartialEq, Eq)]
pub struct Game {
pub board: Board,

6
src/board/mod.rs Normal file
View File

@@ -0,0 +1,6 @@
pub mod bitboard;
pub mod board;
pub mod fen;
pub mod game;
pub mod square;
pub mod state;

View File

@@ -1,6 +1,6 @@
use u64 as Bitboard;
use crate::bitboard::lsb;
use crate::board::bitboard::lsb;
pub struct Square {}
@@ -95,9 +95,3 @@ pub fn square_to_algebraic(square: usize) -> String {
format!("{}{}", (file + b'a') as char, (rank + b'1') as char)
}
impl Square {
pub const fn to_bitboard(square: usize) -> Bitboard {
1_u64 << square
}
}

View File

@@ -1,4 +1,4 @@
use crate::{board::Color, r#move::MoveType};
use crate::{board::board::Color, movegen::r#move::MoveType};
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub struct State {

View File

@@ -1,9 +1,9 @@
use u64 as Bitboard;
use crate::{
bitboard::lsb,
board::{Board, Color, PieceType},
psqt::{mirror_index, piece_square_score},
board::bitboard::lsb,
board::board::{Board, Color, PieceType},
evaluation::psqt::{mirror_index, piece_square_score},
};
const fn piece_score(piece_type: PieceType) -> i32 {
@@ -56,9 +56,9 @@ pub fn evaluate_position(board: &Board, color: Color) -> i32 {
#[cfg(test)]
mod tests {
use crate::{
board::{Color, PieceType},
evaluation::{evaluate_position, evaluate_side, piece_score},
fen::from_fen,
board::board::{Color, PieceType},
board::fen::from_fen,
evaluation::evaluation::{evaluate_position, evaluate_side, piece_score},
};
const FEN_QUIET: [&str; 2] = [

2
src/evaluation/mod.rs Normal file
View File

@@ -0,0 +1,2 @@
pub mod evaluation;
pub mod psqt;

View File

@@ -1,4 +1,4 @@
use crate::board::PieceType;
use crate::board::board::PieceType;
pub const fn piece_square_score(piece_type: PieceType, index: usize) -> i32 {
match piece_type {
@@ -113,9 +113,9 @@ const KING_ENDGAME_PSQT: [i32; 64] = [
#[cfg(test)]
mod tests {
use crate::{
board::PieceType,
psqt::{mirror_index, piece_square_score},
square::Square,
board::board::PieceType,
board::square::Square,
evaluation::psqt::{mirror_index, piece_square_score},
};
#[test]

1
src/interface/mod.rs Normal file
View File

@@ -0,0 +1 @@
pub mod uci;

View File

@@ -3,7 +3,7 @@ use std::{
str::SplitWhitespace,
};
use crate::{game::Game, r#move::Move, search::search, square::Square};
use crate::{board::game::Game, board::square::Square, movegen::r#move::Move, search::search};
#[derive(PartialEq, Eq, Debug)]
pub enum Command {
@@ -128,7 +128,7 @@ pub fn uci_go(go: &mut SplitWhitespace, game: &mut Game) -> Result<Move, String>
_ => (),
}
}
search(game, params.depth.unwrap_or(MAX_DEPTH));
search::search(game, params.depth.unwrap_or(MAX_DEPTH));
Ok(Move::new(Square::B8, Square::C6))
}
@@ -173,8 +173,8 @@ pub fn uci_loop() -> Result<(), String> {
#[cfg(test)]
mod tests {
use crate::{
fen::from_fen,
uci::{parse_command, Command},
board::fen::from_fen,
interface::uci::{parse_command, Command},
};
use super::uci_position;
@@ -217,3 +217,20 @@ mod tests {
Ok(())
}
}
/*
```
- CuteChess: `uci`
- Engine: `id name MyChessEngine`
- Engine: `id author John Doe`
- Engine: `option name Hash type spin default 32 min 1 max 512`
- Engine: `uciok`
- CuteChess: `setoption name Hash value 128`
- CuteChess: `ucinewgame`
- CuteChess: `position startpos moves e2e4 e7e5`
- CuteChess: `go wtime 600000 btime 600000 winc 0 binc 0`
- Engine: `info depth 1 score cp 20 nodes 15 nps 1500 time 10 pv e2e4`
- Engine: `bestmove e2e4`
- CuteChess: `quit`
```
*/

View File

@@ -1,26 +1,16 @@
pub mod attack;
pub mod bitboard;
pub mod board;
pub mod evaluation;
pub mod fen;
pub mod game;
pub mod magic;
pub mod r#move;
pub mod movegen;
pub mod perft;
pub mod psqt;
pub mod search;
pub mod square;
pub mod state;
pub mod uci;
mod board;
mod evaluation;
mod interface;
mod movegen;
mod search;
fn main() {
attack::init_attacks();
movegen::attack::init_attacks();
let command = std::env::args().nth(1).unwrap_or(String::from("quit"));
match command.as_str() {
"perft" => perft::perftree_script(),
"uci" => uci::uci_loop().unwrap_or_else(|e| println!("{}", e)),
"perft" => search::perft::perftree_script(),
"uci" => interface::uci::uci_loop().unwrap_or_else(|e| println!("{}", e)),
"quit" => println!("Exiting.."),
_ => println!("Wrong command. Exiting.."),
};

View File

@@ -1,4 +1,4 @@
use crate::{
use crate::board::{
bitboard::{
have_common_bit, lsb, square_to_bitboard, square_to_bitboard_wrapping, EMPTY, NOT_FILE_A,
NOT_FILE_AB, NOT_FILE_GH, NOT_FILE_H,
@@ -218,7 +218,7 @@ pub fn fetch_king_attacks(square: usize) -> Bitboard {
unsafe { KING_ATTACKS[square] }
}
use crate::magic::{BISHOP_MAGIC, ROOK_MAGIC};
use crate::movegen::magic::{BISHOP_MAGIC, ROOK_MAGIC};
pub fn fetch_bishop_attacks(mut occupancy: Bitboard, square: usize) -> Bitboard {
unsafe {
@@ -316,7 +316,7 @@ pub fn init_attacks() {
#[cfg(test)]
mod tests {
use super::*;
use crate::board::{Color, Piece, PieceType};
use crate::board::board::{Color, Piece, PieceType};
#[test]
fn test_pawn_attacks() -> Result<(), String> {

View File

@@ -1,9 +1,9 @@
use crate::attack::{
use crate::board::bitboard::{bit_count, square_to_bitboard, EMPTY, RANK_8};
use crate::board::square::Square;
use crate::movegen::attack::{
bishop_attacks_on_the_fly, mask_bishop_attacks, mask_rook_attacks, rook_attacks_on_the_fly,
set_occupancy, BISHOP_RELEVANT_BITS, ROOK_RELEVANT_BITS,
};
use crate::bitboard::{bit_count, square_to_bitboard, EMPTY, RANK_8};
use crate::square::Square;
use rand::rngs::SmallRng;
use rand::{RngCore, SeedableRng};
use u64 as Bitboard;
@@ -51,7 +51,7 @@ pub const BISHOP_MAGIC: [u64; 64] = [
0x4000000004208200, 0x804a10011602, 0x200a24c410041500, 0x8408080088061020,
];
pub fn random_uint64(state: &mut SmallRng) -> u64 {
fn random_uint64(state: &mut SmallRng) -> u64 {
let n1 = state.next_u32() as u64 & 0xffff;
let n2 = state.next_u32() as u64 & 0xffff;
let n3 = state.next_u32() as u64 & 0xffff;
@@ -60,11 +60,11 @@ pub fn random_uint64(state: &mut SmallRng) -> u64 {
n1 | (n2 << (16)) | (n3 << (32)) | (n4 << (48))
}
pub fn generate_magic_number_candidate(state: &mut SmallRng) -> u64 {
fn generate_magic_number_candidate(state: &mut SmallRng) -> u64 {
random_uint64(state) & random_uint64(state) & random_uint64(state)
}
pub fn init_magic_arrays() {
fn init_magic_arrays() {
let mut state = SmallRng::seed_from_u64(1804289383);
for square in Square::A1..=Square::H8 {
@@ -93,7 +93,7 @@ pub fn init_magic_arrays() {
}
}
pub fn find_magic_numbers<F1, F2>(
fn find_magic_numbers<F1, F2>(
relevant_bits: usize,
bitboard: Bitboard,
state: &mut SmallRng,
@@ -125,7 +125,7 @@ where
)
}
pub fn generate_magic_number(
fn generate_magic_number(
relevant_bits: usize,
state: &mut SmallRng,
attack_mask: u64,
@@ -165,8 +165,8 @@ pub fn generate_magic_number(
mod tests {
use super::init_magic_arrays;
use crate::{
magic::{BISHOP_MAGIC, BISHOP_MAGIC_INIT, ROOK_MAGIC, ROOK_MAGIC_INIT},
square::Square,
board::square::Square,
movegen::magic::{BISHOP_MAGIC, BISHOP_MAGIC_INIT, ROOK_MAGIC, ROOK_MAGIC_INIT},
};
#[test]

4
src/movegen/mod.rs Normal file
View File

@@ -0,0 +1,4 @@
pub mod attack;
pub mod magic;
pub mod r#move;
pub mod movegen;

View File

@@ -1,6 +1,6 @@
use core::fmt;
use crate::{
use crate::board::{
bitboard::{have_common_bit, square_to_bitboard},
board::{Board, Color, Piece, PieceType},
square::{coords_to_square, square_to_algebraic, Square},
@@ -112,8 +112,6 @@ impl Board {
self.update_board_state(mv, color);
}
pub fn unmake_move(&mut self) {}
pub fn update_board_state(&mut self, mv: &Move, color: Color) {
let (own_pieces, opponent_pieces, en_passant_square) = match color {
Color::White => (
@@ -227,12 +225,8 @@ impl Board {
#[cfg(test)]
mod tests {
use crate::{
board::Color,
fen::from_fen,
r#move::{Move, MoveType, Promote},
square::Square,
};
use crate::board::{board::Color, fen::from_fen, square::Square};
use crate::movegen::r#move::{Move, MoveType, Promote};
const FEN_QUIET: [&str; 2] = [
"r3k2r/2p1p1qp/2npb3/1p3p2/p3P1pP/P1PB1Q2/1P1PNPP1/R3K2R w KQkq - 0 1",

View File

@@ -1,14 +1,14 @@
use crate::attack::{
fetch_bishop_attacks, fetch_king_attacks, fetch_knight_attacks, fetch_pawn_attacks,
fetch_queen_attacks, fetch_rook_attacks,
};
use crate::bitboard::{
use crate::board::bitboard::{
have_common_bit, lsb, square_to_bitboard, NOT_FILE_A, NOT_FILE_H, RANK_1, RANK_2, RANK_4,
RANK_5, RANK_7, RANK_8,
};
use crate::board::{Board, Color};
use crate::r#move::{Move, MoveType, Promote};
use crate::state::Castle;
use crate::board::board::{Board, Color};
use crate::board::state::Castle;
use crate::movegen::attack::{
fetch_bishop_attacks, fetch_king_attacks, fetch_knight_attacks, fetch_pawn_attacks,
fetch_queen_attacks, fetch_rook_attacks,
};
use crate::movegen::r#move::{Move, MoveType, Promote};
use u64 as Bitboard;
pub fn pawn_pseudo_moves(
@@ -399,10 +399,10 @@ fn king_and_adj_square_safety(board: &Board, color: Color) -> Castle {
#[cfg(test)]
mod tests {
use crate::{attack::init_attacks, fen::from_fen};
use crate::{board::fen::from_fen, movegen::attack::init_attacks};
use super::*;
use crate::board::PieceType;
use crate::board::board::PieceType;
const FEN_PAWN_MOVES: &str = "r1bqk2r/p4pbp/1pnp1np1/P3P1B1/3NNP2/8/1PP3PP/R2QKB1R w - - 0 1";

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

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

View File

@@ -1,4 +1,4 @@
use crate::game::Game;
use crate::board::game::Game;
pub fn driver(game: &mut Game, nodes: &mut u64, depth: u8) {
if depth == 0 {
@@ -12,7 +12,7 @@ pub fn driver(game: &mut Game, nodes: &mut u64, depth: u8) {
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;
@@ -27,7 +27,7 @@ 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::fen::from_fen(fen).expect("Invalid FEN string");
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);
}
@@ -35,7 +35,7 @@ pub fn perftree_script() {
use std::collections::HashMap;
#[rustfmt::skip]
pub fn square_to_notation(square: u8) -> &'static str {
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");
@@ -58,7 +58,7 @@ pub fn square_to_notation(square: u8) -> &'static str {
#[cfg(test)]
mod tests {
use crate::{attack::init_attacks, fen::from_fen};
use crate::{board::fen::from_fen, movegen::attack::init_attacks};
use super::driver;

View File

@@ -1,4 +1,4 @@
use crate::game::Game;
use crate::board::game::Game;
pub fn search(game: &mut Game, depth: u8) {
if depth == 0 {
@@ -11,7 +11,7 @@ pub fn search(game: &mut Game, depth: u8) {
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;
@@ -21,3 +21,22 @@ pub fn search(game: &mut Game, depth: u8) {
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(())
}
}