Skip to content

Commit

Permalink
DFRC Support (#33)
Browse files Browse the repository at this point in the history
Bench: 2726116
  • Loading branch information
jw1912 authored Mar 26, 2024
1 parent 1a80f04 commit 2f79e63
Show file tree
Hide file tree
Showing 11 changed files with 230 additions and 126 deletions.
25 changes: 0 additions & 25 deletions monty-core/src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,33 +42,8 @@ impl Right {
pub const WKS: u8 = 0b0100;
pub const BQS: u8 = 0b0010;
pub const BKS: u8 = 0b0001;
pub const TABLE: [[u8; 2]; 2] = [[Self::WQS, Self::WKS], [Self::BQS, Self::BKS]];
}

// paths required to be clear for castling
pub struct Path;
impl Path {
pub const BD1: u64 = 0x0000_0000_0000_000E;
pub const FG1: u64 = 0x0000_0000_0000_0060;
pub const BD8: u64 = 0x0E00_0000_0000_0000;
pub const FG8: u64 = 0x6000_0000_0000_0000;
pub const TABLE: [[u64; 2]; 2] = [[Self::BD1, Self::FG1], [Self::BD8, Self::FG8]];
}

// the castling rook move bitboards
pub const ROOK_MOVES: [[(u8, u8); 2]; 2] = [[(0, 3), (56, 59)], [(7, 5), (63, 61)]];

// mask off castling rights by square
pub const CASTLE_MASK: [u8; 64] = init!(|idx, 64| match idx {
0 => 7,
4 => 3,
7 => 11,
56 => 13,
60 => 12,
63 => 14,
_ => 15,
});

// for promotions / double pushes
pub struct Rank;
impl Rank {
Expand Down
89 changes: 89 additions & 0 deletions monty-core/src/frc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
use crate::{
consts::{Piece, Right, Side},
position::Position,
};

#[derive(Clone, Copy)]
pub struct Castling {
chess960: bool,
castle_mask: [u8; 64],
rook_files: [[u8; 2]; 2],
}

impl Default for Castling {
fn default() -> Self {
Self {
chess960: false,
castle_mask: [0; 64],
rook_files: [[0; 2]; 2],
}
}
}

impl Castling {
pub fn is_chess960(&self) -> bool {
self.chess960
}

pub fn mask(&self, sq: usize) -> u8 {
self.castle_mask[sq]
}

pub fn rook_file(&self, side: usize, ks: usize) -> u8 {
self.rook_files[side][ks]
}

pub fn parse(&mut self, pos: &Position, rights_str: &str) -> u8 {
let mut kings = [4, 4];

self.chess960 = false;
self.rook_files[0][0] = 0;
self.rook_files[0][1] = 7;
self.rook_files[1][0] = 0;
self.rook_files[1][1] = 7;

let rights = rights_str.chars().fold(0, |cr, ch| {
cr | match ch as u8 {
b'Q' => Right::WQS,
b'K' => Right::WKS,
b'q' => Right::BQS,
b'k' => Right::BKS,
b'A'..=b'H' => self.parse_castle(pos, Side::WHITE, &mut kings, ch),
b'a'..=b'h' => self.parse_castle(pos, Side::BLACK, &mut kings, ch),
_ => 0,
}
});

for sq in self.castle_mask.iter_mut() {
*sq = 15;
}

self.castle_mask[usize::from(self.rook_file(0, 0))] = 7;
self.castle_mask[usize::from(self.rook_file(0, 1))] = 11;
self.castle_mask[usize::from(self.rook_file(1, 0)) + 56] = 13;
self.castle_mask[usize::from(self.rook_file(1, 1)) + 56] = 14;
self.castle_mask[kings[0]] = 3;
self.castle_mask[kings[1] + 56] = 12;

rights
}

fn parse_castle(
&mut self,
pos: &Position,
side: usize,
kings: &mut [usize; 2],
ch: char,
) -> u8 {
self.chess960 = true;

let wkc = (pos.piece(side) & pos.piece(Piece::KING)).trailing_zeros() as u8 & 7;
kings[side] = wkc as usize;
let rook = ch as u8 - [b'A', b'a'][side];
let i = usize::from(rook > wkc);

self.rook_files[side][i] = rook;

[[Right::WQS, Right::WKS], [Right::BQS, Right::BKS]][side][i]
}
}
2 changes: 2 additions & 0 deletions monty-core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
mod attacks;
mod consts;
mod frc;
mod moves;
mod policy;
mod position;
mod value;

pub use consts::{Flag, Piece, Side};
pub use frc::Castling;
pub use moves::{Move, MoveList};
pub use policy::{PolicyNetwork, POLICY_NETWORK, SubNet};
pub use position::{perft, GameState, Position};
Expand Down
15 changes: 11 additions & 4 deletions monty-core/src/moves.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{consts::Flag, position::Position, PolicyNetwork};
use crate::{consts::Flag, frc::Castling, position::Position, PolicyNetwork};

#[macro_export]
macro_rules! pop_lsb {
Expand Down Expand Up @@ -101,15 +101,22 @@ impl Move {
}
}

#[must_use]
pub fn to_uci(self) -> String {
pub fn to_uci(self, castling: &Castling) -> String {
let idx_to_sq = |i| format!("{}{}", ((i & 7) + b'a') as char, (i / 8) + 1);
let promo = if self.flag & 0b1000 > 0 {
["n", "b", "r", "q"][(self.flag & 0b11) as usize]
} else {
""
};
format!("{}{}{}", idx_to_sq(self.from), idx_to_sq(self.to), promo)

let to = if castling.is_chess960() && [Flag::QS, Flag::KS].contains(&self.flag) {
let sf = 56 * (self.to / 56);
sf + castling.rook_file(usize::from(sf > 0), usize::from(self.flag == Flag::KS))
} else {
self.to
};

format!("{}{}{}", idx_to_sq(self.from), idx_to_sq(to), promo)
}
}

Expand Down
Loading

0 comments on commit 2f79e63

Please sign in to comment.