aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/attacks.rs67
1 files changed, 48 insertions, 19 deletions
diff --git a/src/attacks.rs b/src/attacks.rs
index 4562f25..0315ec9 100644
--- a/src/attacks.rs
+++ b/src/attacks.rs
@@ -1,4 +1,4 @@
-use crate::bitboard::Bitboard;
+use crate::{bitboard::Bitboard, board::Color};
static NOT_A_FILE: Bitboard = 0xFEFEFEFEFEFEFEFE;
static NOT_B_FILE: Bitboard = 0xFDFDFDFDFDFDFDFD;
@@ -40,6 +40,7 @@ enum Direction {
pub struct Attacks {
pub knight: AttackTable,
pub king: AttackTable,
+ pub pawn: [AttackTable; 2],
pub first_rank_attacks: FirstRankAttacks,
/// Should be indexed by Direction
pub ray_attacks: [AttackTable; 8],
@@ -52,28 +53,40 @@ impl Attacks {
let king = Self::precompute_king_attacks();
let first_rank_attacks = Self::precompute_first_rank_attacks();
let ray_attacks = Self::precompute_ray_attacks();
+ let pawn = Self::precompute_pawn_attacks();
Self {
knight,
king,
+ pawn,
first_rank_attacks,
ray_attacks,
}
}
+ fn precompute_pawn_attacks() -> [AttackTable; 2] {
+ let mut attacks = [[0; 64]; 2];
+ for index in 0..64 {
+ let square = 1u64 << index;
+ attacks[Color::White as usize][index] = ((square & NOT_A_FILE) << 7) | ((square & NOT_H_FILE) << 9);
+ attacks[Color::Black as usize][index] = ((square & NOT_A_FILE) >> 9) | ((square & NOT_H_FILE) >> 7);
+ }
+ attacks
+ }
+
fn precompute_knight_attacks() -> AttackTable {
let mut attacks = [0; 64];
for index in 0..64 {
- let position = 1u64 << index;
+ let square = 1u64 << index;
attacks[index] =
- ((position & NOT_A_FILE & NOT_B_FILE) << 6) |
- ((position & NOT_G_FILE & NOT_H_FILE) << 10) |
- ((position & NOT_A_FILE) << 15) |
- ((position & NOT_H_FILE) << 17) |
- ((position & NOT_G_FILE & NOT_H_FILE) >> 6) |
- ((position & NOT_A_FILE & NOT_B_FILE) >> 10) |
- ((position & NOT_H_FILE) >> 15) |
- ((position & NOT_A_FILE) >> 17);
+ ((square & NOT_A_FILE & NOT_B_FILE) << 6) |
+ ((square & NOT_G_FILE & NOT_H_FILE) << 10) |
+ ((square & NOT_A_FILE) << 15) |
+ ((square & NOT_H_FILE) << 17) |
+ ((square & NOT_G_FILE & NOT_H_FILE) >> 6) |
+ ((square & NOT_A_FILE & NOT_B_FILE) >> 10) |
+ ((square & NOT_H_FILE) >> 15) |
+ ((square & NOT_A_FILE) >> 17);
}
attacks
}
@@ -81,16 +94,16 @@ impl Attacks {
fn precompute_king_attacks() -> AttackTable {
let mut attacks = [0; 64];
for index in 0..64 {
- let position = 1u64 << index;
+ let square = 1u64 << index;
attacks[index] =
- ((position & NOT_A_FILE) >> 1) |
- ((position & NOT_A_FILE) << 7) |
- ((position & NOT_A_FILE) >> 9) |
- ((position & NOT_H_FILE) << 1) |
- ((position & NOT_H_FILE) >> 7) |
- ((position & NOT_H_FILE) << 9) |
- (position << 8) |
- (position >> 8);
+ ((square & NOT_A_FILE) >> 1) |
+ ((square & NOT_A_FILE) << 7) |
+ ((square & NOT_A_FILE) >> 9) |
+ ((square & NOT_H_FILE) << 1) |
+ ((square & NOT_H_FILE) >> 7) |
+ ((square & NOT_H_FILE) << 9) |
+ (square << 8) |
+ (square >> 8);
}
attacks
}
@@ -278,6 +291,22 @@ mod tests {
use super::*;
#[test]
+ fn test_pawn_attacks() {
+ let attacks = Attacks::precompute_pawn_attacks();
+ let square = Square::E4 as usize;
+
+ let white_attacks = attacks[Color::White as usize][square];
+ assert_eq!(white_attacks, 1 << Square::D5 as usize | 1 << Square::F5 as usize);
+ print(white_attacks);
+
+ assert_eq!(attacks[Color::White as usize][Square::H4 as usize], 1 << Square::G5 as usize);
+ assert_eq!(attacks[Color::White as usize][Square::A4 as usize], 1 << Square::B5 as usize);
+
+ assert_eq!(pop_count(attacks[Color::White as usize][Square::E8 as usize]), 0);
+ assert_eq!(pop_count(attacks[Color::Black as usize][Square::E1 as usize]), 0);
+ }
+
+ #[test]
fn test_knight_attacks() {
let attacks = Attacks::precompute_knight_attacks();
let e4_attacks = attacks[Square::E4 as usize];