aboutsummaryrefslogtreecommitdiff
path: root/src/attacks.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/attacks.rs')
-rw-r--r--src/attacks.rs126
1 files changed, 115 insertions, 11 deletions
diff --git a/src/attacks.rs b/src/attacks.rs
index a8daec9..97e4f37 100644
--- a/src/attacks.rs
+++ b/src/attacks.rs
@@ -4,7 +4,7 @@ static NOT_A_FILE: Bitboard = 0xFEFEFEFEFEFEFEFE;
static NOT_B_FILE: Bitboard = 0xFDFDFDFDFDFDFDFD;
static NOT_G_FILE: Bitboard = 0xBFBFBFBFBFBFBFBF;
static NOT_H_FILE: Bitboard = 0x7F7F7F7F7F7F7F7F;
-static B_FILE: Bitboard = 0x0202020202020202;
+static B_FILE: Bitboard = 0x0202020202020202;
/// An array where N-th item is an attack bitboard
/// of a piece on N-th square
@@ -21,21 +21,24 @@ pub type Byte = u8;
/// ```
type FirstRankAttacks = [[Byte; 8]; 256];
+enum Direction {
+ Nort,
+ NoEa,
+ East,
+ SoEa,
+ Sout,
+ SoWe,
+ West,
+ NoWe,
+}
#[derive(Debug)]
pub struct Attacks {
pub knight: AttackTable,
pub king: AttackTable,
pub first_rank_attacks: FirstRankAttacks,
-
- // pub nort_ray: AttackTable,
- // pub noea_ray: AttackTable,
- // pub east_ray: AttackTable,
- // pub soea_ray: AttackTable,
- // pub sout_ray: AttackTable,
- // pub sowe_ray: AttackTable,
- // pub west_ray: AttackTable,
- // pub nowe_ray: AttackTable,
+ /// Should be indexed by Direction
+ pub ray_attacks: [AttackTable; 8],
}
#[allow(unused)]
@@ -44,11 +47,13 @@ impl Attacks {
let knight = Self::precompute_knight_attacks();
let king = Self::precompute_king_attacks();
let first_rank_attacks = Self::precompute_first_rank_attacks();
+ let ray_attacks = Self::precompute_ray_attacks();
Self {
knight,
king,
first_rank_attacks,
+ ray_attacks,
}
}
@@ -121,11 +126,93 @@ impl Attacks {
}
attacks
}
+
+ fn precompute_ray_attacks() -> [AttackTable; 8] {
+ let mut nort = [0; 64];
+ let mut noea = [0; 64];
+ let mut east = [0; 64];
+ let mut soea = [0; 64];
+ let mut sout = [0; 64];
+ let mut sowe = [0; 64];
+ let mut west = [0; 64];
+ let mut nowe = [0; 64];
+
+ for rank in 0..8 {
+ for file in 0..8 {
+ let index = rank * 8 + file;
+ {
+ let mut rank = rank;
+ while rank != 7 {
+ rank += 1;
+ nort[index] |= 1 << (rank * 8 + file);
+ }
+ }
+ {
+ let mut rank = rank;
+ let mut file = file;
+ while (rank < 7) && (file < 7) {
+ rank += 1;
+ file += 1;
+ noea[index] |= 1 << (rank * 8 + file);
+ }
+ }
+ {
+ let mut file = file;
+ while file < 7 {
+ file += 1;
+ east[index] |= 1 << (rank * 8 + file);
+ }
+ }
+ {
+ let mut rank = rank;
+ let mut file = file;
+ while (rank > 0) && (file < 7) {
+ rank -= 1;
+ file += 1;
+ soea[index] |= 1 << (rank * 8 + file);
+ }
+ }
+ {
+ let mut rank = rank;
+ while rank > 0 {
+ rank -= 1;
+ sout[index] |= 1 << (rank * 8 + file);
+ }
+ }
+ {
+ let mut rank = rank;
+ let mut file = file;
+ while (rank > 0) && (file > 0) {
+ rank -= 1;
+ file -= 1;
+ sowe[index] |= 1 << (rank * 8 + file);
+ }
+ }
+ {
+ let mut file = file;
+ while file > 0 {
+ file -= 1;
+ west[index] |= 1 << (rank * 8 + file);
+ }
+ }
+ {
+ let mut rank = rank;
+ let mut file = file;
+ while (file > 0) && (rank < 7) {
+ file -= 1;
+ rank += 1;
+ nowe[index] |= 1 << (rank * 8 + file);
+ }
+ }
+ }
+ }
+ [nort, noea, east, soea, sout, sowe, west, nowe]
+ }
}
#[cfg(test)]
mod tests {
- use crate::{bitboard::pop_count, board::Square};
+ use crate::{bitboard::{pop_count, print}, board::Square};
use super::*;
@@ -180,4 +267,21 @@ mod tests {
assert_eq!(attacks[0b01010010][4], 0b01101110);
}
+
+ #[test]
+ fn test_ray_attacks() {
+ let attacks = Attacks::precompute_ray_attacks();
+ let square = Square::E4 as usize;
+
+ let bitboard =
+ attacks[0][square] |
+ attacks[1][square] |
+ attacks[2][square] |
+ attacks[3][square] |
+ attacks[4][square] |
+ attacks[5][square] |
+ attacks[6][square] |
+ attacks[7][square];
+ print(bitboard);
+ }
}