128 lines
2.4 KiB
Rust
128 lines
2.4 KiB
Rust
|
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);
|
||
|
}
|
||
|
}
|