pub struct Bitboard {
pub x_bitboard: u16,
pub o_bitboard: u16,
}
impl Bitboard {
pub fn new() -> Bitboard {
Bitboard {
x_bitboard: 0b000_0000_0000_0000,
o_bitboard: 0b0000_0000_0000_0000,
}
}
#[inline(always)]
pub fn clear_square(&mut self, square: u8) {
if self.x_bitboard & (1 << square) == (1 << square) {
self.x_bitboard -= 1 << square
}
if self.o_bitboard & (1 << square) == 1 << square {
self.o_bitboard -= 1 << square
}
}
#[inline(always)]
pub fn current_player(&self) -> bool {
self.x_bitboard.count_ones() <= self.o_bitboard.count_ones()
}
#[inline(always)]
pub fn num_moves(&self) -> u8 {
(self.x_bitboard.count_ones() + self.o_bitboard.count_ones()) as u8
}
#[inline(always)]
pub fn play(&mut self, square: u8) {
if self.current_player() {
self.x_bitboard |= 1 << square
} else {
self.o_bitboard |= 1 << square
}
}
#[inline(always)]
pub fn is_draw(&self) -> bool {
self.x_bitboard | self.o_bitboard == 0b0000_0001_1111_1111
}
#[inline(always)]
pub fn o_won(&self) -> bool {
if self.o_bitboard & 0b0000_0001_0001_0001 == 0b0000_0001_0001_0001 {
return true;
}
if self.o_bitboard & 0b0000_0000_0101_0100 == 0b0000_0000_0101_0100 {
return true;
}
for row in 0..3 {
if self.o_bitboard & 0b0000_0000_0000_0111 << (row * 3)
== 0b0000_0000_0000_0111 << (row * 3)
{
return true;
}
if self.o_bitboard & 0b0000_0000_0100_1001 << row == 0b0000_0000_0100_1001 << row {
return true;
}
}
return false;
}
#[inline(always)]
pub fn x_won(&self) -> bool {
if self.x_bitboard & 0b0000_0001_0001_0001 == 0b0000_0001_0001_0001 {
return true;
}
if self.x_bitboard & 0b0000_0000_0101_0100 == 0b0000_0000_0101_0100 {
return true;
}
for row in 0..3 {
if self.x_bitboard & 0b0000_0000_0000_0111 << (row * 3)
== 0b0000_0000_0000_0111 << (row * 3)
{
return true;
}
if self.x_bitboard & 0b0000_0000_0100_1001 << row == 0b0000_0000_0100_1001 << row {
return true;
}
}
return false;
}
#[inline(always)]
pub fn is_legal(&self, square: u8) -> bool {
self.x_bitboard & (1 << square) != 1 << square
&& (self.o_bitboard & (1 << square)) != 1 << square
}
}