Skip to content

Commit

Permalink
EnumMap
Browse files Browse the repository at this point in the history
  • Loading branch information
Heiaha committed Dec 4, 2024
1 parent 25b6f35 commit 6723103
Show file tree
Hide file tree
Showing 14 changed files with 282 additions and 160 deletions.
31 changes: 16 additions & 15 deletions src/attacks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ use super::bitboard::*;
use super::magics::*;
use super::piece::*;
use super::square::*;
use crate::types::*;

#[rustfmt::skip]
const KNIGHT_ATTACKS: [Bitboard; SQ::N_SQUARES] = [
const KNIGHT_ATTACKS: SQMap<Bitboard> = SQMap::new([
B!(0x0000000000020400), B!(0x0000000000050800), B!(0x00000000000a1100), B!(0x0000000000142200),
B!(0x0000000000284400), B!(0x0000000000508800), B!(0x0000000000a01000), B!(0x0000000000402000),
B!(0x0000000002040004), B!(0x0000000005080008), B!(0x000000000a110011), B!(0x0000000014220022),
Expand All @@ -21,10 +22,10 @@ const KNIGHT_ATTACKS: [Bitboard; SQ::N_SQUARES] = [
B!(0x4400442800000000), B!(0x8800885000000000), B!(0x100010a000000000), B!(0x2000204000000000),
B!(0x0004020000000000), B!(0x0008050000000000), B!(0x00110a0000000000), B!(0x0022140000000000),
B!(0x0044280000000000), B!(0x0088500000000000), B!(0x0010a00000000000), B!(0x0020400000000000)
];
]);

#[rustfmt::skip]
const ADJACENT_ATTACKS: [Bitboard; SQ::N_SQUARES] = [
const ADJACENT_ATTACKS: SQMap<Bitboard> = SQMap::new([
B!(0x0000000000000302), B!(0x0000000000000705), B!(0x0000000000000e0a), B!(0x0000000000001c14),
B!(0x0000000000003828), B!(0x0000000000007050), B!(0x000000000000e0a0), B!(0x000000000000c040),
B!(0x0000000000030203), B!(0x0000000000070507), B!(0x00000000000e0a0e), B!(0x00000000001c141c),
Expand All @@ -41,11 +42,11 @@ const ADJACENT_ATTACKS: [Bitboard; SQ::N_SQUARES] = [
B!(0x3828380000000000), B!(0x7050700000000000), B!(0xe0a0e00000000000), B!(0xc040c00000000000),
B!(0x0203000000000000), B!(0x0507000000000000), B!(0x0a0e000000000000), B!(0x141c000000000000),
B!(0x2838000000000000), B!(0x5070000000000000), B!(0xa0e0000000000000), B!(0x40c0000000000000)
];
]);

#[rustfmt::skip]
const PAWN_ATTACKS: [[Bitboard; SQ::N_SQUARES]; Color::N_COLORS] = [
[
const PAWN_ATTACKS: ColorMap<SQMap<Bitboard>>= ColorMap::new([
SQMap::new([
B!(0x0000000000000200), B!(0x0000000000000500), B!(0x0000000000000a00), B!(0x0000000000001400),
B!(0x0000000000002800), B!(0x0000000000005000), B!(0x000000000000a000), B!(0x0000000000004000),
B!(0x0000000000020000), B!(0x0000000000050000), B!(0x00000000000a0000), B!(0x0000000000140000),
Expand All @@ -62,8 +63,8 @@ const PAWN_ATTACKS: [[Bitboard; SQ::N_SQUARES]; Color::N_COLORS] = [
B!(0x2800000000000000), B!(0x5000000000000000), B!(0xa000000000000000), B!(0x4000000000000000),
B!(0x0000000000000000), B!(0x0000000000000000), B!(0x0000000000000000), B!(0x0000000000000000),
B!(0x0000000000000000), B!(0x0000000000000000), B!(0x0000000000000000), B!(0x0000000000000000),
],
[
]),
SQMap::new([
B!(0x00000000000000), B!(0x00000000000000), B!(0x00000000000000), B!(0x00000000000000),
B!(0x00000000000000), B!(0x00000000000000), B!(0x00000000000000), B!(0x00000000000000),
B!(0x00000000000002), B!(0x00000000000005), B!(0x0000000000000a), B!(0x00000000000014),
Expand All @@ -79,32 +80,32 @@ const PAWN_ATTACKS: [[Bitboard; SQ::N_SQUARES]; Color::N_COLORS] = [
B!(0x00020000000000), B!(0x00050000000000), B!(0x000a0000000000), B!(0x00140000000000),
B!(0x00280000000000), B!(0x00500000000000), B!(0x00a00000000000), B!(0x00400000000000),
B!(0x02000000000000), B!(0x05000000000000), B!(0x0a000000000000), B!(0x14000000000000),
B!(0x28000000000000), B!(0x50000000000000), B!(0xa0000000000000), B!(0x40000000000000)]
B!(0x28000000000000), B!(0x50000000000000), B!(0xa0000000000000), B!(0x40000000000000)])

];
]);

pub fn rook_attacks(sq: SQ, occ: Bitboard) -> Bitboard {
unsafe { ROOK_MAGICS.attacks[sq.index()][ROOK_MAGICS.index(sq, occ)] }
unsafe { ROOK_MAGICS.attacks[sq][ROOK_MAGICS.index(sq, occ)] }
}

pub fn bishop_attacks(sq: SQ, occ: Bitboard) -> Bitboard {
unsafe { BISHOP_MAGICS.attacks[sq.index()][BISHOP_MAGICS.index(sq, occ)] }
unsafe { BISHOP_MAGICS.attacks[sq][BISHOP_MAGICS.index(sq, occ)] }
}

pub fn knight_attacks(sq: SQ) -> Bitboard {
KNIGHT_ATTACKS[sq.index()]
KNIGHT_ATTACKS[sq]
}

pub fn king_attacks(sq: SQ) -> Bitboard {
ADJACENT_ATTACKS[sq.index()]
ADJACENT_ATTACKS[sq]
}

pub fn pawn_attacks_bb(bb: Bitboard, color: Color) -> Bitboard {
bb.shift(Direction::NorthWest.relative(color)) | bb.shift(Direction::NorthEast.relative(color))
}

pub fn pawn_attacks_sq(sq: SQ, color: Color) -> Bitboard {
PAWN_ATTACKS[color.index()][sq.index()]
PAWN_ATTACKS[color][sq]
}

pub fn sliding_attacks(sq: SQ, occ: Bitboard, mask: Bitboard) -> Bitboard {
Expand Down
47 changes: 24 additions & 23 deletions src/bitboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ use super::piece::*;
use super::square::*;
use super::types::*;
use std::fmt;
use std::ops::*;
use std::ops::{
BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Mul, Not, Shl, ShlAssign, Shr,
ShrAssign, Sub,
};

#[derive(Clone, Copy, Default, PartialEq, Eq)]
pub struct Bitboard(pub Hash);
Expand Down Expand Up @@ -78,11 +81,11 @@ impl Bitboard {

impl Bitboard {
pub fn line(sq1: SQ, sq2: SQ) -> Self {
unsafe { LINES_BB[sq1.index()][sq2.index()] }
unsafe { LINES_BB[sq1][sq2] }
}

pub fn between(sq1: SQ, sq2: SQ) -> Self {
unsafe { BETWEEN_BB[sq1.index()][sq2.index()] }
unsafe { BETWEEN_BB[sq1][sq2] }
}

pub fn oo_mask(c: Color) -> Self {
Expand Down Expand Up @@ -313,44 +316,42 @@ impl Bitboard {
pub const CENTER: Self = B!(0x1818000000);
}

static mut BETWEEN_BB: [[Bitboard; SQ::N_SQUARES]; SQ::N_SQUARES] =
[[B!(0); SQ::N_SQUARES]; SQ::N_SQUARES];
static mut LINES_BB: [[Bitboard; SQ::N_SQUARES]; SQ::N_SQUARES] =
[[B!(0); SQ::N_SQUARES]; SQ::N_SQUARES];
static mut BETWEEN_BB: SQMap<SQMap<Bitboard>> =
SQMap::new([SQMap::new([B!(0); SQ::N_SQUARES]); SQ::N_SQUARES]);
static mut LINES_BB: SQMap<SQMap<Bitboard>> =
SQMap::new([SQMap::new([B!(0); SQ::N_SQUARES]); SQ::N_SQUARES]);

fn init_between() -> [[Bitboard; SQ::N_SQUARES]; SQ::N_SQUARES] {
let mut between_bb = [[B!(0); SQ::N_SQUARES]; SQ::N_SQUARES];
fn init_between() -> SQMap<SQMap<Bitboard>> {
let mut between_bb = SQMap::new([SQMap::new([B!(0); SQ::N_SQUARES]); SQ::N_SQUARES]);
for sq1 in Bitboard::ALL {
for sq2 in Bitboard::ALL {
let sqs = sq1.bb() | sq2.bb();
if sq1.file() == sq2.file() || sq1.rank() == sq2.rank() {
between_bb[sq1.index()][sq2.index()] = attacks::rook_attacks_for_init(sq1, sqs)
between_bb[sq1][sq2] = attacks::rook_attacks_for_init(sq1, sqs)
& attacks::rook_attacks_for_init(sq2, sqs);
} else if sq1.diagonal() == sq2.diagonal() || sq1.antidiagonal() == sq2.antidiagonal() {
between_bb[sq1.index()][sq2.index()] = attacks::bishop_attacks_for_init(sq1, sqs)
between_bb[sq1][sq2] = attacks::bishop_attacks_for_init(sq1, sqs)
& attacks::bishop_attacks_for_init(sq2, sqs);
}
}
}
between_bb
}

fn init_lines() -> [[Bitboard; SQ::N_SQUARES]; SQ::N_SQUARES] {
let mut lines_bb = [[B!(0); SQ::N_SQUARES]; SQ::N_SQUARES];
fn init_lines() -> SQMap<SQMap<Bitboard>> {
let mut lines_bb = SQMap::new([SQMap::new([B!(0); SQ::N_SQUARES]); SQ::N_SQUARES]);
for sq1 in Bitboard::ALL {
for sq2 in Bitboard::ALL {
if sq1.file() == sq2.file() || sq1.rank() == sq2.rank() {
lines_bb[sq1.index()][sq2.index()] =
attacks::rook_attacks_for_init(sq1, Bitboard::ZERO)
& attacks::rook_attacks_for_init(sq2, Bitboard::ZERO)
| sq1.bb()
| sq2.bb();
lines_bb[sq1][sq2] = attacks::rook_attacks_for_init(sq1, Bitboard::ZERO)
& attacks::rook_attacks_for_init(sq2, Bitboard::ZERO)
| sq1.bb()
| sq2.bb();
} else if sq1.diagonal() == sq2.diagonal() || sq1.antidiagonal() == sq2.antidiagonal() {
lines_bb[sq1.index()][sq2.index()] =
attacks::bishop_attacks_for_init(sq1, Bitboard::ZERO)
& attacks::bishop_attacks_for_init(sq2, Bitboard::ZERO)
| sq1.bb()
| sq2.bb();
lines_bb[sq1][sq2] = attacks::bishop_attacks_for_init(sq1, Bitboard::ZERO)
& attacks::bishop_attacks_for_init(sq2, Bitboard::ZERO)
| sq1.bb()
| sq2.bb();
}
}
}
Expand Down
60 changes: 30 additions & 30 deletions src/board.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,14 @@ use super::square::*;
use super::types::*;
use super::zobrist::*;
use regex::Regex;
use std::convert::TryFrom;
use std::fmt;
use std::sync::LazyLock;

#[derive(Clone)]
pub struct Board {
board: [Option<Piece>; SQ::N_SQUARES],
piece_type_bb: [Bitboard; PieceType::N_PIECE_TYPES],
color_bb: [Bitboard; Color::N_COLORS],
board: SQMap<Option<Piece>>,
piece_type_bb: PieceTypeMap<Bitboard>,
color_bb: ColorMap<Bitboard>,
history: [HistoryEntry; Self::N_HISTORIES],
ctm: Color,
ply: usize,
Expand All @@ -38,29 +37,29 @@ impl Board {
self.ctm = Color::White;
self.history = [HistoryEntry::default(); Self::N_HISTORIES];

self.color_bb = [Bitboard::ZERO; Color::N_COLORS];
self.piece_type_bb = [Bitboard::ZERO; PieceType::N_PIECE_TYPES];
self.board = [None; SQ::N_SQUARES];
self.color_bb = ColorMap::new([Bitboard::ZERO; Color::N_COLORS]);
self.piece_type_bb = PieceTypeMap::new([Bitboard::ZERO; PieceType::N_PIECE_TYPES]);
self.board = SQMap::new([None; SQ::N_SQUARES]);

self.hasher.clear();
self.network = Network::new();
}

pub fn piece_at(&self, sq: SQ) -> Option<Piece> {
self.board[sq.index()]
self.board[sq]
}

pub fn piece_type_at(&self, sq: SQ) -> Option<PieceType> {
self.board[sq.index()].map(|pc| pc.type_of())
self.board[sq].map(|pc| pc.type_of())
}

pub fn set_piece_at(&mut self, pc: Piece, sq: SQ) {
self.network.activate(pc, sq);
self.hasher.update_piece(pc, sq);

self.board[sq.index()] = Some(pc);
self.color_bb[pc.color_of().index()] |= sq.bb();
self.piece_type_bb[pc.type_of().index()] |= sq.bb();
self.board[sq] = Some(pc);
self.color_bb[pc.color_of()] |= sq.bb();
self.piece_type_bb[pc.type_of()] |= sq.bb();
}

pub fn remove_piece(&mut self, sq: SQ) {
Expand All @@ -71,9 +70,9 @@ impl Board {
self.network.deactivate(pc, sq);
self.hasher.update_piece(pc, sq);

self.piece_type_bb[pc.type_of().index()] &= !sq.bb();
self.color_bb[pc.color_of().index()] &= !sq.bb();
self.board[sq.index()] = None;
self.piece_type_bb[pc.type_of()] &= !sq.bb();
self.color_bb[pc.color_of()] &= !sq.bb();
self.board[sq] = None;
}

pub fn move_piece_quiet(&mut self, from_sq: SQ, to_sq: SQ) {
Expand All @@ -85,10 +84,10 @@ impl Board {
self.hasher.move_piece(pc, from_sq, to_sq);

let mask = from_sq.bb() | to_sq.bb();
self.piece_type_bb[pc.type_of().index()] ^= mask;
self.color_bb[pc.color_of().index()] ^= mask;
self.board[to_sq.index()] = self.board[from_sq.index()];
self.board[from_sq.index()] = None;
self.piece_type_bb[pc.type_of()] ^= mask;
self.color_bb[pc.color_of()] ^= mask;
self.board[to_sq] = self.board[from_sq];
self.board[from_sq] = None;
}

pub fn move_piece(&mut self, from_sq: SQ, to_sq: SQ) {
Expand All @@ -101,15 +100,15 @@ impl Board {
}

pub fn bitboard_of(&self, c: Color, pt: PieceType) -> Bitboard {
self.piece_type_bb[pt.index()] & self.color_bb[c.index()]
self.piece_type_bb[pt] & self.color_bb[c]
}

pub fn bitboard_of_pc(&self, pc: Piece) -> Bitboard {
self.piece_type_bb[pc.type_of().index()] & self.color_bb[pc.color_of().index()]
self.piece_type_bb[pc.type_of().index()] & self.color_bb[pc.color_of()]
}

pub fn bitboard_of_pt(&self, pt: PieceType) -> Bitboard {
self.piece_type_bb[pt.index()]
self.piece_type_bb[pt]
}

pub fn diagonal_sliders(&self) -> Bitboard {
Expand All @@ -129,11 +128,11 @@ impl Board {
}

pub fn all_pieces(&self) -> Bitboard {
self.color_bb[Color::White.index()] | self.color_bb[Color::Black.index()]
self.color_bb[Color::White] | self.color_bb[Color::Black]
}

pub fn all_pieces_c(&self, color: Color) -> Bitboard {
self.color_bb[color.index()]
self.color_bb[color]
}

pub fn attackers(&self, sq: SQ, occ: Bitboard) -> Bitboard {
Expand Down Expand Up @@ -949,12 +948,13 @@ impl Board {
}

pub fn simple_eval_c(&self, color: Color) -> Value {
const PIECE_VALUES: [Value; PieceType::N_PIECE_TYPES] = [100, 305, 333, 563, 950, 0];
const PIECE_TYPE_VALUES: PieceTypeMap<Value> =
PieceTypeMap::new([100, 305, 333, 563, 950, 0]);

let mut eval = 0;
for piece_type in PieceType::iter(PieceType::Pawn, PieceType::Queen) {
eval += self.bitboard_of(color, piece_type).pop_count()
* PIECE_VALUES[piece_type.index()] as Value;
* PIECE_TYPE_VALUES[piece_type] as Value;
}

eval
Expand Down Expand Up @@ -988,9 +988,9 @@ impl Board {
impl Default for Board {
fn default() -> Self {
Self {
piece_type_bb: [Bitboard::ZERO; PieceType::N_PIECE_TYPES],
color_bb: [Bitboard::ZERO; Color::N_COLORS],
board: [None; SQ::N_SQUARES],
piece_type_bb: PieceTypeMap::new([Bitboard::ZERO; PieceType::N_PIECE_TYPES]),
color_bb: ColorMap::new([Bitboard::ZERO; Color::N_COLORS]),
board: SQMap::new([None; SQ::N_SQUARES]),
ctm: Color::White,
ply: 0,
hasher: Hasher::new(),
Expand Down Expand Up @@ -1019,7 +1019,7 @@ impl fmt::Display for Board {
for file_idx in 0..=7 {
let file = File::from(file_idx);
let sq = SQ::encode(rank, file);
match self.board[sq.index()] {
match self.board[sq] {
Some(pc) => {
if empty_squares != 0 {
board_str.push_str(empty_squares.to_string().as_str());
Expand Down
Loading

0 comments on commit 6723103

Please sign in to comment.