use crate::bounded::WrappedU8; /// Global game Direction. #[derive(Clone, Copy, PartialEq)] pub enum Direction { /// Towards the top of the board. Up, /// Towarfs the bottom of the board. Down, /// Towards the Left of the board. Left, /// Towards the Right of the board. Right } /// The way to Turn the Snake relative to it's global Direction. /// /// For example if the Snake is heading Right and it is told to go Left then /// it's next Direction would be Up. #[derive(Clone, Copy, PartialEq)] pub enum Turn { /// Turn left! Left, /// Turn right! Right, /// Go straight. Straight } /// Defines a position on the Game board. /// /// The game board is a grid with the upper left being (0, 0) /// with positive X to the right and positive y going down. /// /// Below is a 5x5 representation. /// /// [ (0,0) (1,0), (2,0), (3,0), (4,0) ] /// [ (0,1) (1,1), (2,1), (3,1), (4,1) ] /// [ (0,2) (1,2), (2,2), (3,2), (4,2) ] /// [ (0,3) (1,3), (2,3), (3,3), (4,3) ] /// [ (0,4) (1,4), (2,4), (3,4), (4,4) ] #[derive(Clone, Copy, Default, PartialEq)] pub struct Position { /// The column we are in. pub x: WrappedU8<0, 4>, /// The row we are in. pub y: WrappedU8<0, 4> } impl Position { pub fn new(x: u8, y: u8) -> Self { Position { x: x.into(), y: y.into() } } pub fn set(&mut self, new_x: u8, new_y: u8) { self.x = new_x.into(); self.y = new_y.into(); } } impl From<&Position> for (usize, usize) { fn from(pos: &Position) -> Self { (pos.x.get() as usize, pos.y.get() as usize) } } #[cfg(test)] mod tests { // use super::bounded::WrappedU8; use super::Position; #[test] fn position_new_sets_coordinates_correctly() { let pos = Position::new(2, 3); assert_eq!(pos.x.get(), 2); assert_eq!(pos.y.get(), 3); } #[test] fn position_set_updates_coordinates() { let mut pos = Position::new(0, 0); pos.set(4, 1); assert_eq!(pos.x.get(), 4); assert_eq!(pos.y.get(), 1); } #[test] fn position_new_wraps_coordinates() { let pos = Position::new(5, 6); assert_eq!(pos.x.get(), 1); assert_eq!(pos.y.get(), 2); } #[test] fn position_default_is_zero_zero() { let pos = Position::default(); assert_eq!(pos.x.get(), 0); assert_eq!(pos.y.get(), 0); } }