use crate::file::File;
use crate::rank::Rank;
use crate::square::*;
use std::fmt;
use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Mul, Not};
#[derive(PartialEq, PartialOrd, Clone, Copy, Debug, Default)]
pub struct BitBoard(pub u64);
pub const EMPTY: BitBoard = BitBoard(0);
impl BitAnd for BitBoard {
type Output = BitBoard;
fn bitand(self, other: BitBoard) -> BitBoard {
BitBoard(self.0 & other.0)
}
}
impl BitAnd for &BitBoard {
type Output = BitBoard;
fn bitand(self, other: &BitBoard) -> BitBoard {
BitBoard(self.0 & other.0)
}
}
impl BitAnd<&BitBoard> for BitBoard {
type Output = BitBoard;
fn bitand(self, other: &BitBoard) -> BitBoard {
BitBoard(self.0 & other.0)
}
}
impl BitAnd<BitBoard> for &BitBoard {
type Output = BitBoard;
fn bitand(self, other: BitBoard) -> BitBoard {
BitBoard(self.0 & other.0)
}
}
impl BitOr for BitBoard {
type Output = BitBoard;
fn bitor(self, other: BitBoard) -> BitBoard {
BitBoard(self.0 | other.0)
}
}
impl BitOr for &BitBoard {
type Output = BitBoard;
fn bitor(self, other: &BitBoard) -> BitBoard {
BitBoard(self.0 | other.0)
}
}
impl BitOr<&BitBoard> for BitBoard {
type Output = BitBoard;
fn bitor(self, other: &BitBoard) -> BitBoard {
BitBoard(self.0 | other.0)
}
}
impl BitOr<BitBoard> for &BitBoard {
type Output = BitBoard;
fn bitor(self, other: BitBoard) -> BitBoard {
BitBoard(self.0 | other.0)
}
}
impl BitXor for BitBoard {
type Output = BitBoard;
fn bitxor(self, other: BitBoard) -> BitBoard {
BitBoard(self.0 ^ other.0)
}
}
impl BitXor for &BitBoard {
type Output = BitBoard;
fn bitxor(self, other: &BitBoard) -> BitBoard {
BitBoard(self.0 ^ other.0)
}
}
impl BitXor<&BitBoard> for BitBoard {
type Output = BitBoard;
fn bitxor(self, other: &BitBoard) -> BitBoard {
BitBoard(self.0 ^ other.0)
}
}
impl BitXor<BitBoard> for &BitBoard {
type Output = BitBoard;
fn bitxor(self, other: BitBoard) -> BitBoard {
BitBoard(self.0 ^ other.0)
}
}
impl BitAndAssign for BitBoard {
fn bitand_assign(&mut self, other: BitBoard) {
self.0 &= other.0;
}
}
impl BitAndAssign<&BitBoard> for BitBoard {
fn bitand_assign(&mut self, other: &BitBoard) {
self.0 &= other.0;
}
}
impl BitOrAssign for BitBoard {
fn bitor_assign(&mut self, other: BitBoard) {
self.0 |= other.0;
}
}
impl BitOrAssign<&BitBoard> for BitBoard {
fn bitor_assign(&mut self, other: &BitBoard) {
self.0 |= other.0;
}
}
impl BitXorAssign for BitBoard {
fn bitxor_assign(&mut self, other: BitBoard) {
self.0 ^= other.0;
}
}
impl BitXorAssign<&BitBoard> for BitBoard {
fn bitxor_assign(&mut self, other: &BitBoard) {
self.0 ^= other.0;
}
}
impl Mul for BitBoard {
type Output = BitBoard;
fn mul(self, other: BitBoard) -> BitBoard {
BitBoard(self.0.wrapping_mul(other.0))
}
}
impl Mul for &BitBoard {
type Output = BitBoard;
fn mul(self, other: &BitBoard) -> BitBoard {
BitBoard(self.0.wrapping_mul(other.0))
}
}
impl Mul<&BitBoard> for BitBoard {
type Output = BitBoard;
fn mul(self, other: &BitBoard) -> BitBoard {
BitBoard(self.0.wrapping_mul(other.0))
}
}
impl Mul<BitBoard> for &BitBoard {
type Output = BitBoard;
fn mul(self, other: BitBoard) -> BitBoard {
BitBoard(self.0.wrapping_mul(other.0))
}
}
impl Not for BitBoard {
type Output = BitBoard;
fn not(self) -> BitBoard {
BitBoard(!self.0)
}
}
impl Not for &BitBoard {
type Output = BitBoard;
fn not(self) -> BitBoard {
BitBoard(!self.0)
}
}
impl fmt::Display for BitBoard {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut s: String = "".to_owned();
for x in 0..64 {
if self.0 & (1u64 << x) == (1u64 << x) {
s.push_str("X ");
} else {
s.push_str(". ");
}
if x % 8 == 7 {
s.push_str("\n");
}
}
write!(f, "{}", s)
}
}
impl BitBoard {
pub fn new(b: u64) -> BitBoard {
BitBoard(b)
}
pub fn set(rank: Rank, file: File) -> BitBoard {
BitBoard::from_square(Square::make_square(rank, file))
}
pub fn from_square(sq: Square) -> BitBoard {
BitBoard(1u64 << sq.to_int())
}
pub fn from_maybe_square(sq: Option<Square>) -> Option<BitBoard> {
sq.map(|s| BitBoard::from_square(s))
}
pub fn to_square(&self) -> Square {
unsafe { Square::new(self.0.trailing_zeros() as u8) }
}
pub fn popcnt(&self) -> u32 {
self.0.count_ones()
}
pub fn reverse_colors(&self) -> BitBoard {
BitBoard(self.0.swap_bytes())
}
pub fn to_size(&self, rightshift: u8) -> usize {
(self.0 >> rightshift) as usize
}
}
impl Iterator for BitBoard {
type Item = Square;
fn next(&mut self) -> Option<Square> {
if self.0 == 0 {
None
} else {
let result = self.to_square();
*self ^= BitBoard::from_square(result);
Some(result)
}
}
}