Skip to content

Commit

Permalink
Everything changed.
Browse files Browse the repository at this point in the history
This overhauls the way MoveTable is used by boxing it in a new struct
NoArc. NoArc is a thread-safe way to read a block of memory. Essentially
every file in the engine had to change, because essentially every file
used GameManager or MoveTable in some way. It shouldn't be too horrible
to sort through, though!
  • Loading branch information
ethanbarry committed Nov 25, 2024
1 parent 9dd6cb5 commit 2a7943c
Show file tree
Hide file tree
Showing 12 changed files with 148 additions and 202 deletions.
170 changes: 60 additions & 110 deletions src/gamemanager/legal_moves.rs

Large diffs are not rendered by default.

26 changes: 8 additions & 18 deletions src/gamemanager/legal_moves/perft.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,13 @@
use crate::types::Move;

use super::GameManager;
use super::{GameManager, MoveTable, NoArc};
use rayon::prelude::*;

pub fn perft(depth: u16, maxdepth: u16, mv: Move, gm: GameManager) {
if depth > maxdepth {
return;
}
let mvlst = gm.legal_moves();
let count = mvlst.iter().count();
pub fn perft(depth: u16, maxdepth: u16, gm: GameManager, tbl: &NoArc<MoveTable>) -> u64 {
if depth == maxdepth {
//let s = format!("{}{}: ", mv.1.to_str(), mv.2.to_str()).to_ascii_lowercase();
//println!("{}", s);
//eprintln!("MOVE AT DEPTH {depth}");
//println!("{s}{}", mvlst.iter().count());
1
} else {
gm.legal_moves(tbl)
.into_par_iter()
.map(|mv| perft(depth + 1, maxdepth, mv.4, tbl))
.sum::<u64>()
}
mvlst
.into_par_iter()
.for_each(|(pc, from, to, mvtp, modgm)| {
perft(depth + 1, maxdepth, (pc, from, to, mvtp.clone()), modgm)
});
}
27 changes: 12 additions & 15 deletions src/gamemanager/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
#![allow(dead_code, unused_variables, unused_mut)]
use std::sync::LazyLock;

use crate::{
bitboard,
movetable::MoveTable,
movetable::{noarc::NoArc, MoveTable},
types::{CastlingRecord, Color},
MOVETABLE,
};
use bitboard::BitBoard;
use pseudolegal_moves::pseudolegal_moves;
Expand Down Expand Up @@ -33,7 +29,6 @@ pub struct GameManager {
* fullmove number - number of completed turns (increment when black moves)
*/
pub bitboard: BitBoard,
pub movetable: &'static LazyLock<MoveTable>,
pub white_to_move: bool,
pub castling_rights: CastlingRecord,
pub en_passant_target: String,
Expand All @@ -42,11 +37,10 @@ pub struct GameManager {
}

impl Default for GameManager {
/// Constructs a new `GameManager`, set to Chess's starting position
/// Constructs a new `GameManager` set to startpos.
fn default() -> Self {
GameManager {
bitboard: BitBoard::default(),
movetable: &MOVETABLE,
white_to_move: true,
castling_rights: CastlingRecord::default(),
en_passant_target: String::new(),
Expand All @@ -60,13 +54,12 @@ impl GameManager {
/// A utility method for generating a new `GameManager` from a FEN string\
/// * `fen` - a `&str` representing a game's state in FEN
/// * `returns` - a `GameManager` as generated from the FEN
pub fn from_fen_string(fen: &str) -> Self {
pub fn from_fen_str(fen: &str) -> Self {
if Self::is_valid_fen(fen) {
let tokens: Vec<String> = fen.split_whitespace().map(str::to_string).collect();
GameManager {
//board space validation implemented at higher level (is_valid_fen())
bitboard: BitBoard::from_fen_string(&tokens[0]),
movetable: &MOVETABLE,
white_to_move: tokens[1] == "w",
castling_rights: CastlingRecord::try_from(tokens[2].as_str())
.expect("We expect FEN strings to be well-formed."),
Expand Down Expand Up @@ -151,15 +144,15 @@ impl GameManager {
}

/// Returns a bitmask of all the pieces attacked by the given color on this GameManager's state.
pub fn attacked_by(&self, color: Color) -> u64 {
pub fn attacked_by(&self, tbl: &NoArc<MoveTable>, color: Color) -> u64 {
let moves = pseudolegal_moves(
color,
self.bitboard,
&MOVETABLE,
self.castling_rights,
&self.en_passant_target,
self.halfmoves,
self.fullmoves,
tbl,
);

moves
Expand All @@ -172,19 +165,23 @@ impl GameManager {
#[cfg(test)]
mod test {
use super::GameManager;
use crate::{gamemanager::pseudolegal_moves::*, types::Color};
use crate::{
gamemanager::pseudolegal_moves::*,
movetable::{noarc::NoArc, MoveTable},
types::Color,
};

#[test]
fn check_psl_moves_1() {
let game_manager = GameManager::default();
let moves = pseudolegal_moves(
Color::Black,
game_manager.bitboard,
&game_manager.movetable,
game_manager.castling_rights,
&game_manager.en_passant_target,
game_manager.halfmoves,
game_manager.fullmoves,
&NoArc::new(MoveTable::default()),
);

assert_eq!(
Expand All @@ -199,11 +196,11 @@ mod test {
let moves = pseudolegal_moves(
Color::White,
game_manager.bitboard,
&game_manager.movetable,
game_manager.castling_rights,
&game_manager.en_passant_target,
game_manager.halfmoves,
game_manager.fullmoves,
&NoArc::new(MoveTable::default()),
);

assert_eq!(
Expand Down
15 changes: 11 additions & 4 deletions src/gamemanager/pseudolegal_moves/bishops.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use crate::{movetable::MoveTable, types::*};
use crate::{
movetable::{noarc::NoArc, MoveTable},
types::*,
};

/// Returns all pseudolegal moves the knights can make from their positions.
/// ## Inputs
Expand Down Expand Up @@ -41,10 +44,10 @@ use crate::{movetable::MoveTable, types::*};
/// ```
pub fn pseudolegal_bishop_moves(
color: Color,
movetable: &MoveTable,
bishop_locations: Vec<u64>,
friendly_pieces: u64,
enemy_pieces: u64,
movetable: &NoArc<MoveTable>,
) -> Vec<(PieceType, Square, Square, MoveType)> {
let mut bishop_pseudo_legal_moves = Vec::new();

Expand Down Expand Up @@ -88,17 +91,21 @@ pub fn pseudolegal_bishop_moves(

#[cfg(test)]
mod test {
use crate::{gamemanager::pseudolegal_moves::bishops, movetable::MoveTable, types::*};
use crate::{
gamemanager::pseudolegal_moves::bishops,
movetable::{noarc::NoArc, MoveTable},
types::*,
};
use std::collections::HashSet;

#[test]
fn check_bishop_pslm() {
let pslnm = bishops::pseudolegal_bishop_moves(
Color::Black,
&MoveTable::default(),
vec![0x20000000_00000000],
0xFFAF5000_00000000,
0xFFFF,
&NoArc::new(MoveTable::default()),
);
let moves: HashSet<u64> = HashSet::from_iter(
vec![
Expand Down
19 changes: 13 additions & 6 deletions src/gamemanager/pseudolegal_moves/kings.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use crate::{movetable::MoveTable, types::*};
use crate::{
movetable::{noarc::NoArc, MoveTable},
types::*,
};

/// Returns all pseudolegal moves the kings can make from their positions.
/// ## Inputs
Expand Down Expand Up @@ -43,12 +46,12 @@ use crate::{movetable::MoveTable, types::*};
/// ```
pub fn pseudolegal_king_moves(
color: Color,
movetable: &MoveTable,
king_locations: Vec<u64>,
friendly_pieces: u64,
friendly_rooks: u64,
enemy_pieces: u64,
castling_rights: CastlingRecord,
movetable: &NoArc<MoveTable>,
) -> Vec<Move> {
let mut king_pseudo_legal_moves = Vec::new();

Expand Down Expand Up @@ -190,15 +193,18 @@ pub fn pseudolegal_king_moves(

#[cfg(test)]
mod tests {
use crate::{gamemanager::pseudolegal_moves::kings, movetable::MoveTable, types::*};
use crate::{
gamemanager::pseudolegal_moves::kings,
movetable::{noarc::NoArc, MoveTable},
types::*,
};
use std::collections::HashSet;
use Square::*;

#[test]
fn check_king_pslm() {
let pslnm = kings::pseudolegal_king_moves(
Color::Black,
&MoveTable::default(),
vec![B5.to_u64()],
0,
0,
Expand All @@ -207,6 +213,7 @@ mod tests {
black: CastlingRights::Neither,
white: CastlingRights::Neither,
},
&NoArc::new(MoveTable::default()),
);
let moves: HashSet<u64> = HashSet::from_iter(
vec![
Expand All @@ -230,7 +237,6 @@ mod tests {
fn check_black_king_pslm_castling() {
let pslnm = kings::pseudolegal_king_moves(
Color::Black,
&MoveTable::default(),
vec![E8.to_u64()],
0,
Square::A8.to_u64() | Square::H8.to_u64(),
Expand All @@ -239,6 +245,7 @@ mod tests {
black: CastlingRights::Both,
white: CastlingRights::Neither,
},
&NoArc::new(MoveTable::default()),
);
let moves: HashSet<u64> = HashSet::from_iter(
vec![
Expand All @@ -262,7 +269,6 @@ mod tests {
fn check_white_king_pslm_castling() {
let pslnm = kings::pseudolegal_king_moves(
Color::White,
&MoveTable::default(),
vec![E1.to_u64()],
0,
Square::A1.to_u64() | Square::H1.to_u64(),
Expand All @@ -271,6 +277,7 @@ mod tests {
black: CastlingRights::Neither,
white: CastlingRights::Both,
},
&NoArc::new(MoveTable::default()),
);
let moves: HashSet<u64> = HashSet::from_iter(
vec![
Expand Down
10 changes: 7 additions & 3 deletions src/gamemanager/pseudolegal_moves/knights.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use crate::{movetable::MoveTable, types::*};
use crate::{
movetable::{noarc::NoArc, MoveTable},
types::*,
};

/// Returns all pseudolegal moves the knights can make from their positions.
/// ## Inputs
Expand Down Expand Up @@ -29,10 +32,10 @@ use crate::{movetable::MoveTable, types::*};
/// ```
pub fn pseudolegal_knight_moves(
color: Color,
movetable: &MoveTable,
knight_locations: Vec<u64>,
friendly_pieces: u64,
enemy_pieces: u64,
movetable: &NoArc<MoveTable>,
) -> Vec<Move> {
let mut knight_pseudo_legal_moves = Vec::new();

Expand Down Expand Up @@ -73,17 +76,18 @@ pub fn pseudolegal_knight_moves(
#[cfg(test)]
mod tests {
use crate::gamemanager::pseudolegal_moves::knights;
use crate::movetable::noarc::NoArc;
use crate::{movetable::MoveTable, types::*};
use std::collections::HashSet;

#[test]
fn check_knight_pslm() {
let pslnm = knights::pseudolegal_knight_moves(
Color::Black,
&MoveTable::default(),
vec![0x40000000_00000000],
0xFFFF0000_00000000,
0xFFFF,
&NoArc::new(MoveTable::default()),
);
let moves: HashSet<u64> = HashSet::from_iter(
vec![0x00008000_00000000, 0x00002000_00000000]
Expand Down
Loading

0 comments on commit 2a7943c

Please sign in to comment.