summaryrefslogtreecommitdiff
path: root/model/src/moves.rs
diff options
context:
space:
mode:
authorMicha White <botahamec@outlook.com>2023-12-21 20:24:44 -0500
committerMicha White <botahamec@outlook.com>2023-12-21 20:24:44 -0500
commit2143281a1f84040dbcd7a43b62772f9827042136 (patch)
tree5ab3e3fc41541092e4b185d7cd7c6f64735298c0 /model/src/moves.rs
parent94342846b8750cb753d2734b16dce20f249c6e65 (diff)
Reduce the size of a move to 8 bits
Diffstat (limited to 'model/src/moves.rs')
-rw-r--r--model/src/moves.rs99
1 files changed, 46 insertions, 53 deletions
diff --git a/model/src/moves.rs b/model/src/moves.rs
index 720ded6..c28bcef 100644
--- a/model/src/moves.rs
+++ b/model/src/moves.rs
@@ -11,16 +11,7 @@ pub enum MoveDirection {
/// A checkers move
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
-pub struct Move {
- /// The position of the piece to move
- start: u32,
-
- /// The direction to move to
- direction: MoveDirection,
-
- /// Whether or not it's a jump
- jump: bool,
-}
+pub struct Move(u8);
impl Move {
/// Create a new move
@@ -31,42 +22,44 @@ impl Move {
/// * `direction` - The direction the piece should move in
/// * `jump` - Whether or not the piece should jump
pub const fn new(start: usize, direction: MoveDirection, jump: bool) -> Self {
- Self {
- start: start as u32,
- direction,
- jump,
- }
+ Self(((start as u8) << 3) | ((direction as u8) << 1) | jump as u8)
}
/// The stating position of the move
pub const fn start(self) -> u32 {
- self.start
+ ((self.0 >> 3) & 0b11111) as u32
}
/// The direction the move goes in
pub const fn direction(self) -> MoveDirection {
- self.direction
+ match (self.0 >> 1) & 0b11 {
+ 0 => MoveDirection::ForwardLeft,
+ 1 => MoveDirection::ForwardRight,
+ 2 => MoveDirection::BackwardLeft,
+ 3 => MoveDirection::BackwardRight,
+ _ => unreachable!(),
+ }
}
/// Returns `true` if the move is a jump
pub const fn is_jump(self) -> bool {
- self.jump
+ (self.0 & 1) == 1
}
/// Calculates the value of the end position of the move
pub const fn end_position(self) -> usize {
- let dest = match self.jump {
- false => match self.direction {
- MoveDirection::ForwardLeft => (self.start + 7) % 32,
- MoveDirection::ForwardRight => (self.start + 1) % 32,
- MoveDirection::BackwardLeft => self.start.wrapping_sub(1) % 32,
- MoveDirection::BackwardRight => self.start.wrapping_sub(7) % 32,
+ let dest = match self.is_jump() {
+ false => match self.direction() {
+ MoveDirection::ForwardLeft => (self.start() + 7) % 32,
+ MoveDirection::ForwardRight => (self.start() + 1) % 32,
+ MoveDirection::BackwardLeft => self.start().wrapping_sub(1) % 32,
+ MoveDirection::BackwardRight => self.start().wrapping_sub(7) % 32,
},
- true => match self.direction {
- MoveDirection::ForwardLeft => (self.start + 14) % 32,
- MoveDirection::ForwardRight => (self.start + 2) % 32,
- MoveDirection::BackwardLeft => self.start.wrapping_sub(2) % 32,
- MoveDirection::BackwardRight => self.start.wrapping_sub(14) % 32,
+ true => match self.direction() {
+ MoveDirection::ForwardLeft => (self.start() + 14) % 32,
+ MoveDirection::ForwardRight => (self.start() + 2) % 32,
+ MoveDirection::BackwardLeft => self.start().wrapping_sub(2) % 32,
+ MoveDirection::BackwardRight => self.start().wrapping_sub(14) % 32,
},
};
dest as usize
@@ -93,33 +86,33 @@ impl Move {
/// * A jump occurs where jumps are not allowed
/// * A move is not a jump even though jumps are available
pub const unsafe fn apply_to(self, board: CheckersBitBoard) -> CheckersBitBoard {
- match self.jump {
- false => match self.direction {
+ match self.is_jump() {
+ false => match self.direction() {
MoveDirection::ForwardLeft => {
- board.move_piece_forward_left_unchecked(self.start as usize)
+ board.move_piece_forward_left_unchecked(self.start() as usize)
}
MoveDirection::ForwardRight => {
- board.move_piece_forward_right_unchecked(self.start as usize)
+ board.move_piece_forward_right_unchecked(self.start() as usize)
}
MoveDirection::BackwardLeft => {
- board.move_piece_backward_left_unchecked(self.start as usize)
+ board.move_piece_backward_left_unchecked(self.start() as usize)
}
MoveDirection::BackwardRight => {
- board.move_piece_backward_right_unchecked(self.start as usize)
+ board.move_piece_backward_right_unchecked(self.start() as usize)
}
},
- true => match self.direction {
+ true => match self.direction() {
MoveDirection::ForwardLeft => {
- board.jump_piece_forward_left_unchecked(self.start as usize)
+ board.jump_piece_forward_left_unchecked(self.start() as usize)
}
MoveDirection::ForwardRight => {
- board.jump_piece_forward_right_unchecked(self.start as usize)
+ board.jump_piece_forward_right_unchecked(self.start() as usize)
}
MoveDirection::BackwardLeft => {
- board.jump_piece_backward_left_unchecked(self.start as usize)
+ board.jump_piece_backward_left_unchecked(self.start() as usize)
}
MoveDirection::BackwardRight => {
- board.jump_piece_backward_right_unchecked(self.start as usize)
+ board.jump_piece_backward_right_unchecked(self.start() as usize)
}
},
}
@@ -131,7 +124,7 @@ impl Display for Move {
write!(
f,
"{}-{}",
- SquareCoordinate::from_value(self.start as usize),
+ SquareCoordinate::from_value(self.start() as usize),
SquareCoordinate::from_value(self.end_position())
)
}
@@ -148,27 +141,27 @@ mod tests {
fn new(start in 0usize..32, jump in proptest::bool::ANY) {
let direction = MoveDirection::ForwardLeft;
let move_test = Move::new(start, direction, jump);
- assert_eq!(move_test.start as usize, start);
- assert_eq!(move_test.direction, direction);
- assert_eq!(move_test.jump, jump);
+ assert_eq!(move_test.start() as usize, start);
+ assert_eq!(move_test.direction(), direction);
+ assert_eq!(move_test.is_jump(), jump);
let direction = MoveDirection::ForwardRight;
let move_test = Move::new(start, direction, jump);
- assert_eq!(move_test.start as usize, start);
- assert_eq!(move_test.direction, direction);
- assert_eq!(move_test.jump, jump);
+ assert_eq!(move_test.start() as usize, start);
+ assert_eq!(move_test.direction(), direction);
+ assert_eq!(move_test.is_jump(), jump);
let direction = MoveDirection::BackwardLeft;
let move_test = Move::new(start, direction, jump);
- assert_eq!(move_test.start as usize, start);
- assert_eq!(move_test.direction, direction);
- assert_eq!(move_test.jump, jump);
+ assert_eq!(move_test.start() as usize, start);
+ assert_eq!(move_test.direction(), direction);
+ assert_eq!(move_test.is_jump(), jump);
let direction = MoveDirection::BackwardRight;
let move_test = Move::new(start, direction, jump);
- assert_eq!(move_test.start as usize, start);
- assert_eq!(move_test.direction, direction);
- assert_eq!(move_test.jump, jump);
+ assert_eq!(move_test.start() as usize, start);
+ assert_eq!(move_test.direction(), direction);
+ assert_eq!(move_test.is_jump(), jump);
}
#[test]