1use thedes_geometry::orientation::Direction;
2use thiserror::Error;
3
4use crate::geometry::CoordPair;
5
6#[derive(Debug, Error)]
7pub enum InitError {
8 #[error("Player pointer position would overflow")]
9 Overflow,
10}
11
12#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
13pub struct PlayerPosition {
14 head: CoordPair,
15 facing: Direction,
16}
17
18impl PlayerPosition {
19 pub fn new(head: CoordPair, facing: Direction) -> Result<Self, InitError> {
20 if head.checked_move_unit(facing).is_none() {
21 Err(InitError::Overflow)?
22 }
23 Ok(Self { head, facing })
24 }
25
26 pub fn head(&self) -> CoordPair {
27 self.head
28 }
29
30 pub(crate) fn set_head(&mut self, new_head: CoordPair) {
31 self.head = new_head;
32 }
33
34 pub fn facing(&self) -> Direction {
35 self.facing
36 }
37
38 pub(crate) fn face(&mut self, direction: Direction) {
39 self.facing = direction;
40 }
41
42 pub fn pointer(&self) -> CoordPair {
43 self.head.move_unit(self.facing)
44 }
45}
46
47#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
48pub struct Player {
49 position: PlayerPosition,
50}
51
52impl Player {
53 pub fn new(position: PlayerPosition) -> Self {
54 Self { position }
55 }
56
57 pub fn position(&self) -> &PlayerPosition {
58 &self.position
59 }
60
61 pub(crate) fn position_mut(&mut self) -> &mut PlayerPosition {
62 &mut self.position
63 }
64}