bitboard: various changes and test fixes
This commit is contained in:
parent
b4dd16d87d
commit
fce38693bf
121
src/board.rs
121
src/board.rs
|
@ -150,16 +150,16 @@ impl Board {
|
|||
pub const fn new() -> Board {
|
||||
Board {
|
||||
colors: [
|
||||
0b11000000_11000000_11000000_11000000_11000000_11000000_11000000_11000000,
|
||||
0b00000011_00000011_00000011_00000011_00000011_00000011_00000011_00000011,
|
||||
0b00000011_00000011_00000011_00000011_00000011_00000011_00000011_00000011, // W
|
||||
0b11000000_11000000_11000000_11000000_11000000_11000000_11000000_11000000, // B
|
||||
],
|
||||
pieces: [
|
||||
0b01000010_01000010_01000010_01000010_01000010_01000010_01000010_01000010,
|
||||
0b00000000_00000000_10000001_00000000_00000000_10000001_00000000_00000000,
|
||||
0b00000000_10000001_00000000_00000000_00000000_00000000_10000001_00000000,
|
||||
0b10000001_00000000_00000000_00000000_00000000_00000000_00000000_10000001,
|
||||
0b00000000_00000000_00000000_10000001_00000000_00000000_00000000_00000000,
|
||||
0b00000000_00000000_00000000_00000000_10000001_00000000_00000000_00000000,
|
||||
0b01000010_01000010_01000010_01000010_01000010_01000010_01000010_01000010, // P
|
||||
0b00000000_00000000_10000001_00000000_00000000_10000001_00000000_00000000, // B
|
||||
0b00000000_10000001_00000000_00000000_00000000_00000000_10000001_00000000, // N
|
||||
0b10000001_00000000_00000000_00000000_00000000_00000000_00000000_10000001, // R
|
||||
0b00000000_00000000_00000000_00000000_10000001_00000000_00000000_00000000, // Q
|
||||
0b00000000_00000000_00000000_10000001_00000000_00000000_00000000_00000000, // K
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -179,18 +179,18 @@ impl Board {
|
|||
let mut r = 7;
|
||||
for c in fen.chars() {
|
||||
match c {
|
||||
'r' => { board.set_square(f * 8 + r, BLACK, ROOK); f += 1 }
|
||||
'n' => { board.set_square(f * 8 + r, BLACK, KNIGHT); f += 1 }
|
||||
'b' => { board.set_square(f * 8 + r, BLACK, BISHOP); f += 1 }
|
||||
'q' => { board.set_square(f * 8 + r, BLACK, QUEEN); f += 1 }
|
||||
'k' => { board.set_square(f * 8 + r, BLACK, KING); f += 1 }
|
||||
'p' => { board.set_square(f * 8 + r, BLACK, PAWN); f += 1 }
|
||||
'R' => { board.set_square(f * 8 + r, WHITE, ROOK); f += 1 }
|
||||
'N' => { board.set_square(f * 8 + r, WHITE, KNIGHT); f += 1 }
|
||||
'B' => { board.set_square(f * 8 + r, WHITE, BISHOP); f += 1 }
|
||||
'Q' => { board.set_square(f * 8 + r, WHITE, QUEEN); f += 1 }
|
||||
'K' => { board.set_square(f * 8 + r, WHITE, KING); f += 1 }
|
||||
'P' => { board.set_square(f * 8 + r, WHITE, PAWN); f += 1 }
|
||||
'r' => { board.set_square(sq(f, r), BLACK, ROOK); f += 1 }
|
||||
'n' => { board.set_square(sq(f, r), BLACK, KNIGHT); f += 1 }
|
||||
'b' => { board.set_square(sq(f, r), BLACK, BISHOP); f += 1 }
|
||||
'q' => { board.set_square(sq(f, r), BLACK, QUEEN); f += 1 }
|
||||
'k' => { board.set_square(sq(f, r), BLACK, KING); f += 1 }
|
||||
'p' => { board.set_square(sq(f, r), BLACK, PAWN); f += 1 }
|
||||
'R' => { board.set_square(sq(f, r), WHITE, ROOK); f += 1 }
|
||||
'N' => { board.set_square(sq(f, r), WHITE, KNIGHT); f += 1 }
|
||||
'B' => { board.set_square(sq(f, r), WHITE, BISHOP); f += 1 }
|
||||
'Q' => { board.set_square(sq(f, r), WHITE, QUEEN); f += 1 }
|
||||
'K' => { board.set_square(sq(f, r), WHITE, KING); f += 1 }
|
||||
'P' => { board.set_square(sq(f, r), WHITE, PAWN); f += 1 }
|
||||
'/' => { f = 0; r -= 1; }
|
||||
d if d.is_digit(10) => { f += d.to_digit(10).unwrap() as i8 }
|
||||
_ => break,
|
||||
|
@ -207,28 +207,46 @@ impl Board {
|
|||
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.
|
||||
pub fn is_empty(&self, square: Square) -> bool {
|
||||
self.combined() & bit_pos(square) == 0
|
||||
}
|
||||
|
||||
/// 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);
|
||||
if (self.colors[WHITE] & bp) == 1 { WHITE }
|
||||
else if (self.pieces[BLACK] & bp) == 1 { BLACK }
|
||||
if (self.colors[WHITE] & bp) != 0 { WHITE }
|
||||
else if (self.colors[BLACK] & bp) != 0 { BLACK }
|
||||
else { panic!("Empty square.") }
|
||||
}
|
||||
|
||||
/// 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);
|
||||
if (self.pieces[PAWN] & bp) == 1 { PAWN }
|
||||
else if (self.pieces[BISHOP] & bp) == 1 { BISHOP }
|
||||
else if (self.pieces[KNIGHT] & bp) == 1 { KNIGHT }
|
||||
else if (self.pieces[ROOK] & bp) == 1 { ROOK }
|
||||
else if (self.pieces[QUEEN] & bp) == 1 { QUEEN }
|
||||
else if (self.pieces[KING] & bp) == 1 { KING }
|
||||
if (self.pieces[PAWN] & bp) != 0 { PAWN }
|
||||
else if (self.pieces[BISHOP] & bp) != 0 { BISHOP }
|
||||
else if (self.pieces[KNIGHT] & bp) != 0 { KNIGHT }
|
||||
else if (self.pieces[ROOK] & bp) != 0 { ROOK }
|
||||
else if (self.pieces[QUEEN] & bp) != 0 { QUEEN }
|
||||
else if (self.pieces[KING] & bp) != 0 { KING }
|
||||
else { panic!("Empty square.") }
|
||||
}
|
||||
|
||||
|
@ -236,6 +254,7 @@ impl Board {
|
|||
#[inline]
|
||||
pub fn set_square(&mut self, square: Square, color: Color, piece: Piece) {
|
||||
self.colors[color] |= bit_pos(square);
|
||||
self.colors[opposite(color)] &= !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.
|
||||
#[inline]
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -257,7 +276,7 @@ impl Board {
|
|||
pub fn find_king(&self, color: Color) -> Option<Square> {
|
||||
let king_bb = self.colors[color] & self.pieces[KING];
|
||||
for square in 0..64 {
|
||||
if king_bb & bit_pos(square) == 1 {
|
||||
if king_bb & bit_pos(square) != 0 {
|
||||
return Some(square)
|
||||
}
|
||||
}
|
||||
|
@ -278,16 +297,16 @@ impl Board {
|
|||
|
||||
/// Debug only: write a text view of the board.
|
||||
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() {
|
||||
let mut rank_str = String::with_capacity(8);
|
||||
for file in 0..8 {
|
||||
let square = file * 8 + rank;
|
||||
let square = sq(file, rank);
|
||||
let bp = bit_pos(square);
|
||||
let piece_char = if cbb & bp == 0 {
|
||||
'.'
|
||||
} 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 {
|
||||
PAWN => 'p',
|
||||
BISHOP => 'b',
|
||||
|
@ -347,27 +366,27 @@ mod tests {
|
|||
#[test]
|
||||
fn test_get_color() {
|
||||
let b = Board::new();
|
||||
assert_eq!(b.get_color(A1), WHITE);
|
||||
assert_eq!(b.get_color(A2), WHITE);
|
||||
assert_eq!(b.get_color(A7), BLACK);
|
||||
assert_eq!(b.get_color(A8), BLACK);
|
||||
assert_eq!(b.get_color(D1), WHITE);
|
||||
assert_eq!(b.get_color(D8), BLACK);
|
||||
assert_eq!(b.get_color(E1), WHITE);
|
||||
assert_eq!(b.get_color(E8), BLACK);
|
||||
assert_eq!(b.get_color_on(A1), WHITE);
|
||||
assert_eq!(b.get_color_on(A2), WHITE);
|
||||
assert_eq!(b.get_color_on(A7), BLACK);
|
||||
assert_eq!(b.get_color_on(A8), BLACK);
|
||||
assert_eq!(b.get_color_on(D1), WHITE);
|
||||
assert_eq!(b.get_color_on(D8), BLACK);
|
||||
assert_eq!(b.get_color_on(E1), WHITE);
|
||||
assert_eq!(b.get_color_on(E8), BLACK);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_piece() {
|
||||
let b = Board::new();
|
||||
assert_eq!(b.get_piece(A1), ROOK);
|
||||
assert_eq!(b.get_piece(A2), PAWN);
|
||||
assert_eq!(b.get_piece(A7), PAWN);
|
||||
assert_eq!(b.get_piece(A8), ROOK);
|
||||
assert_eq!(b.get_piece(D1), QUEEN);
|
||||
assert_eq!(b.get_piece(D8), QUEEN);
|
||||
assert_eq!(b.get_piece(E1), KING);
|
||||
assert_eq!(b.get_piece(E8), KING);
|
||||
assert_eq!(b.get_piece_on(A1), ROOK);
|
||||
assert_eq!(b.get_piece_on(A2), PAWN);
|
||||
assert_eq!(b.get_piece_on(A7), PAWN);
|
||||
assert_eq!(b.get_piece_on(A8), ROOK);
|
||||
assert_eq!(b.get_piece_on(D1), QUEEN);
|
||||
assert_eq!(b.get_piece_on(D8), QUEEN);
|
||||
assert_eq!(b.get_piece_on(E1), KING);
|
||||
assert_eq!(b.get_piece_on(E8), KING);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -64,9 +64,9 @@ impl Move {
|
|||
}
|
||||
// Else, check if the king or a rook moved to update castling options.
|
||||
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 {
|
||||
match board.get_piece(self.dest) {
|
||||
match board.get_piece_on(self.dest) {
|
||||
KING => {
|
||||
if self.source == E1 {
|
||||
game_state.castling &= !CASTLING_WH_MASK;
|
||||
|
@ -82,7 +82,7 @@ impl Move {
|
|||
_ => {}
|
||||
}
|
||||
} 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 => {
|
||||
if self.source == E8 {
|
||||
game_state.castling &= !CASTLING_BL_MASK;
|
||||
|
@ -126,7 +126,7 @@ impl Move {
|
|||
} else {
|
||||
board.move_square(self.source, self.dest);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -213,7 +213,7 @@ mod tests {
|
|||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_apply_move_to_board() {
|
||||
fn test_apply_to_board() {
|
||||
let mut b = Board::new_empty();
|
||||
|
||||
// Put 2 enemy knights on board.
|
||||
|
@ -222,18 +222,18 @@ mod tests {
|
|||
// Move white knight in a position attacked by black knight.
|
||||
Move::new(D4, E6).apply_to_board(&mut b);
|
||||
assert!(b.is_empty(D4));
|
||||
assert_eq!(b.get_color(E6), WHITE);
|
||||
assert_eq!(b.get_piece(E6), KNIGHT);
|
||||
assert_eq!(b.get_color_on(E6), WHITE);
|
||||
assert_eq!(b.get_piece_on(E6), KNIGHT);
|
||||
assert_eq!(b.num_pieces(), 2);
|
||||
// Sack it with black knight
|
||||
Move::new(F4, E6).apply_to_board(&mut b);
|
||||
assert_eq!(b.get_color(E6), BLACK);
|
||||
assert_eq!(b.get_piece(E6), KNIGHT);
|
||||
assert_eq!(b.get_color_on(E6), BLACK);
|
||||
assert_eq!(b.get_piece_on(E6), KNIGHT);
|
||||
assert_eq!(b.num_pieces(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_apply_move_to_castling() {
|
||||
fn test_apply_to_castling() {
|
||||
let mut b = Board::new();
|
||||
let mut gs = GameState::new();
|
||||
assert_eq!(gs.castling, CASTLING_MASK);
|
||||
|
@ -251,19 +251,19 @@ mod tests {
|
|||
b.clear_square(G8);
|
||||
// White queen-side castling.
|
||||
Move::new(E1, C1).apply_to(&mut b, &mut gs);
|
||||
assert_eq!(b.get_color(C1), WHITE);
|
||||
assert_eq!(b.get_piece(C1), KING);
|
||||
assert_eq!(b.get_color(D1), WHITE);
|
||||
assert_eq!(b.get_piece(D1), ROOK);
|
||||
assert_eq!(b.get_color_on(C1), WHITE);
|
||||
assert_eq!(b.get_piece_on(C1), KING);
|
||||
assert_eq!(b.get_color_on(D1), WHITE);
|
||||
assert_eq!(b.get_piece_on(D1), ROOK);
|
||||
assert!(b.is_empty(A1));
|
||||
assert!(b.is_empty(E1));
|
||||
assert_eq!(gs.castling, CASTLING_BL_MASK);
|
||||
// Black king-side castling.
|
||||
Move::new(E8, G8).apply_to(&mut b, &mut gs);
|
||||
assert_eq!(b.get_color(G1), BLACK);
|
||||
assert_eq!(b.get_piece(G1), KING);
|
||||
assert_eq!(b.get_color(F1), BLACK);
|
||||
assert_eq!(b.get_piece(F1), ROOK);
|
||||
assert_eq!(b.get_color_on(G8), BLACK);
|
||||
assert_eq!(b.get_piece_on(G8), KING);
|
||||
assert_eq!(b.get_color_on(F8), BLACK);
|
||||
assert_eq!(b.get_piece_on(F8), ROOK);
|
||||
assert!(b.is_empty(H8));
|
||||
assert!(b.is_empty(E8));
|
||||
// At the end, no more castling options for both sides.
|
||||
|
|
36
src/rules.rs
36
src/rules.rs
|
@ -5,8 +5,8 @@ use crate::castling::*;
|
|||
use crate::fen;
|
||||
use crate::movement::Move;
|
||||
|
||||
const POS_MIN: i8 = 0;
|
||||
const POS_MAX: i8 = 7;
|
||||
pub const POS_MIN: i8 = 0;
|
||||
pub const POS_MAX: i8 = 7;
|
||||
|
||||
/// Characteristics of the state of a game.
|
||||
///
|
||||
|
@ -74,7 +74,7 @@ pub fn get_player_moves(
|
|||
if board.is_empty(square) {
|
||||
continue
|
||||
}
|
||||
if board.get_color(square) == game_state.color {
|
||||
if board.get_color_on(square) == game_state.color {
|
||||
moves.append(
|
||||
&mut get_piece_moves(board, game_state, square, game_state.color, commit)
|
||||
);
|
||||
|
@ -97,7 +97,7 @@ pub fn get_piece_moves(
|
|||
color: Color,
|
||||
commit: bool,
|
||||
) -> Vec<Move> {
|
||||
match board.get_piece(square) {
|
||||
match board.get_piece_on(square) {
|
||||
PAWN => get_pawn_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),
|
||||
|
@ -147,7 +147,7 @@ fn get_pawn_moves(
|
|||
if f - 1 >= POS_MIN {
|
||||
let diag = sq(f - 1, forward_r);
|
||||
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 can_register(commit, board, game_state, &m) {
|
||||
moves.push(m);
|
||||
|
@ -160,7 +160,7 @@ fn get_pawn_moves(
|
|||
if f + 1 <= POS_MAX {
|
||||
let diag = sq(f + 1, forward_r);
|
||||
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 can_register(commit, board, game_state, &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.
|
||||
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;
|
||||
continue
|
||||
}
|
||||
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;
|
||||
continue
|
||||
}
|
||||
|
@ -209,7 +209,7 @@ fn get_bishop_moves(
|
|||
moves.push(m);
|
||||
}
|
||||
} 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 can_register(commit, board, game_state, &m) {
|
||||
moves.push(m);
|
||||
|
@ -233,11 +233,11 @@ fn get_knight_moves(
|
|||
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() {
|
||||
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
|
||||
}
|
||||
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
|
||||
}
|
||||
let ray_square = sq(ray_f, ray_r);
|
||||
|
@ -248,7 +248,7 @@ fn get_knight_moves(
|
|||
moves.push(m);
|
||||
}
|
||||
} 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 can_register(commit, board, game_state, &m) {
|
||||
moves.push(m);
|
||||
|
@ -276,12 +276,12 @@ fn get_rook_moves(
|
|||
}
|
||||
|
||||
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;
|
||||
continue
|
||||
}
|
||||
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;
|
||||
continue
|
||||
}
|
||||
|
@ -293,7 +293,7 @@ fn get_rook_moves(
|
|||
moves.push(m);
|
||||
}
|
||||
} 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 can_register(commit, board, game_state, &m) {
|
||||
moves.push(m);
|
||||
|
@ -331,11 +331,11 @@ fn get_king_moves(
|
|||
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() {
|
||||
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
|
||||
}
|
||||
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
|
||||
}
|
||||
let ray_square = sq(ray_f, ray_r);
|
||||
|
@ -346,7 +346,7 @@ fn get_king_moves(
|
|||
moves.push(m);
|
||||
}
|
||||
} 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 can_register(commit, board, game_state, &m) {
|
||||
moves.push(m);
|
||||
|
|
|
@ -67,10 +67,10 @@ impl BoardStats {
|
|||
for file in 0..8 {
|
||||
for rank in 0..8 {
|
||||
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
|
||||
}
|
||||
match board.get_piece(square) {
|
||||
match board.get_piece_on(square) {
|
||||
ROOK => self.num_rooks += 1,
|
||||
KNIGHT => self.num_knights += 1,
|
||||
BISHOP => self.num_bishops += 1,
|
||||
|
|
Reference in a new issue