diff options
author | eug-vs <eugene@eug-vs.xyz> | 2023-01-21 18:44:03 +0300 |
---|---|---|
committer | eug-vs <eugene@eug-vs.xyz> | 2023-01-21 18:46:42 +0300 |
commit | 7d93bee082fb561d80a8fe3e1c60a9fcb0a399ba (patch) | |
tree | 2088c6980550da7264687d72a94de53bbaf00375 | |
parent | 74973416aa6a7b0fae9ed2b9911fa18fe87c4e1c (diff) | |
download | chessnost-7d93bee082fb561d80a8fe3e1c60a9fcb0a399ba.tar.gz |
refactor: return generated arrays
-rw-r--r-- | src/attacks.rs | 91 | ||||
-rw-r--r-- | src/board.rs | 35 |
2 files changed, 74 insertions, 52 deletions
diff --git a/src/attacks.rs b/src/attacks.rs index 141ba44..a8daec9 100644 --- a/src/attacks.rs +++ b/src/attacks.rs @@ -1,9 +1,10 @@ -use crate::bitboard::{Bitboard, ls1b, pop_count}; +use crate::bitboard::{Bitboard, ls1b}; 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; /// An array where N-th item is an attack bitboard /// of a piece on N-th square @@ -26,20 +27,33 @@ 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, } +#[allow(unused)] impl Attacks { pub fn new() -> Self { - let mut knight = [0; 64]; - let mut king = [0; 64]; - let mut first_rank_attacks = [[0; 8]; 256]; - Self::precompute_knight_attacks(&mut knight); - Self::precompute_king_attacks(&mut king); - Self::precompute_first_rank_attacks(&mut first_rank_attacks); - Self { knight, king, first_rank_attacks } + let knight = Self::precompute_knight_attacks(); + let king = Self::precompute_king_attacks(); + let first_rank_attacks = Self::precompute_first_rank_attacks(); + + Self { + knight, + king, + first_rank_attacks, + } } - fn precompute_knight_attacks(attacks: &mut AttackTable) { + fn precompute_knight_attacks() -> AttackTable { + let mut attacks = [0; 64]; for index in 0..64 { let position = 1u64 << index; attacks[index] = @@ -52,9 +66,11 @@ impl Attacks { ((position & NOT_H_FILE) >> 15) | ((position & NOT_A_FILE) >> 17); } + attacks } - fn precompute_king_attacks(attacks: &mut AttackTable) { + fn precompute_king_attacks() -> AttackTable { + let mut attacks = [0; 64]; for index in 0..64 { let position = 1u64 << index; attacks[index] = @@ -67,9 +83,13 @@ impl Attacks { (position << 8) | (position >> 8); } + attacks } - fn precompute_first_rank_attacks(attacks: &mut FirstRankAttacks) { + + fn precompute_first_rank_attacks() -> FirstRankAttacks { + let mut attacks = [[0; 8]; 256]; + /// Really slow implementation of Most Significant One Bit which is fine to use when pre-computing fn log_base_2(bb: Bitboard) -> u64 { (bb as f64).log2() as u64 @@ -99,6 +119,7 @@ impl Attacks { } } } + attacks } } @@ -110,8 +131,8 @@ mod tests { #[test] fn test_knight_attacks() { - let attacks = Attacks::new(); - let e4_attacks = attacks.knight[Square::E4 as usize]; + let attacks = Attacks::precompute_knight_attacks(); + let e4_attacks = attacks[Square::E4 as usize]; assert_ne!(e4_attacks & 1 << Square::G5 as usize, 0); assert_ne!(e4_attacks & 1 << Square::G3 as usize, 0); @@ -126,37 +147,37 @@ mod tests { assert_eq!(e4_attacks & 1 << Square::D4 as usize, 0); assert_eq!(e4_attacks & 1 << Square::A1 as usize, 0); - assert_eq!(pop_count(attacks.knight[Square::G1 as usize]), 3); - assert_eq!(pop_count(attacks.knight[Square::H8 as usize]), 2); + assert_eq!(pop_count(attacks[Square::G1 as usize]), 3); + assert_eq!(pop_count(attacks[Square::H8 as usize]), 2); } #[test] fn test_king_attacks() { - let attacks = Attacks::new(); - assert_eq!(pop_count(attacks.king[Square::E4 as usize]), 8); - - assert_eq!(pop_count(attacks.king[Square::A1 as usize]), 3); - assert_eq!(pop_count(attacks.king[Square::A8 as usize]), 3); - assert_eq!(pop_count(attacks.king[Square::H1 as usize]), 3); - assert_eq!(pop_count(attacks.king[Square::H8 as usize]), 3); - - assert_eq!(pop_count(attacks.king[Square::E1 as usize]), 5); - assert_eq!(pop_count(attacks.king[Square::E8 as usize]), 5); - assert_eq!(pop_count(attacks.king[Square::A4 as usize]), 5); - assert_eq!(pop_count(attacks.king[Square::H4 as usize]), 5); + let attacks = Attacks::precompute_king_attacks(); + assert_eq!(pop_count(attacks[Square::E4 as usize]), 8); + + assert_eq!(pop_count(attacks[Square::A1 as usize]), 3); + assert_eq!(pop_count(attacks[Square::A8 as usize]), 3); + assert_eq!(pop_count(attacks[Square::H1 as usize]), 3); + assert_eq!(pop_count(attacks[Square::H8 as usize]), 3); + + assert_eq!(pop_count(attacks[Square::E1 as usize]), 5); + assert_eq!(pop_count(attacks[Square::E8 as usize]), 5); + assert_eq!(pop_count(attacks[Square::A4 as usize]), 5); + assert_eq!(pop_count(attacks[Square::H4 as usize]), 5); } #[test] fn test_first_rank_attacks() { - let attacks = Attacks::new(); + let attacks = Attacks::precompute_first_rank_attacks(); // HGFEDCBA HGFEDCBA - assert_eq!(attacks.first_rank_attacks[0b00010000][4], 0b11101111, "If rook is the only one on the file, it should be able to attack all rank"); - assert_eq!(attacks.first_rank_attacks[0b00010001][4], 0b11101111, "If only other piece is on A rank, rook should be able to attack all rank"); - assert_eq!(attacks.first_rank_attacks[0b10010000][4], 0b11101111, "If only other piece is on H rank, rook should be able to attack all rank"); - assert_eq!(attacks.first_rank_attacks[0b10010001][4], 0b11101111, "If only other pieces are on A and H ranks, rook should be able to attack all rank"); - assert_eq!(attacks.first_rank_attacks[0b00010100][4], 0b11101100); - assert_eq!(attacks.first_rank_attacks[0b01010100][4], 0b01101100); - assert_eq!(attacks.first_rank_attacks[0b01010010][4], 0b01101110); + assert_eq!(attacks[0b00010000][4], 0b11101111, "If rook is the only one on the file, it should be able to attack all rank"); + assert_eq!(attacks[0b00010001][4], 0b11101111, "If only other piece is on A rank, rook should be able to attack all rank"); + assert_eq!(attacks[0b10010000][4], 0b11101111, "If only other piece is on H rank, rook should be able to attack all rank"); + assert_eq!(attacks[0b10010001][4], 0b11101111, "If only other pieces are on A and H ranks, rook should be able to attack all rank"); + assert_eq!(attacks[0b00010100][4], 0b11101100); + assert_eq!(attacks[0b01010100][4], 0b01101100); + assert_eq!(attacks[0b01010010][4], 0b01101110); } } diff --git a/src/board.rs b/src/board.rs index 13f86ec..86c42c7 100644 --- a/src/board.rs +++ b/src/board.rs @@ -32,6 +32,7 @@ const PIECE_CHARS: [&str; 12] = [ ]; +#[allow(unused)] impl Board { #[allow(non_snake_case)] pub fn from_FEN(fen: String) -> Self { @@ -128,7 +129,7 @@ pub enum Square { #[cfg(test)] mod tests { use super::*; - use crate::bitboard; + use crate::bitboard::{pop_count, bitscan}; #[test] fn test_square_enum() { @@ -142,22 +143,22 @@ mod tests { let fen = String::from("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); let board = Board::from_FEN(fen); - assert_eq!(bitboard::pop_count(board.pieces[PieceTypes::Pawn as usize]), 8); - assert_eq!(bitboard::pop_count(board.pieces[PieceTypes::Knight as usize]), 2); - assert_eq!(bitboard::pop_count(board.pieces[PieceTypes::Bishop as usize]), 2); - assert_eq!(bitboard::pop_count(board.pieces[PieceTypes::Rook as usize]), 2); - assert_eq!(bitboard::pop_count(board.pieces[PieceTypes::Queen as usize]), 1); - assert_eq!(bitboard::pop_count(board.pieces[PieceTypes::King as usize]), 1); - - assert_eq!(bitboard::pop_count(board.pieces[PieceTypes::PawnBlack as usize]), 8); - assert_eq!(bitboard::pop_count(board.pieces[PieceTypes::KnightBlack as usize]), 2); - assert_eq!(bitboard::pop_count(board.pieces[PieceTypes::BishopBlack as usize]), 2); - assert_eq!(bitboard::pop_count(board.pieces[PieceTypes::RookBlack as usize]), 2); - assert_eq!(bitboard::pop_count(board.pieces[PieceTypes::QueenBlack as usize]), 1); - assert_eq!(bitboard::pop_count(board.pieces[PieceTypes::KingBlack as usize]), 1); - - assert_eq!(bitboard::bitscan(board.pieces[PieceTypes::King as usize]), Square::E1 as u8); - assert_eq!(bitboard::bitscan(board.pieces[PieceTypes::QueenBlack as usize]), Square::D8 as u8); + assert_eq!(pop_count(board.pieces[PieceTypes::Pawn as usize]), 8); + assert_eq!(pop_count(board.pieces[PieceTypes::Knight as usize]), 2); + assert_eq!(pop_count(board.pieces[PieceTypes::Bishop as usize]), 2); + assert_eq!(pop_count(board.pieces[PieceTypes::Rook as usize]), 2); + assert_eq!(pop_count(board.pieces[PieceTypes::Queen as usize]), 1); + assert_eq!(pop_count(board.pieces[PieceTypes::King as usize]), 1); + + assert_eq!(pop_count(board.pieces[PieceTypes::PawnBlack as usize]), 8); + assert_eq!(pop_count(board.pieces[PieceTypes::KnightBlack as usize]), 2); + assert_eq!(pop_count(board.pieces[PieceTypes::BishopBlack as usize]), 2); + assert_eq!(pop_count(board.pieces[PieceTypes::RookBlack as usize]), 2); + assert_eq!(pop_count(board.pieces[PieceTypes::QueenBlack as usize]), 1); + assert_eq!(pop_count(board.pieces[PieceTypes::KingBlack as usize]), 1); + + assert_eq!(bitscan(board.pieces[PieceTypes::King as usize]), Square::E1 as u8); + assert_eq!(bitscan(board.pieces[PieceTypes::QueenBlack as usize]), Square::D8 as u8); board.print(); } |