summaryrefslogtreecommitdiff
path: root/model/src
diff options
context:
space:
mode:
Diffstat (limited to 'model/src')
-rw-r--r--model/src/board.rs31
-rw-r--r--model/src/board/tests.rs314
-rw-r--r--model/src/possible_moves.rs27
3 files changed, 134 insertions, 238 deletions
diff --git a/model/src/board.rs b/model/src/board.rs
index 52d2b44..b722fd6 100644
--- a/model/src/board.rs
+++ b/model/src/board.rs
@@ -30,6 +30,10 @@ pub struct CheckersBitBoard {
pub kings: u32,
/// The player who has the next turn
pub turn: PieceColor,
+ /// The player with the previous turn
+ pub previous_turn: PieceColor,
+ /// Where the most recent move was to
+ pub previous_move_to: u8,
}
impl Default for CheckersBitBoard {
@@ -83,6 +87,9 @@ impl CheckersBitBoard {
color,
kings,
turn,
+ previous_turn: turn.flip(),
+ // this field is only used if previous_turn == turn
+ previous_move_to: 0,
}
}
@@ -330,6 +337,18 @@ impl CheckersBitBoard {
CheckersBitBoard::new(self.pieces, self.color, self.kings, self.turn.flip())
}
+ /// Change whose turn it was previously to the current player
+ pub const fn set_previous_turn(self, dest: usize) -> Self {
+ CheckersBitBoard {
+ pieces: self.pieces,
+ color: self.color,
+ kings: self.kings,
+ turn: self.turn,
+ previous_turn: self.turn,
+ previous_move_to: dest as u8,
+ }
+ }
+
/// Moves a piece from `start` to `dest`. The original location will be empty.
/// This does not mutate the original board.
/// If a piece already exists at `dest`, it will be overwritten.
@@ -543,7 +562,7 @@ impl CheckersBitBoard {
if (is_king || (((1 << value) & KING_MASK) == 0))
&& PossibleMoves::has_jumps_at(board.flip_turn(), (value + 14) & 31)
{
- board.flip_turn()
+ board.flip_turn().set_previous_turn((value + 14) & 31)
} else {
board
}
@@ -576,7 +595,7 @@ impl CheckersBitBoard {
if (is_king || (((1 << value) & KING_MASK) == 0))
&& PossibleMoves::has_jumps_at(board.flip_turn(), (value + 2) & 31)
{
- board.flip_turn()
+ board.flip_turn().set_previous_turn((value + 2) & 31)
} else {
board
}
@@ -609,7 +628,9 @@ impl CheckersBitBoard {
if (is_king || (((1 << value) & KING_MASK) == 0))
&& PossibleMoves::has_jumps_at(board.flip_turn(), value.wrapping_sub(2) & 31)
{
- board.flip_turn()
+ board
+ .flip_turn()
+ .set_previous_turn((value.wrapping_sub(2)) & 31)
} else {
board
}
@@ -642,7 +663,9 @@ impl CheckersBitBoard {
if (is_king || (((1 << value) & KING_MASK) == 0))
&& PossibleMoves::has_jumps_at(board.flip_turn(), value.wrapping_sub(14) & 31)
{
- board.flip_turn()
+ board
+ .flip_turn()
+ .set_previous_turn((value.wrapping_sub(14)) & 31)
} else {
board
}
diff --git a/model/src/board/tests.rs b/model/src/board/tests.rs
index f1009e7..8c119dc 100644
--- a/model/src/board/tests.rs
+++ b/model/src/board/tests.rs
@@ -15,10 +15,7 @@ proptest! {
#[test]
fn test_bits_fns(p in 0u32..=u32::MAX, c in 0u32..=u32::MAX, k in 0u32..=u32::MAX) {
- let board = CheckersBitBoard {
- pieces: p, color: c, kings: k, turn: PieceColor::Dark
- };
-
+ let board = CheckersBitBoard::new(p, c, k, PieceColor::Dark);
assert_eq!(p, board.pieces_bits());
assert_eq!(c, board.color_bits());
assert_eq!(k, board.king_bits());
@@ -26,15 +23,8 @@ proptest! {
#[test]
fn test_bitboard_hash(pieces in 0u32..=u32::MAX, color in 0u32..=u32::MAX, kings in 0u32..=u32::MAX, c in 0u32..=u32::MAX, k in 0u32..=u32::MAX) {
- let board1 = CheckersBitBoard {
- pieces, color, kings, turn: PieceColor::Dark
- };
- let board2 = CheckersBitBoard {
- pieces,
- color: c,
- kings: k,
- turn: PieceColor::Dark
- };
+ let board1 = CheckersBitBoard::new(pieces, color, kings, PieceColor::Dark);
+ let board2 = CheckersBitBoard::new(pieces, color, kings, PieceColor::Dark);
let mut hasher1 = DefaultHasher::new();
let mut hasher2 = DefaultHasher::new();
board1.hash(&mut hasher1);
@@ -44,26 +34,21 @@ proptest! {
#[test]
fn test_bitboard_eq_identical(pieces in 0u32..=u32::MAX, color in 0u32..u32::MAX, kings in 0u32..=u32::MAX) {
- let board1 = CheckersBitBoard {pieces, color, kings, turn: PieceColor::Dark};
- let board2 = CheckersBitBoard {pieces, color, kings, turn: PieceColor::Dark};
+ let board1 = CheckersBitBoard::new(pieces, color, kings, PieceColor::Dark);
+ let board2 = CheckersBitBoard::new(pieces, color, kings, PieceColor::Dark);
assert_eq!(board1, board2);
}
#[test]
fn test_bitboard_eq_empty(c1 in 0u32..u32::MAX, k1 in 0u32..=u32::MAX, c2 in 0u32..u32::MAX, k2 in 0u32..=u32::MAX) {
- let board1 = CheckersBitBoard {pieces: 0, color: c1, kings: k1, turn: PieceColor::Dark};
- let board2 = CheckersBitBoard {pieces: 0, color: c2, kings: k2, turn: PieceColor::Dark};
+ let board1 = CheckersBitBoard::new(0, c1, k1, PieceColor::Dark);
+ let board2 = CheckersBitBoard::new(0, c2, k2, PieceColor::Dark);
assert_eq!(board1, board2);
}
#[test]
fn test_piece_at(p in 0u32..=u32::MAX, c in 0u32..=u32::MAX, k in 0u32..=u32::MAX, v in 0usize..32) {
- let board = CheckersBitBoard {
- pieces: p,
- color: c,
- kings: k,
- turn: PieceColor::Dark
- };
+ let board = CheckersBitBoard ::new(p, c, k, PieceColor::Dark);
// just test for no crash
let _ = board.piece_at(v);
@@ -71,12 +56,7 @@ proptest! {
#[test]
fn test_color_at_unchecked(p in 0u32..=u32::MAX, c in 0u32..=u32::MAX, k in 0u32..=u32::MAX, v in 0usize..32) {
- let board = CheckersBitBoard {
- pieces: p,
- color: c,
- kings: k,
- turn: PieceColor::Dark
- };
+ let board = CheckersBitBoard ::new(p, c, k, PieceColor::Dark);
// just test for no crash
unsafe {let _ = board.color_at_unchecked(v);}
@@ -84,23 +64,13 @@ proptest! {
#[test]
fn test_king_at_unchecked(p in 0u32..=u32::MAX, c in 0u32..=u32::MAX, k in 0u32..=u32::MAX, v in 0usize..32) {
- let board = CheckersBitBoard {
- pieces: p,
- color: c,
- kings: k,
- turn: PieceColor::Dark
- };
+ let board = CheckersBitBoard ::new(p, c, k, PieceColor::Dark);
unsafe {let _ = board.king_at_unchecked(v);}
}
#[test]
fn test_color_at(p in 0u32..=u32::MAX, c in 0u32..=u32::MAX, k in 0u32..=u32::MAX, v in 0usize..32) {
- let board = CheckersBitBoard {
- pieces: p,
- color: c,
- kings: k,
- turn: PieceColor::Dark
- };
+ let board = CheckersBitBoard ::new(p, c, k, PieceColor::Dark);
// just testing for no crash
let _ = board.color_at(v);
@@ -108,12 +78,7 @@ proptest! {
#[test]
fn test_king_at(p in 0u32..=u32::MAX, c in 0u32..=u32::MAX, k in 0u32..=u32::MAX, v in 0usize..32) {
- let board = CheckersBitBoard {
- pieces: p,
- color: c,
- kings: k,
- turn: PieceColor::Dark
- };
+ let board = CheckersBitBoard ::new(p, c, k, PieceColor::Dark);
// just testing for no crash
let _ = board.king_at(v);
@@ -121,39 +86,27 @@ proptest! {
#[test]
fn test_move_piece_to(p in 0u32..=u32::MAX, c in 0u32..=u32::MAX, k in 0u32..=u32::MAX, s in 0usize..32, e in 0usize..32) {
- let board = CheckersBitBoard {
- pieces: p,
- color: c,
- kings: k,
- turn: PieceColor::Dark
- };
+ let board = CheckersBitBoard ::new(p, c, k, PieceColor::Dark);
let _ = unsafe {board.move_piece_to_unchecked(s, e)};
}
#[test]
fn test_move_forward(p in 0..u32::MAX, c in 0..u32::MAX, k in 0..u32::MAX, v in 0usize..32, a in 0usize..usize::MAX) {
if a <= usize::MAX - v { // so there's no overflow
- let board = CheckersBitBoard {
- pieces: p, color: c, kings: k, turn: PieceColor::Dark
- };
+ let board = CheckersBitBoard ::new(p, c, k, PieceColor::Dark);
let _ = unsafe {board.move_piece_forward_unchecked(v, a)};
}
}
#[test]
fn test_move_backward(p in 0..u32::MAX, c in 0..u32::MAX, k in 0..u32::MAX, v in 0usize..32, a in 0usize..usize::MAX) {
- let board = CheckersBitBoard {
- pieces: p, color: c, kings: k, turn: PieceColor::Dark
- };
+ let board = CheckersBitBoard ::new(p, c, k, PieceColor::Dark);
let _ = unsafe {board.move_piece_backward_unchecked(v, a)};
}
#[test]
fn test_move_forward_left(p in 0..u32::MAX, c in 0..u32::MAX, k in 0..u32::MAX) {
- let board = CheckersBitBoard {
- pieces: p, color: c, kings: k, turn: PieceColor::Dark
- };
-
+ let board = CheckersBitBoard ::new(p, c, k, PieceColor::Dark);
if board.piece_at(0) {
let board2 = unsafe {board.move_piece_forward_left_unchecked(0)};
assert_eq!(board2.color_at(7), board.color_at(0));
@@ -163,10 +116,7 @@ proptest! {
#[test]
fn test_move_forward_right(p in 0..u32::MAX, c in 0..u32::MAX, k in 0..u32::MAX) {
- let board = CheckersBitBoard {
- pieces: p, color: c, kings: k, turn: PieceColor::Dark
- };
-
+ let board = CheckersBitBoard ::new(p, c, k, PieceColor::Dark);
if board.piece_at(18) {
let board2 = unsafe {board.move_piece_forward_right_unchecked(18)};
assert_eq!(board2.color_at(19), board.color_at(18));
@@ -176,10 +126,7 @@ proptest! {
#[test]
fn test_move_backward_left(p in 0..u32::MAX, c in 0..u32::MAX, k in 0..u32::MAX) {
- let board = CheckersBitBoard {
- pieces: p, color: c, kings: k, turn: PieceColor::Dark
- };
-
+ let board = CheckersBitBoard ::new(p, c, k, PieceColor::Dark);
if board.piece_at(25) {
let board2 = unsafe {board.move_piece_backward_left_unchecked(25)};
assert_eq!(board2.color_at(24), board.color_at(25));
@@ -189,9 +136,7 @@ proptest! {
#[test]
fn test_move_backward_right(p in 0..u32::MAX, c in 0..u32::MAX, k in 0..u32::MAX) {
- let board = CheckersBitBoard {
- pieces: p, color: c, kings: k, turn: PieceColor::Dark
- };
+ let board = CheckersBitBoard ::new(p, c, k, PieceColor::Dark);
if board.piece_at(11) {
let board2 = unsafe {board.move_piece_backward_right_unchecked(11)};
assert_eq!(board2.color_at(4), board.color_at(11));
@@ -201,20 +146,14 @@ proptest! {
#[test]
fn test_clear_piece(p in 0..u32::MAX, c in 0..u32::MAX, k in 0..u32::MAX, v in 0usize..32) {
- let board = CheckersBitBoard {
- pieces: p, color: c, kings: k, turn: PieceColor::Dark
- };
-
+ let board = CheckersBitBoard ::new(p, c, k, PieceColor::Dark);
let board = board.clear_piece(v);
assert!(!board.piece_at(v));
}
#[test]
fn test_jump_forward_left(p in 0..u32::MAX, c in 0..u32::MAX, k in 0..u32::MAX) {
- let board = CheckersBitBoard {
- pieces: p, color: c, kings: k, turn: PieceColor::Dark
- };
-
+ let board = CheckersBitBoard ::new(p, c, k, PieceColor::Dark);
unsafe {
if board.piece_at(0) && board.piece_at(7) && !board.piece_at(14) && board.color_at_unchecked(0) != board.color_at_unchecked(7) {
let board2 = board.jump_piece_forward_left_unchecked(0);
@@ -229,10 +168,7 @@ proptest! {
#[test]
fn test_jump_forward_right(p in 0..u32::MAX, c in 0..u32::MAX, k in 0..u32::MAX) {
- let board = CheckersBitBoard {
- pieces: p, color: c, kings: k, turn: PieceColor::Dark
- };
-
+ let board = CheckersBitBoard ::new(p, c, k, PieceColor::Dark);
unsafe {
if board.piece_at(18) && board.piece_at(19) && !board.piece_at(20) && board.color_at_unchecked(18) != board.color_at_unchecked(19) {
let board2 = board.jump_piece_forward_right_unchecked(18);
@@ -247,10 +183,7 @@ proptest! {
#[test]
fn test_jump_backward_left(p in 0..u32::MAX, c in 0..u32::MAX, k in 0..u32::MAX) {
- let board = CheckersBitBoard {
- pieces: p, color: c, kings: k, turn: PieceColor::Dark
- };
-
+ let board = CheckersBitBoard ::new(p, c, k, PieceColor::Dark);
unsafe {
if board.piece_at(25) && board.piece_at(24) && !board.piece_at(23) && board.color_at_unchecked(25) != board.color_at_unchecked(24) {
let board2 = board.jump_piece_backward_left_unchecked(25);
@@ -265,10 +198,7 @@ proptest! {
#[test]
fn test_jump_backward_right(p in 0..u32::MAX, c in 0..u32::MAX, k in 0..u32::MAX) {
- let board = CheckersBitBoard {
- pieces: p, color: c, kings: k, turn: PieceColor::Dark
- };
-
+ let board = CheckersBitBoard ::new(p, c, k, PieceColor::Dark);
unsafe {
if board.piece_at(11) && board.piece_at(4) && !board.piece_at(29) && board.color_at_unchecked(11) != board.color_at_unchecked(4) {
let board2 = board.jump_piece_backward_right_unchecked(11);
@@ -284,12 +214,7 @@ proptest! {
#[test]
fn test_piece_at_empty_board() {
- let board = CheckersBitBoard {
- pieces: 0,
- color: 0,
- kings: 0,
- turn: PieceColor::Dark,
- };
+ let board = CheckersBitBoard::new(0, 0, 0, PieceColor::Dark);
// There should be no piece in any space
for i in 0..32 {
@@ -299,12 +224,7 @@ fn test_piece_at_empty_board() {
#[test]
fn test_piece_at_space_zero() {
- let board = CheckersBitBoard {
- pieces: 1,
- color: 0,
- kings: 0,
- turn: PieceColor::Dark,
- };
+ let board = CheckersBitBoard::new(1, 0, 0, PieceColor::Dark);
assert!(board.piece_at(0)); // There should be a piece in space 0
// There should be no piece in any other square
@@ -315,12 +235,7 @@ fn test_piece_at_space_zero() {
#[test]
fn test_color_at_unchecked_all_light() {
- let board = CheckersBitBoard {
- pieces: 0,
- color: 0,
- kings: 0,
- turn: PieceColor::Dark,
- };
+ let board = CheckersBitBoard::new(0, 0, 0, PieceColor::Dark);
// All squares should be light
for i in 0..32 {
@@ -330,12 +245,7 @@ fn test_color_at_unchecked_all_light() {
#[test]
fn test_color_at_unchecked_all_dark() {
- let board = CheckersBitBoard {
- pieces: 0,
- color: u32::MAX,
- kings: 0,
- turn: PieceColor::Dark,
- };
+ let board = CheckersBitBoard::new(0, u32::MAX, 0, PieceColor::Dark);
// All squares should be dark
for i in 0..32 {
@@ -345,12 +255,7 @@ fn test_color_at_unchecked_all_dark() {
#[test]
fn test_king_at_unchecked_all_kings() {
- let board = CheckersBitBoard {
- pieces: 0,
- color: 0,
- kings: u32::MAX,
- turn: PieceColor::Dark,
- };
+ let board = CheckersBitBoard::new(0, 0, u32::MAX, PieceColor::Dark);
// All squares should be kings
for i in 0..32 {
@@ -360,12 +265,7 @@ fn test_king_at_unchecked_all_kings() {
#[test]
fn test_king_at_unchecked_one_king() {
- let board = CheckersBitBoard {
- pieces: 0,
- color: 0,
- kings: 1,
- turn: PieceColor::Dark,
- };
+ let board = CheckersBitBoard::new(0, 0, 1, PieceColor::Dark);
assert!(unsafe { board.king_at_unchecked(0) });
@@ -399,63 +299,58 @@ fn test_default_bitboard() {
#[test]
fn test_bitboard_eq_default() {
- let board1 = CheckersBitBoard {
- pieces: 0b11100111100111100111110111111011,
- color: 0b11110011110000110000110000111100,
- kings: 0,
- turn: PieceColor::Dark,
- };
- let board2 = CheckersBitBoard {
- pieces: 0b11100111100111100111110111111011,
- color: 0b11110011110000110000110000111100,
- kings: 0,
- turn: PieceColor::Dark,
- };
+ let board1 = CheckersBitBoard::new(
+ 0b11100111100111100111110111111011,
+ 0b11110011110000110000110000111100,
+ 0,
+ PieceColor::Dark,
+ );
+ let board2 = CheckersBitBoard::new(
+ 0b11100111100111100111110111111011,
+ 0b11110011110000110000110000111100,
+ 0,
+ PieceColor::Dark,
+ );
assert_eq!(board1, board2);
}
#[test]
fn test_bitboard_neq_color() {
- let board1 = CheckersBitBoard {
- pieces: 0b11100111100111100111110111111011,
- color: 0b11110011110000110000110000111100,
- kings: 0,
- turn: PieceColor::Dark,
- };
- let board2 = CheckersBitBoard {
- pieces: 0b11100111100111100111110111111011,
- color: 465413646,
- kings: 0,
- turn: PieceColor::Dark,
- };
+ let board1 = CheckersBitBoard::new(
+ 0b11100111100111100111110111111011,
+ 0b11110011110000110000110000111100,
+ 0,
+ PieceColor::Dark,
+ );
+ let board2 = CheckersBitBoard::new(
+ 0b11100111100111100111110111111011,
+ 465413646,
+ 0,
+ PieceColor::Dark,
+ );
assert_ne!(board1, board2);
}
#[test]
fn test_bitboard_neq_kings() {
- let board1 = CheckersBitBoard {
- pieces: 0b11100111100111100111110111111011,
- color: 0b11110011110000110000110000111100,
- kings: 0,
- turn: PieceColor::Dark,
- };
- let board2 = CheckersBitBoard {
- pieces: 0b11100111100111100111110111111011,
- color: 0b11110011110000110000110000111100,
- kings: 465413646,
- turn: PieceColor::Dark,
- };
+ let board1 = CheckersBitBoard::new(
+ 0b11100111100111100111110111111011,
+ 0b11110011110000110000110000111100,
+ 0,
+ PieceColor::Dark,
+ );
+ let board2 = CheckersBitBoard::new(
+ 0b11100111100111100111110111111011,
+ 0b11110011110000110000110000111100,
+ 465413646,
+ PieceColor::Dark,
+ );
assert_ne!(board1, board2);
}
#[test]
fn test_color_at_empty() {
- let board = CheckersBitBoard {
- pieces: 0,
- color: 0,
- kings: 0,
- turn: PieceColor::Dark,
- };
+ let board = CheckersBitBoard::new(0, 0, 0, PieceColor::Dark);
for i in 0..32 {
assert_eq!(board.color_at(i), None)
@@ -464,12 +359,7 @@ fn test_color_at_empty() {
#[test]
fn test_color_at_specified_empty_colors() {
- let board = CheckersBitBoard {
- pieces: 0,
- color: 0b01,
- kings: 0,
- turn: PieceColor::Dark,
- };
+ let board = CheckersBitBoard::new(0, 0b01, 0, PieceColor::Dark);
for i in 0..32 {
assert_eq!(board.color_at(i), None)
@@ -478,12 +368,7 @@ fn test_color_at_specified_empty_colors() {
#[test]
fn test_color_at_some_colors() {
- let board = CheckersBitBoard {
- pieces: 3,
- color: 0b01,
- kings: 0,
- turn: PieceColor::Dark,
- };
+ let board = CheckersBitBoard::new(3, 0b01, 0, PieceColor::Dark);
assert_eq!(board.color_at(0), Some(PieceColor::Dark));
assert_eq!(board.color_at(1), Some(PieceColor::Light));
@@ -495,12 +380,7 @@ fn test_color_at_some_colors() {
#[test]
fn test_king_at_empty() {
- let board = CheckersBitBoard {
- pieces: 0,
- color: 0,
- kings: 0,
- turn: PieceColor::Dark,
- };
+ let board = CheckersBitBoard::new(0, 0, 0, PieceColor::Dark);
for i in 0..32 {
assert_eq!(board.king_at(i), None)
@@ -509,12 +389,7 @@ fn test_king_at_empty() {
#[test]
fn test_king_at_specified_empty_colors() {
- let board = CheckersBitBoard {
- pieces: 0,
- color: 0,
- kings: 0b01,
- turn: PieceColor::Dark,
- };
+ let board = CheckersBitBoard::new(0, 0, 0b01, PieceColor::Dark);
for i in 0..32 {
assert_eq!(board.king_at(i), None)
@@ -523,12 +398,7 @@ fn test_king_at_specified_empty_colors() {
#[test]
fn test_king_at_some_colors() {
- let board = CheckersBitBoard {
- pieces: 3,
- color: 0,
- kings: 0b01,
- turn: PieceColor::Dark,
- };
+ let board = CheckersBitBoard::new(3, 0, 0b01, PieceColor::Dark);
assert_eq!(board.king_at(0), Some(true));
assert_eq!(board.king_at(1), Some(false));
@@ -596,6 +466,7 @@ fn test_move_piece_backward_standard() {
assert_eq!(board.color_at(15).unwrap(), PieceColor::Light);
assert!(!board.king_at(15).unwrap());
assert_eq!(board.turn, PieceColor::Dark);
+ assert_eq!(board.previous_turn, PieceColor::Light);
}
#[test]
@@ -607,17 +478,13 @@ fn test_move_piece_backward_wrap() {
assert_eq!(board.color_at(28).unwrap(), PieceColor::Dark);
assert!(!board.king_at(28).unwrap());
assert_eq!(board.turn, PieceColor::Light);
+ assert_eq!(board.previous_turn, PieceColor::Dark);
}
#[test]
// the specific tests have special values, and are different from the property tests
fn test_jump_forward_left_specific() {
- let board = CheckersBitBoard {
- pieces: 0b10000001,
- color: 1,
- kings: 0,
- turn: PieceColor::Dark,
- };
+ let board = CheckersBitBoard::new(0b10000001, 1, 0, PieceColor::Dark);
let board2 = unsafe { board.jump_piece_forward_left_unchecked(0) };
assert!(!board2.piece_at(0));
@@ -630,12 +497,12 @@ fn test_jump_forward_left_specific() {
#[test]
fn test_jump_forward_right_specific() {
- let board = CheckersBitBoard {
- pieces: 0b11000000000000000000,
- color: 0b10000000000000000000,
- kings: 0,
- turn: PieceColor::Dark,
- };
+ let board = CheckersBitBoard::new(
+ 0b11000000000000000000,
+ 0b10000000000000000000,
+ 0,
+ PieceColor::Dark,
+ );
let board2 = unsafe { board.jump_piece_forward_right_unchecked(18) };
assert!(!board2.piece_at(18));
@@ -648,12 +515,12 @@ fn test_jump_forward_right_specific() {
#[test]
fn test_jump_backward_left_specific() {
- let board = CheckersBitBoard {
- pieces: 0b110000000000000000000000000,
- color: 0b100000000000000000000000000,
- kings: 0,
- turn: PieceColor::Dark,
- };
+ let board = CheckersBitBoard::new(
+ 0b110000000000000000000000000,
+ 0b100000000000000000000000000,
+ 0,
+ PieceColor::Dark,
+ );
let board2 = unsafe { board.jump_piece_backward_left_unchecked(25) };
assert!(!board2.piece_at(25));
@@ -666,12 +533,7 @@ fn test_jump_backward_left_specific() {
#[test]
fn test_jump_backward_right_specific() {
- let board = CheckersBitBoard {
- pieces: 0b100000010000,
- color: 0b10000,
- kings: 0,
- turn: PieceColor::Dark,
- };
+ let board = CheckersBitBoard::new(0b100000010000, 0b10000, 0, PieceColor::Dark);
let board2 = unsafe { board.jump_piece_backward_right_unchecked(11) };
assert!(!board2.piece_at(11));
diff --git a/model/src/possible_moves.rs b/model/src/possible_moves.rs
index bf69df6..ef05048 100644
--- a/model/src/possible_moves.rs
+++ b/model/src/possible_moves.rs
@@ -699,10 +699,26 @@ impl PossibleMoves {
}
}
- pub const fn moves(board: CheckersBitBoard) -> Self {
- match board.turn() {
+ const fn filter_to_square(self, square: u8) -> Self {
+ let mask = 1 << square;
+ Self {
+ forward_left_movers: self.forward_left_movers & mask,
+ forward_right_movers: self.forward_right_movers & mask,
+ backward_left_movers: self.backward_left_movers & mask,
+ backward_right_movers: self.backward_right_movers & (mask | 2),
+ }
+ }
+
+ pub fn moves(board: CheckersBitBoard) -> Self {
+ let moves = match board.turn() {
PieceColor::Dark => Self::dark_moves(board),
PieceColor::Light => Self::light_moves(board),
+ };
+
+ if board.turn == board.previous_turn {
+ moves.filter_to_square(board.previous_move_to)
+ } else {
+ moves
}
}
@@ -1026,12 +1042,7 @@ mod tests {
//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 board = CheckersBitBoard::new(16908890, 401395713, 50332352, PieceColor::Light);
let possible_moves = PossibleMoves::moves(board);
assert!(!possible_moves.can_jump())
}