bitboard: various changes and test fixes

This commit is contained in:
dece 2020-06-20 03:42:20 +02:00
parent b4dd16d87d
commit fce38693bf
4 changed files with 108 additions and 89 deletions

View file

@ -150,16 +150,16 @@ impl Board {
pub const fn new() -> Board { pub const fn new() -> Board {
Board { Board {
colors: [ colors: [
0b11000000_11000000_11000000_11000000_11000000_11000000_11000000_11000000, 0b00000011_00000011_00000011_00000011_00000011_00000011_00000011_00000011, // W
0b00000011_00000011_00000011_00000011_00000011_00000011_00000011_00000011, 0b11000000_11000000_11000000_11000000_11000000_11000000_11000000_11000000, // B
], ],
pieces: [ pieces: [
0b01000010_01000010_01000010_01000010_01000010_01000010_01000010_01000010, 0b01000010_01000010_01000010_01000010_01000010_01000010_01000010_01000010, // P
0b00000000_00000000_10000001_00000000_00000000_10000001_00000000_00000000, 0b00000000_00000000_10000001_00000000_00000000_10000001_00000000_00000000, // B
0b00000000_10000001_00000000_00000000_00000000_00000000_10000001_00000000, 0b00000000_10000001_00000000_00000000_00000000_00000000_10000001_00000000, // N
0b10000001_00000000_00000000_00000000_00000000_00000000_00000000_10000001, 0b10000001_00000000_00000000_00000000_00000000_00000000_00000000_10000001, // R
0b00000000_00000000_00000000_10000001_00000000_00000000_00000000_00000000, 0b00000000_00000000_00000000_00000000_10000001_00000000_00000000_00000000, // Q
0b00000000_00000000_00000000_00000000_10000001_00000000_00000000_00000000, 0b00000000_00000000_00000000_10000001_00000000_00000000_00000000_00000000, // K
] ]
} }
} }
@ -179,18 +179,18 @@ impl Board {
let mut r = 7; let mut r = 7;
for c in fen.chars() { for c in fen.chars() {
match c { match c {
'r' => { board.set_square(f * 8 + r, BLACK, ROOK); f += 1 } 'r' => { board.set_square(sq(f, r), BLACK, ROOK); f += 1 }
'n' => { board.set_square(f * 8 + r, BLACK, KNIGHT); f += 1 } 'n' => { board.set_square(sq(f, r), BLACK, KNIGHT); f += 1 }
'b' => { board.set_square(f * 8 + r, BLACK, BISHOP); f += 1 } 'b' => { board.set_square(sq(f, r), BLACK, BISHOP); f += 1 }
'q' => { board.set_square(f * 8 + r, BLACK, QUEEN); f += 1 } 'q' => { board.set_square(sq(f, r), BLACK, QUEEN); f += 1 }
'k' => { board.set_square(f * 8 + r, BLACK, KING); f += 1 } 'k' => { board.set_square(sq(f, r), BLACK, KING); f += 1 }
'p' => { board.set_square(f * 8 + r, BLACK, PAWN); f += 1 } 'p' => { board.set_square(sq(f, r), BLACK, PAWN); f += 1 }
'R' => { board.set_square(f * 8 + r, WHITE, ROOK); f += 1 } 'R' => { board.set_square(sq(f, r), WHITE, ROOK); f += 1 }
'N' => { board.set_square(f * 8 + r, WHITE, KNIGHT); f += 1 } 'N' => { board.set_square(sq(f, r), WHITE, KNIGHT); f += 1 }
'B' => { board.set_square(f * 8 + r, WHITE, BISHOP); f += 1 } 'B' => { board.set_square(sq(f, r), WHITE, BISHOP); f += 1 }
'Q' => { board.set_square(f * 8 + r, WHITE, QUEEN); f += 1 } 'Q' => { board.set_square(sq(f, r), WHITE, QUEEN); f += 1 }
'K' => { board.set_square(f * 8 + r, WHITE, KING); f += 1 } 'K' => { board.set_square(sq(f, r), WHITE, KING); f += 1 }
'P' => { board.set_square(f * 8 + r, WHITE, PAWN); f += 1 } 'P' => { board.set_square(sq(f, r), WHITE, PAWN); f += 1 }
'/' => { f = 0; r -= 1; } '/' => { f = 0; r -= 1; }
d if d.is_digit(10) => { f += d.to_digit(10).unwrap() as i8 } d if d.is_digit(10) => { f += d.to_digit(10).unwrap() as i8 }
_ => break, _ => break,
@ -207,28 +207,46 @@ impl Board {
self.colors[WHITE] | self.colors[BLACK] self.colors[WHITE] | self.colors[BLACK]
} }
/// Get the bitboard of a color.
#[inline]
pub fn by_color(&self, color: Color) -> Bitboard {
self.colors[color]
}
/// Get the bitboard of a piece type.
#[inline]
pub fn by_piece(&self, piece: Piece) -> Bitboard {
self.pieces[piece]
}
/// Get the bitboard of a piece type for this color.
#[inline]
pub fn by_color_piece(&self, color: Color, piece: Piece) -> Bitboard {
self.by_color(color) & self.by_piece(piece)
}
/// True if this square is empty. /// True if this square is empty.
pub fn is_empty(&self, square: Square) -> bool { pub fn is_empty(&self, square: Square) -> bool {
self.combined() & bit_pos(square) == 0 self.combined() & bit_pos(square) == 0
} }
/// Get color type at position. It must hold a piece! /// Get color type at position. It must hold a piece!
pub fn get_color(&self, square: Square) -> Color { pub fn get_color_on(&self, square: Square) -> Color {
let bp = bit_pos(square); let bp = bit_pos(square);
if (self.colors[WHITE] & bp) == 1 { WHITE } if (self.colors[WHITE] & bp) != 0 { WHITE }
else if (self.pieces[BLACK] & bp) == 1 { BLACK } else if (self.colors[BLACK] & bp) != 0 { BLACK }
else { panic!("Empty square.") } else { panic!("Empty square.") }
} }
/// Get piece type at position. It must hold a piece! /// Get piece type at position. It must hold a piece!
pub fn get_piece(&self, square: Square) -> Piece { pub fn get_piece_on(&self, square: Square) -> Piece {
let bp = bit_pos(square); let bp = bit_pos(square);
if (self.pieces[PAWN] & bp) == 1 { PAWN } if (self.pieces[PAWN] & bp) != 0 { PAWN }
else if (self.pieces[BISHOP] & bp) == 1 { BISHOP } else if (self.pieces[BISHOP] & bp) != 0 { BISHOP }
else if (self.pieces[KNIGHT] & bp) == 1 { KNIGHT } else if (self.pieces[KNIGHT] & bp) != 0 { KNIGHT }
else if (self.pieces[ROOK] & bp) == 1 { ROOK } else if (self.pieces[ROOK] & bp) != 0 { ROOK }
else if (self.pieces[QUEEN] & bp) == 1 { QUEEN } else if (self.pieces[QUEEN] & bp) != 0 { QUEEN }
else if (self.pieces[KING] & bp) == 1 { KING } else if (self.pieces[KING] & bp) != 0 { KING }
else { panic!("Empty square.") } else { panic!("Empty square.") }
} }
@ -236,6 +254,7 @@ impl Board {
#[inline] #[inline]
pub fn set_square(&mut self, square: Square, color: Color, piece: Piece) { pub fn set_square(&mut self, square: Square, color: Color, piece: Piece) {
self.colors[color] |= bit_pos(square); self.colors[color] |= bit_pos(square);
self.colors[opposite(color)] &= !bit_pos(square);
self.pieces[piece] |= bit_pos(square); self.pieces[piece] |= bit_pos(square);
} }
@ -249,7 +268,7 @@ impl Board {
/// Move a piece from a position to another, clearing initial position. /// Move a piece from a position to another, clearing initial position.
#[inline] #[inline]
pub fn move_square(&mut self, source: Square, dest: Square) { pub fn move_square(&mut self, source: Square, dest: Square) {
self.set_square(dest, self.get_color(source), self.get_piece(source)); self.set_square(dest, self.get_color_on(source), self.get_piece_on(source));
self.clear_square(source); self.clear_square(source);
} }
@ -257,7 +276,7 @@ impl Board {
pub fn find_king(&self, color: Color) -> Option<Square> { pub fn find_king(&self, color: Color) -> Option<Square> {
let king_bb = self.colors[color] & self.pieces[KING]; let king_bb = self.colors[color] & self.pieces[KING];
for square in 0..64 { for square in 0..64 {
if king_bb & bit_pos(square) == 1 { if king_bb & bit_pos(square) != 0 {
return Some(square) return Some(square)
} }
} }
@ -278,16 +297,16 @@ impl Board {
/// Debug only: write a text view of the board. /// Debug only: write a text view of the board.
pub(crate) fn draw(&self, f: &mut dyn std::io::Write) { pub(crate) fn draw(&self, f: &mut dyn std::io::Write) {
let cbb = self.colors[WHITE] | self.colors[BLACK]; let cbb = self.combined();
for rank in (0..8).rev() { for rank in (0..8).rev() {
let mut rank_str = String::with_capacity(8); let mut rank_str = String::with_capacity(8);
for file in 0..8 { for file in 0..8 {
let square = file * 8 + rank; let square = sq(file, rank);
let bp = bit_pos(square); let bp = bit_pos(square);
let piece_char = if cbb & bp == 0 { let piece_char = if cbb & bp == 0 {
'.' '.'
} else { } else {
let (color, piece) = (self.get_color(square), self.get_piece(square)); let (color, piece) = (self.get_color_on(square), self.get_piece_on(square));
let mut piece_char = match piece { let mut piece_char = match piece {
PAWN => 'p', PAWN => 'p',
BISHOP => 'b', BISHOP => 'b',
@ -347,27 +366,27 @@ mod tests {
#[test] #[test]
fn test_get_color() { fn test_get_color() {
let b = Board::new(); let b = Board::new();
assert_eq!(b.get_color(A1), WHITE); assert_eq!(b.get_color_on(A1), WHITE);
assert_eq!(b.get_color(A2), WHITE); assert_eq!(b.get_color_on(A2), WHITE);
assert_eq!(b.get_color(A7), BLACK); assert_eq!(b.get_color_on(A7), BLACK);
assert_eq!(b.get_color(A8), BLACK); assert_eq!(b.get_color_on(A8), BLACK);
assert_eq!(b.get_color(D1), WHITE); assert_eq!(b.get_color_on(D1), WHITE);
assert_eq!(b.get_color(D8), BLACK); assert_eq!(b.get_color_on(D8), BLACK);
assert_eq!(b.get_color(E1), WHITE); assert_eq!(b.get_color_on(E1), WHITE);
assert_eq!(b.get_color(E8), BLACK); assert_eq!(b.get_color_on(E8), BLACK);
} }
#[test] #[test]
fn test_get_piece() { fn test_get_piece() {
let b = Board::new(); let b = Board::new();
assert_eq!(b.get_piece(A1), ROOK); assert_eq!(b.get_piece_on(A1), ROOK);
assert_eq!(b.get_piece(A2), PAWN); assert_eq!(b.get_piece_on(A2), PAWN);
assert_eq!(b.get_piece(A7), PAWN); assert_eq!(b.get_piece_on(A7), PAWN);
assert_eq!(b.get_piece(A8), ROOK); assert_eq!(b.get_piece_on(A8), ROOK);
assert_eq!(b.get_piece(D1), QUEEN); assert_eq!(b.get_piece_on(D1), QUEEN);
assert_eq!(b.get_piece(D8), QUEEN); assert_eq!(b.get_piece_on(D8), QUEEN);
assert_eq!(b.get_piece(E1), KING); assert_eq!(b.get_piece_on(E1), KING);
assert_eq!(b.get_piece(E8), KING); assert_eq!(b.get_piece_on(E8), KING);
} }
#[test] #[test]

View file

@ -64,9 +64,9 @@ impl Move {
} }
// Else, check if the king or a rook moved to update castling options. // Else, check if the king or a rook moved to update castling options.
else { else {
let color = board.get_color(self.dest); let color = board.get_color_on(self.dest);
if color == WHITE && game_state.castling & CASTLING_WH_MASK != 0 { if color == WHITE && game_state.castling & CASTLING_WH_MASK != 0 {
match board.get_piece(self.dest) { match board.get_piece_on(self.dest) {
KING => { KING => {
if self.source == E1 { if self.source == E1 {
game_state.castling &= !CASTLING_WH_MASK; game_state.castling &= !CASTLING_WH_MASK;
@ -82,7 +82,7 @@ impl Move {
_ => {} _ => {}
} }
} else if color == BLACK && game_state.castling & CASTLING_BL_MASK != 0 { } else if color == BLACK && game_state.castling & CASTLING_BL_MASK != 0 {
match board.get_piece(self.dest) { match board.get_piece_on(self.dest) {
KING => { KING => {
if self.source == E8 { if self.source == E8 {
game_state.castling &= !CASTLING_BL_MASK; game_state.castling &= !CASTLING_BL_MASK;
@ -126,7 +126,7 @@ impl Move {
} else { } else {
board.move_square(self.source, self.dest); board.move_square(self.source, self.dest);
if let Some(piece) = self.promotion { if let Some(piece) = self.promotion {
let color = board.get_color(self.dest); let color = board.get_color_on(self.dest);
board.set_square(self.dest, color, piece); board.set_square(self.dest, color, piece);
} }
} }
@ -213,7 +213,7 @@ mod tests {
use super::*; use super::*;
#[test] #[test]
fn test_apply_move_to_board() { fn test_apply_to_board() {
let mut b = Board::new_empty(); let mut b = Board::new_empty();
// Put 2 enemy knights on board. // Put 2 enemy knights on board.
@ -222,18 +222,18 @@ mod tests {
// Move white knight in a position attacked by black knight. // Move white knight in a position attacked by black knight.
Move::new(D4, E6).apply_to_board(&mut b); Move::new(D4, E6).apply_to_board(&mut b);
assert!(b.is_empty(D4)); assert!(b.is_empty(D4));
assert_eq!(b.get_color(E6), WHITE); assert_eq!(b.get_color_on(E6), WHITE);
assert_eq!(b.get_piece(E6), KNIGHT); assert_eq!(b.get_piece_on(E6), KNIGHT);
assert_eq!(b.num_pieces(), 2); assert_eq!(b.num_pieces(), 2);
// Sack it with black knight // Sack it with black knight
Move::new(F4, E6).apply_to_board(&mut b); Move::new(F4, E6).apply_to_board(&mut b);
assert_eq!(b.get_color(E6), BLACK); assert_eq!(b.get_color_on(E6), BLACK);
assert_eq!(b.get_piece(E6), KNIGHT); assert_eq!(b.get_piece_on(E6), KNIGHT);
assert_eq!(b.num_pieces(), 1); assert_eq!(b.num_pieces(), 1);
} }
#[test] #[test]
fn test_apply_move_to_castling() { fn test_apply_to_castling() {
let mut b = Board::new(); let mut b = Board::new();
let mut gs = GameState::new(); let mut gs = GameState::new();
assert_eq!(gs.castling, CASTLING_MASK); assert_eq!(gs.castling, CASTLING_MASK);
@ -251,19 +251,19 @@ mod tests {
b.clear_square(G8); b.clear_square(G8);
// White queen-side castling. // White queen-side castling.
Move::new(E1, C1).apply_to(&mut b, &mut gs); Move::new(E1, C1).apply_to(&mut b, &mut gs);
assert_eq!(b.get_color(C1), WHITE); assert_eq!(b.get_color_on(C1), WHITE);
assert_eq!(b.get_piece(C1), KING); assert_eq!(b.get_piece_on(C1), KING);
assert_eq!(b.get_color(D1), WHITE); assert_eq!(b.get_color_on(D1), WHITE);
assert_eq!(b.get_piece(D1), ROOK); assert_eq!(b.get_piece_on(D1), ROOK);
assert!(b.is_empty(A1)); assert!(b.is_empty(A1));
assert!(b.is_empty(E1)); assert!(b.is_empty(E1));
assert_eq!(gs.castling, CASTLING_BL_MASK); assert_eq!(gs.castling, CASTLING_BL_MASK);
// Black king-side castling. // Black king-side castling.
Move::new(E8, G8).apply_to(&mut b, &mut gs); Move::new(E8, G8).apply_to(&mut b, &mut gs);
assert_eq!(b.get_color(G1), BLACK); assert_eq!(b.get_color_on(G8), BLACK);
assert_eq!(b.get_piece(G1), KING); assert_eq!(b.get_piece_on(G8), KING);
assert_eq!(b.get_color(F1), BLACK); assert_eq!(b.get_color_on(F8), BLACK);
assert_eq!(b.get_piece(F1), ROOK); assert_eq!(b.get_piece_on(F8), ROOK);
assert!(b.is_empty(H8)); assert!(b.is_empty(H8));
assert!(b.is_empty(E8)); assert!(b.is_empty(E8));
// At the end, no more castling options for both sides. // At the end, no more castling options for both sides.

View file

@ -5,8 +5,8 @@ use crate::castling::*;
use crate::fen; use crate::fen;
use crate::movement::Move; use crate::movement::Move;
const POS_MIN: i8 = 0; pub const POS_MIN: i8 = 0;
const POS_MAX: i8 = 7; pub const POS_MAX: i8 = 7;
/// Characteristics of the state of a game. /// Characteristics of the state of a game.
/// ///
@ -74,7 +74,7 @@ pub fn get_player_moves(
if board.is_empty(square) { if board.is_empty(square) {
continue continue
} }
if board.get_color(square) == game_state.color { if board.get_color_on(square) == game_state.color {
moves.append( moves.append(
&mut get_piece_moves(board, game_state, square, game_state.color, commit) &mut get_piece_moves(board, game_state, square, game_state.color, commit)
); );
@ -97,7 +97,7 @@ pub fn get_piece_moves(
color: Color, color: Color,
commit: bool, commit: bool,
) -> Vec<Move> { ) -> Vec<Move> {
match board.get_piece(square) { match board.get_piece_on(square) {
PAWN => get_pawn_moves(board, game_state, square, color, commit), PAWN => get_pawn_moves(board, game_state, square, color, commit),
BISHOP => get_bishop_moves(board, game_state, square, color, commit), BISHOP => get_bishop_moves(board, game_state, square, color, commit),
KNIGHT => get_knight_moves(board, game_state, square, color, commit), KNIGHT => get_knight_moves(board, game_state, square, color, commit),
@ -147,7 +147,7 @@ fn get_pawn_moves(
if f - 1 >= POS_MIN { if f - 1 >= POS_MIN {
let diag = sq(f - 1, forward_r); let diag = sq(f - 1, forward_r);
if !board.is_empty(diag) { if !board.is_empty(diag) {
let diag_color = board.get_color(diag); let diag_color = board.get_color_on(diag);
if let Some(m) = move_if_enemy(color, square, diag_color, diag, true) { if let Some(m) = move_if_enemy(color, square, diag_color, diag, true) {
if can_register(commit, board, game_state, &m) { if can_register(commit, board, game_state, &m) {
moves.push(m); moves.push(m);
@ -160,7 +160,7 @@ fn get_pawn_moves(
if f + 1 <= POS_MAX { if f + 1 <= POS_MAX {
let diag = sq(f + 1, forward_r); let diag = sq(f + 1, forward_r);
if !board.is_empty(diag) { if !board.is_empty(diag) {
let diag_color = board.get_color(diag); let diag_color = board.get_color_on(diag);
if let Some(m) = move_if_enemy(color, square, diag_color, diag, true) { if let Some(m) = move_if_enemy(color, square, diag_color, diag, true) {
if can_register(commit, board, game_state, &m) { if can_register(commit, board, game_state, &m) {
moves.push(m); moves.push(m);
@ -192,12 +192,12 @@ fn get_bishop_moves(
// If this position is out of the board, stop looking in that direction. // If this position is out of the board, stop looking in that direction.
let ray_f = f + offset.0 * dist; let ray_f = f + offset.0 * dist;
if ray_f <= POS_MIN || ray_f >= POS_MAX { if ray_f < POS_MIN || ray_f > POS_MAX {
views[dir] = false; views[dir] = false;
continue continue
} }
let ray_r = r + offset.1 * dist; let ray_r = r + offset.1 * dist;
if ray_r <= POS_MIN || ray_r >= POS_MAX { if ray_r < POS_MIN || ray_r > POS_MAX {
views[dir] = false; views[dir] = false;
continue continue
} }
@ -209,7 +209,7 @@ fn get_bishop_moves(
moves.push(m); moves.push(m);
} }
} else { } else {
let ray_color = board.get_color(ray_square); let ray_color = board.get_color_on(ray_square);
if let Some(m) = move_if_enemy(color, square, ray_color, ray_square, false) { if let Some(m) = move_if_enemy(color, square, ray_color, ray_square, false) {
if can_register(commit, board, game_state, &m) { if can_register(commit, board, game_state, &m) {
moves.push(m); moves.push(m);
@ -233,11 +233,11 @@ fn get_knight_moves(
let mut moves = Vec::with_capacity(8); let mut moves = Vec::with_capacity(8);
for offset in [(1, 2), (2, 1), (2, -1), (1, -2), (-1, -2), (-2, -1), (-2, 1), (-1, 2)].iter() { for offset in [(1, 2), (2, 1), (2, -1), (1, -2), (-1, -2), (-2, -1), (-2, 1), (-1, 2)].iter() {
let ray_f = f + offset.0; let ray_f = f + offset.0;
if ray_f <= POS_MIN || ray_f >= POS_MAX { if ray_f < POS_MIN || ray_f > POS_MAX {
continue continue
} }
let ray_r = r + offset.1; let ray_r = r + offset.1;
if ray_r <= POS_MIN || ray_r >= POS_MAX { if ray_r < POS_MIN || ray_r > POS_MAX {
continue continue
} }
let ray_square = sq(ray_f, ray_r); let ray_square = sq(ray_f, ray_r);
@ -248,7 +248,7 @@ fn get_knight_moves(
moves.push(m); moves.push(m);
} }
} else { } else {
let ray_color = board.get_color(ray_square); let ray_color = board.get_color_on(ray_square);
if let Some(m) = move_if_enemy(color, square, ray_color, ray_square, false) { if let Some(m) = move_if_enemy(color, square, ray_color, ray_square, false) {
if can_register(commit, board, game_state, &m) { if can_register(commit, board, game_state, &m) {
moves.push(m); moves.push(m);
@ -276,12 +276,12 @@ fn get_rook_moves(
} }
let ray_f = f + offset.0 * dist; let ray_f = f + offset.0 * dist;
if ray_f <= POS_MIN || ray_f >= POS_MAX { if ray_f < POS_MIN || ray_f > POS_MAX {
views[dir] = false; views[dir] = false;
continue continue
} }
let ray_r = r + offset.1 * dist; let ray_r = r + offset.1 * dist;
if ray_r <= POS_MIN || ray_r >= POS_MAX { if ray_r < POS_MIN || ray_r > POS_MAX {
views[dir] = false; views[dir] = false;
continue continue
} }
@ -293,7 +293,7 @@ fn get_rook_moves(
moves.push(m); moves.push(m);
} }
} else { } else {
let ray_color = board.get_color(ray_square); let ray_color = board.get_color_on(ray_square);
if let Some(m) = move_if_enemy(color, square, ray_color, ray_square, false) { if let Some(m) = move_if_enemy(color, square, ray_color, ray_square, false) {
if can_register(commit, board, game_state, &m) { if can_register(commit, board, game_state, &m) {
moves.push(m); moves.push(m);
@ -331,11 +331,11 @@ fn get_king_moves(
let mut moves = Vec::with_capacity(8); let mut moves = Vec::with_capacity(8);
for offset in [(-1, 1), (0, 1), (1, 1), (-1, 0), (1, 0), (-1, -1), (0, -1), (1, -1)].iter() { for offset in [(-1, 1), (0, 1), (1, 1), (-1, 0), (1, 0), (-1, -1), (0, -1), (1, -1)].iter() {
let ray_f = f + offset.0; let ray_f = f + offset.0;
if ray_f <= POS_MIN || ray_f >= POS_MAX { if ray_f < POS_MIN || ray_f > POS_MAX {
continue continue
} }
let ray_r = r + offset.1; let ray_r = r + offset.1;
if ray_r <= POS_MIN || ray_r >= POS_MAX { if ray_r < POS_MIN || ray_r > POS_MAX {
continue continue
} }
let ray_square = sq(ray_f, ray_r); let ray_square = sq(ray_f, ray_r);
@ -346,7 +346,7 @@ fn get_king_moves(
moves.push(m); moves.push(m);
} }
} else { } else {
let ray_color = board.get_color(ray_square); let ray_color = board.get_color_on(ray_square);
if let Some(m) = move_if_enemy(color, square, ray_color, ray_square, false) { if let Some(m) = move_if_enemy(color, square, ray_color, ray_square, false) {
if can_register(commit, board, game_state, &m) { if can_register(commit, board, game_state, &m) {
moves.push(m); moves.push(m);

View file

@ -67,10 +67,10 @@ impl BoardStats {
for file in 0..8 { for file in 0..8 {
for rank in 0..8 { for rank in 0..8 {
let square = sq(file, rank); let square = sq(file, rank);
if board.is_empty(square) || board.get_color(square) != color { if board.is_empty(square) || board.get_color_on(square) != color {
continue continue
} }
match board.get_piece(square) { match board.get_piece_on(square) {
ROOK => self.num_rooks += 1, ROOK => self.num_rooks += 1,
KNIGHT => self.num_knights += 1, KNIGHT => self.num_knights += 1,
BISHOP => self.num_bishops += 1, BISHOP => self.num_bishops += 1,