Files
microbadge/src/snake/position.rs

128 lines
2.4 KiB
Rust
Raw Normal View History

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);
}
}