Use PositionType for position

This commit is contained in:
hal8174 2024-01-20 14:55:29 +01:00
parent 2e9c699600
commit 207a0436d8
4 changed files with 283 additions and 194 deletions

View file

@ -1,3 +1,5 @@
pub type PositionType = i32;
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum Direction {
Up,
@ -65,8 +67,8 @@ impl Direction {
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct Position {
pub x: usize,
pub y: usize,
pub x: PositionType,
pub y: PositionType,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
@ -76,27 +78,34 @@ pub struct Dimension {
}
impl Position {
pub fn new(x: usize, y: usize) -> Self {
pub fn new(x: PositionType, y: PositionType) -> Self {
Self { x, y }
}
pub fn in_direction(
&self,
dir: &Direction,
len: usize,
dimension: &Dimension,
) -> Option<Position> {
pub fn in_direction(&self, dir: &Direction, len: PositionType) -> Position {
match dir {
Direction::Up => self.y.checked_sub(len).map(|y| Position::new(self.x, y)),
Direction::Right => Some(self.x + len)
.filter(|&x| x < dimension.width)
.map(|x| Position::new(x, self.y)),
Direction::Down => Some(self.y + len)
.filter(|&y| y < dimension.height)
.map(|y| Position::new(self.x, y)),
Direction::Left => self.x.checked_sub(len).map(|x| Position::new(x, self.y)),
Direction::Up => Position::new(self.x, self.y - len),
Direction::Right => Position::new(self.x + len, self.y),
Direction::Down => Position::new(self.x, self.y + len),
Direction::Left => Position::new(self.x - len, self.y),
}
}
pub fn in_range(&self, min: &Position, max: &Position) -> Option<&Position> {
if self.x < min.x {
return None;
}
if self.x >= max.x {
return None;
}
if self.y < min.y {
return None;
}
if self.y >= max.y {
return None;
}
Some(self)
}
}
#[derive(Clone, Debug, Copy)]
@ -135,29 +144,23 @@ impl PathField {
}
}
pub fn end_pos(&self, dimension: &Dimension) -> Option<(Position, Direction)> {
pub fn end_pos(&self) -> (Position, Direction) {
match self {
PathField::Belt { pos, dir } => Some((*pos, *dir)),
PathField::Underground { pos, dir, len } => pos
.in_direction(dir, *len as usize, dimension)
.map(|p| (p, *dir)),
PathField::Belt { pos, dir } => (*pos, *dir),
PathField::Underground { pos, dir, len } => {
(pos.in_direction(dir, *len as PositionType), *dir)
}
}
}
pub fn offset(&self, offset: (i32, i32)) -> Self {
pub fn offset(&self, offset: &Position) -> Self {
match self {
PathField::Belt { pos, dir } => PathField::Belt {
pos: Position::new(
(pos.x as i32 + offset.0) as usize,
(pos.y as i32 + offset.1) as usize,
),
pos: Position::new(pos.x + offset.x, pos.y + offset.y),
dir: *dir,
},
PathField::Underground { pos, dir, len } => PathField::Underground {
pos: Position::new(
(pos.x as i32 + offset.0) as usize,
(pos.y as i32 + offset.1) as usize,
),
pos: Position::new(pos.x + offset.x, pos.y + offset.y),
dir: *dir,
len: *len,
},