From bf9e9af7f45433def26d2d2094a04798cb0282c0 Mon Sep 17 00:00:00 2001 From: mrw1593 Date: Tue, 13 Jul 2021 17:54:25 -0400 Subject: Updated docs and tests --- model/src/moves_iter.rs | 287 ++++++++++++++++++++++++------------------------ 1 file changed, 144 insertions(+), 143 deletions(-) (limited to 'model/src/moves_iter.rs') diff --git a/model/src/moves_iter.rs b/model/src/moves_iter.rs index 307ee96..ffa59b6 100644 --- a/model/src/moves_iter.rs +++ b/model/src/moves_iter.rs @@ -1,143 +1,144 @@ -use crate::moves::{Move, MoveDirection}; -use crate::possible_moves::PossibleMoves; - -const FORWARD_LEFT_SLIDE_SQUARES: [usize; 33] = [ - 1, 3, 3, 4, 6, 6, 7, 8, 9, 12, 12, 12, 13, 14, 15, 16, 17, 19, 19, 20, 21, 22, 23, 24, 27, 27, - 27, 28, 29, 30, 32, 32, 32, -]; -const FORWARD_RIGHT_SLIDE_SQUARES: [usize; 33] = [ - 2, 2, 3, 4, 6, 6, 7, 8, 10, 10, 12, 12, 13, 14, 15, 16, 18, 18, 19, 20, 21, 22, 23, 24, 26, 26, - 27, 28, 29, 30, 32, 32, 32, -]; -const BACKWARD_LEFT_SLIDE_SQUARES: [usize; 33] = [ - 1, 3, 3, 4, 5, 7, 7, 8, 9, 11, 11, 13, 13, 14, 15, 16, 17, 19, 19, 20, 21, 22, 23, 24, 25, 27, - 27, 28, 29, 30, 31, 32, 32, -]; -const BACKWARD_RIGHT_SLIDE_SQUARES: [usize; 33] = [ - 2, 2, 3, 4, 5, 7, 7, 8, 10, 10, 11, 13, 13, 14, 15, 16, 19, 19, 19, 20, 21, 22, 23, 24, 26, 26, - 27, 28, 29, 30, 31, 32, 32, -]; - -const FORWARD_LEFT_JUMP_SQUARES: [usize; 33] = [ - 1, 6, 6, 6, 6, 6, 7, 8, 9, 12, 12, 12, 13, 14, 15, 16, 17, 20, 20, 20, 21, 22, 23, 28, 28, 28, - 28, 28, 29, 32, 32, 32, 32, -]; -const FORWARD_RIGHT_JUMP_SQUARES: [usize; 33] = [ - 2, 2, 3, 6, 6, 6, 7, 12, 12, 12, 12, 12, 13, 14, 15, 18, 18, 18, 19, 20, 21, 22, 23, 26, 26, - 26, 27, 28, 29, 32, 32, 32, 32, -]; -const BACKWARD_LEFT_JUMP_SQUARES: [usize; 33] = [ - 4, 4, 4, 4, 5, 8, 8, 8, 9, 14, 14, 14, 14, 14, 15, 16, 17, 20, 20, 20, 21, 22, 23, 24, 25, 28, - 28, 28, 29, 30, 31, 32, 32, -]; -const BACKWARD_RIGHT_JUMP_SQUARES: [usize; 33] = [ - 2, 2, 3, 4, 5, 10, 10, 10, 10, 10, 11, 14, 14, 14, 15, 20, 20, 20, 20, 20, 21, 22, 23, 26, 26, - 26, 27, 28, 29, 30, 31, 32, 32, -]; - -static SLIDE_ARRAYS: [[usize; 33]; 4] = [ - FORWARD_LEFT_SLIDE_SQUARES, - FORWARD_RIGHT_SLIDE_SQUARES, - BACKWARD_LEFT_SLIDE_SQUARES, - BACKWARD_RIGHT_SLIDE_SQUARES, -]; - -static JUMP_ARRAYS: [[usize; 33]; 4] = [ - FORWARD_LEFT_JUMP_SQUARES, - FORWARD_RIGHT_JUMP_SQUARES, - BACKWARD_LEFT_JUMP_SQUARES, - BACKWARD_RIGHT_JUMP_SQUARES, -]; - -pub struct PossibleMovesIter { - possible_moves: PossibleMoves, - current_square: usize, - current_direction: MoveDirection, - movers: u32, - squares: &'static [usize; 33], -} - -impl From for PossibleMovesIter { - fn from(possible_moves: PossibleMoves) -> Self { - Self { - possible_moves, - current_square: 0, - current_direction: MoveDirection::ForwardLeft, - movers: possible_moves.forward_left_bits(), - squares: unsafe { - if possible_moves.can_jump() { - JUMP_ARRAYS.get_unchecked(0) - } else { - SLIDE_ARRAYS.get_unchecked(0) - } - }, - } - } -} - -impl Iterator for PossibleMovesIter { - type Item = Move; - - fn next(&mut self) -> Option { - loop { - if self.current_square == 32 { - if self.current_direction != MoveDirection::BackwardRight { - self.current_square = 0; - // safety: only results in undefined variant if equal to backward right - // this has already been checked for - self.current_direction = - unsafe { std::mem::transmute((self.current_direction as u8) + 1) }; - self.movers = self - .possible_moves - .get_direction_bits(self.current_direction); - - // safety: the max value of the enum is 3 - unsafe { - self.squares = &*(self.squares as *const [usize; 33]).add(1); - } - } else { - return None; - } - } - - if (self.movers >> self.current_square) & 1 != 0 { - let next_move = Move::new( - self.current_square, - self.current_direction, - self.possible_moves.can_jump(), - ); - - // safety: self.current_square will never be > 32 - // squares does not contain such a value - unsafe { - self.current_square = *self.squares.get_unchecked(self.current_square); - } - - return Some(next_move); - } - - if self.current_square != 32 { - // safety: self.current_square will never be > 32 - // squares does not contain such a value - unsafe { - self.current_square = *self.squares.get_unchecked(self.current_square); - } - } - } - } - - fn size_hint(&self) -> (usize, Option) { - ( - 0, - Some( - (32 - self.current_square) - + 32 * match self.current_direction { - MoveDirection::ForwardLeft => 3, - MoveDirection::ForwardRight => 2, - MoveDirection::BackwardLeft => 1, - MoveDirection::BackwardRight => 0, - }, - ), - ) - } -} +use crate::moves::{Move, MoveDirection}; +use crate::possible_moves::PossibleMoves; + +const FORWARD_LEFT_SLIDE_SQUARES: [usize; 33] = [ + 1, 3, 3, 4, 6, 6, 7, 8, 9, 12, 12, 12, 13, 14, 15, 16, 17, 19, 19, 20, 21, 22, 23, 24, 27, 27, + 27, 28, 29, 30, 32, 32, 32, +]; +const FORWARD_RIGHT_SLIDE_SQUARES: [usize; 33] = [ + 2, 2, 3, 4, 6, 6, 7, 8, 10, 10, 12, 12, 13, 14, 15, 16, 18, 18, 19, 20, 21, 22, 23, 24, 26, 26, + 27, 28, 29, 30, 32, 32, 32, +]; +const BACKWARD_LEFT_SLIDE_SQUARES: [usize; 33] = [ + 1, 3, 3, 4, 5, 7, 7, 8, 9, 11, 11, 13, 13, 14, 15, 16, 17, 19, 19, 20, 21, 22, 23, 24, 25, 27, + 27, 28, 29, 30, 31, 32, 32, +]; +const BACKWARD_RIGHT_SLIDE_SQUARES: [usize; 33] = [ + 2, 2, 3, 4, 5, 7, 7, 8, 10, 10, 11, 13, 13, 14, 15, 16, 19, 19, 19, 20, 21, 22, 23, 24, 26, 26, + 27, 28, 29, 30, 31, 32, 32, +]; + +const FORWARD_LEFT_JUMP_SQUARES: [usize; 33] = [ + 1, 6, 6, 6, 6, 6, 7, 8, 9, 12, 12, 12, 13, 14, 15, 16, 17, 20, 20, 20, 21, 22, 23, 28, 28, 28, + 28, 28, 29, 32, 32, 32, 32, +]; +const FORWARD_RIGHT_JUMP_SQUARES: [usize; 33] = [ + 2, 2, 3, 6, 6, 6, 7, 12, 12, 12, 12, 12, 13, 14, 15, 18, 18, 18, 19, 20, 21, 22, 23, 26, 26, + 26, 27, 28, 29, 32, 32, 32, 32, +]; +const BACKWARD_LEFT_JUMP_SQUARES: [usize; 33] = [ + 4, 4, 4, 4, 5, 8, 8, 8, 9, 14, 14, 14, 14, 14, 15, 16, 17, 20, 20, 20, 21, 22, 23, 24, 25, 28, + 28, 28, 29, 30, 31, 32, 32, +]; +const BACKWARD_RIGHT_JUMP_SQUARES: [usize; 33] = [ + 2, 2, 3, 4, 5, 10, 10, 10, 10, 10, 11, 14, 14, 14, 15, 20, 20, 20, 20, 20, 21, 22, 23, 26, 26, + 26, 27, 28, 29, 30, 31, 32, 32, +]; + +static SLIDE_ARRAYS: [[usize; 33]; 4] = [ + FORWARD_LEFT_SLIDE_SQUARES, + FORWARD_RIGHT_SLIDE_SQUARES, + BACKWARD_LEFT_SLIDE_SQUARES, + BACKWARD_RIGHT_SLIDE_SQUARES, +]; + +static JUMP_ARRAYS: [[usize; 33]; 4] = [ + FORWARD_LEFT_JUMP_SQUARES, + FORWARD_RIGHT_JUMP_SQUARES, + BACKWARD_LEFT_JUMP_SQUARES, + BACKWARD_RIGHT_JUMP_SQUARES, +]; + +pub struct PossibleMovesIter { + possible_moves: PossibleMoves, + current_square: usize, + current_direction: MoveDirection, + movers: u32, + squares: &'static [usize; 33], +} + +impl From for PossibleMovesIter { + fn from(possible_moves: PossibleMoves) -> Self { + Self { + possible_moves, + current_square: 0, + current_direction: MoveDirection::ForwardLeft, + movers: possible_moves.forward_left_bits(), + squares: unsafe { + if possible_moves.can_jump() { + JUMP_ARRAYS.get_unchecked(0) + } else { + SLIDE_ARRAYS.get_unchecked(0) + } + }, + } + } +} + +impl Iterator for PossibleMovesIter { + type Item = Move; + + fn next(&mut self) -> Option { + loop { + if self.current_square == 32 { + if self.current_direction != MoveDirection::BackwardRight { + self.current_square = 0; + // safety: only results in undefined variant if equal to backward right + // this has already been checked for + self.current_direction = + unsafe { std::mem::transmute((self.current_direction as u8) + 1) }; + self.movers = self + .possible_moves + .get_direction_bits(self.current_direction); + + // safety: this iterator stops returning values before this + // can result in undefined behavior + unsafe { + self.squares = &*(self.squares as *const [usize; 33]).add(1); + } + } else { + return None; + } + } + + if (self.movers >> self.current_square) & 1 != 0 { + let next_move = Move::new( + self.current_square, + self.current_direction, + self.possible_moves.can_jump(), + ); + + // safety: self.current_square will never be > 32 + // squares does not contain such a value + unsafe { + self.current_square = *self.squares.get_unchecked(self.current_square); + } + + return Some(next_move); + } + + if self.current_square != 32 { + // safety: self.current_square will never be > 32 + // squares does not contain such a value + unsafe { + self.current_square = *self.squares.get_unchecked(self.current_square); + } + } + } + } + + fn size_hint(&self) -> (usize, Option) { + ( + 0, + Some( + (32 - self.current_square) + + 32 * match self.current_direction { + MoveDirection::ForwardLeft => 3, + MoveDirection::ForwardRight => 2, + MoveDirection::BackwardLeft => 1, + MoveDirection::BackwardRight => 0, + }, + ), + ) + } +} -- cgit v1.2.3