summaryrefslogtreecommitdiff
path: root/model
diff options
context:
space:
mode:
authorMicha White <botahamec@outlook.com>2023-10-03 22:09:03 -0400
committerMicha White <botahamec@outlook.com>2023-10-03 22:09:03 -0400
commit2763381eefa80623af41e7f799dc17f0e38dfcae (patch)
tree1c837c4b4521112f96d7d19c0a9a18595fac2ef6 /model
parentdc20b764d34a82df88ad59be5fd56f01b56cabc4 (diff)
Fix bug with move generation jumps
Diffstat (limited to 'model')
-rw-r--r--model/benches/bitboard.rs2
-rw-r--r--model/src/board.rs8
-rw-r--r--model/src/board/tests.rs10
-rw-r--r--model/src/possible_moves.rs40
4 files changed, 41 insertions, 19 deletions
diff --git a/model/benches/bitboard.rs b/model/benches/bitboard.rs
index 7f64f2e..18d1a84 100644
--- a/model/benches/bitboard.rs
+++ b/model/benches/bitboard.rs
@@ -5,7 +5,7 @@ use std::hash::Hash;
fn clone(c: &mut Criterion) {
let board = CheckersBitBoard::starting_position();
- c.bench_function("clone", |b| b.iter(|| black_box(board.clone())));
+ c.bench_function("clone", |b| b.iter(|| black_box(board)));
}
fn hash(c: &mut Criterion) {
diff --git a/model/src/board.rs b/model/src/board.rs
index 1cc8d1c..7d61779 100644
--- a/model/src/board.rs
+++ b/model/src/board.rs
@@ -23,13 +23,13 @@ mod tests;
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct CheckersBitBoard {
/// If the space contains a piece, it's a 1
- pieces: u32,
+ pub pieces: u32,
/// If the piece is black, 1, otherwise 0
- color: u32,
+ pub color: u32,
/// 1 if the piece is a king
- kings: u32,
+ pub kings: u32,
/// The player who has the next turn
- turn: PieceColor,
+ pub turn: PieceColor,
}
impl Default for CheckersBitBoard {
diff --git a/model/src/board/tests.rs b/model/src/board/tests.rs
index c3ea2cd..f1009e7 100644
--- a/model/src/board/tests.rs
+++ b/model/src/board/tests.rs
@@ -127,7 +127,7 @@ proptest! {
kings: k,
turn: PieceColor::Dark
};
- unsafe {board.move_piece_to_unchecked(s, e)};
+ let _ = unsafe {board.move_piece_to_unchecked(s, e)};
}
#[test]
@@ -136,7 +136,7 @@ proptest! {
let board = CheckersBitBoard {
pieces: p, color: c, kings: k, turn: PieceColor::Dark
};
- unsafe {board.move_piece_forward_unchecked(v, a)};
+ let _ = unsafe {board.move_piece_forward_unchecked(v, a)};
}
}
@@ -145,7 +145,7 @@ proptest! {
let board = CheckersBitBoard {
pieces: p, color: c, kings: k, turn: PieceColor::Dark
};
- unsafe {board.move_piece_backward_unchecked(v, a)};
+ let _ = unsafe {board.move_piece_backward_unchecked(v, a)};
}
#[test]
@@ -378,8 +378,8 @@ fn test_king_at_unchecked_one_king() {
#[test]
fn test_default_bitboard() {
let board = CheckersBitBoard::default();
- let exemptions = vec![2, 28, 22, 16, 27, 21, 15, 9];
- let black = vec![18, 12, 6, 0, 19, 13, 7, 1, 26, 20, 14, 8];
+ let exemptions = [2, 28, 22, 16, 27, 21, 15, 9];
+ let black = [18, 12, 6, 0, 19, 13, 7, 1, 26, 20, 14, 8];
for i in 0..32 {
if !exemptions.contains(&i) {
diff --git a/model/src/possible_moves.rs b/model/src/possible_moves.rs
index 5140bb7..9f9f5af 100644
--- a/model/src/possible_moves.rs
+++ b/model/src/possible_moves.rs
@@ -379,7 +379,6 @@ impl IntoIterator for PossibleMoves {
impl PossibleMoves {
// TODO test
const fn slides_dark(board: CheckersBitBoard) -> Self {
- // TODO maybe remove these?
const FORWARD_LEFT_MASK: u32 = 0b01111001111110111111001111011011;
const FORWARD_RIGHT_MASK: u32 = 0b01111101111111011111010111011101;
const BACKWARD_LEFT_MASK: u32 = 0b11111011111110111110101110111010;
@@ -389,14 +388,18 @@ impl PossibleMoves {
let friendly_pieces = board.pieces_bits() & board.color_bits();
let friendly_kings = friendly_pieces & board.king_bits();
- let forward_left_movers = not_occupied.rotate_right(7) & friendly_pieces;
- let forward_right_movers = not_occupied.rotate_right(1) & friendly_pieces;
+ let forward_left_movers =
+ not_occupied.rotate_right(7) & friendly_pieces & FORWARD_LEFT_MASK;
+ let forward_right_movers =
+ not_occupied.rotate_right(1) & friendly_pieces & FORWARD_RIGHT_MASK;
let backward_left_movers;
let backward_right_movers;
if friendly_kings > 0 {
- backward_left_movers = not_occupied.rotate_left(1) & friendly_kings;
- backward_right_movers = not_occupied.rotate_left(7) & friendly_kings;
+ backward_left_movers =
+ not_occupied.rotate_left(1) & friendly_kings & BACKWARD_LEFT_MASK;
+ backward_right_movers =
+ not_occupied.rotate_left(7) & friendly_kings & BACKWARD_RIGHT_MASK;
} else {
backward_left_movers = 0;
backward_right_movers = 0;
@@ -420,14 +423,17 @@ impl PossibleMoves {
let friendly_pieces = board.pieces_bits() & !board.color_bits();
let friendly_kings = friendly_pieces & board.king_bits();
- let backward_left_movers = not_occupied.rotate_left(1) & friendly_pieces;
- let backward_right_movers = not_occupied.rotate_left(7) & friendly_pieces;
+ let backward_left_movers =
+ not_occupied.rotate_left(1) & friendly_pieces & BACKWARD_LEFT_MASK;
+ let backward_right_movers =
+ not_occupied.rotate_left(7) & friendly_pieces & BACKWARD_RIGHT_MASK;
let forward_left_movers;
let forward_right_movers;
if friendly_kings > 0 {
- forward_left_movers = not_occupied.rotate_right(7) & friendly_kings;
- forward_right_movers = not_occupied.rotate_right(1) & friendly_kings;
+ forward_left_movers = not_occupied.rotate_right(7) & friendly_kings & FORWARD_LEFT_MASK;
+ forward_right_movers =
+ not_occupied.rotate_right(1) & friendly_kings & FORWARD_RIGHT_MASK;
} else {
forward_left_movers = 0;
forward_right_movers = 0;
@@ -1019,6 +1025,22 @@ mod tests {
}
#[test]
+ fn cant_jump_in_position_2_without_26() {
+ // This bug was bizarre, but it's caused by a white piece being in the
+ //second bit while there is no piece in the 26th bit. If you don't
+ // apply the bit mask for collision detection, then all of the light
+ // player moves become jumps.
+ let board = CheckersBitBoard {
+ pieces: 16908890,
+ color: 401395713,
+ kings: 50332352,
+ turn: PieceColor::Light,
+ };
+ let possible_moves = PossibleMoves::moves(board);
+ assert!(!possible_moves.can_jump())
+ }
+
+ #[test]
fn test_send() {
fn assert_send<T: Send>() {}
assert_send::<PossibleMoves>();