Skip to main content

scramble_gen/
moves.rs

1use rand::{
2    Rng,
3    distr::{Distribution, StandardUniform},
4};
5use std::fmt;
6
7#[derive(Debug, PartialEq, Eq, Clone)]
8pub struct Move {
9    pub move_face: MoveFace,
10    pub move_type: MoveType,
11    pub move_width: MoveWidth,
12}
13
14impl fmt::Display for Move {
15    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
16        match self.move_width {
17            MoveWidth::Single => write!(f, "{}{}", self.move_face, self.move_type),
18            MoveWidth::Wide => write!(f, "{}w{}", self.move_face, self.move_type),
19            MoveWidth::ThreeWide => write!(f, "3{}{}", self.move_face, self.move_type),
20        }
21    }
22}
23
24#[derive(Debug, PartialEq, Eq, Clone, Copy)]
25pub enum MoveFace {
26    Left,
27    Right,
28    Up,
29    Down,
30    Front,
31    Back,
32}
33
34impl fmt::Display for MoveFace {
35    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36        match self {
37            MoveFace::Left => write!(f, "L"),
38            MoveFace::Right => write!(f, "R"),
39            MoveFace::Up => write!(f, "U"),
40            MoveFace::Down => write!(f, "D"),
41            MoveFace::Front => write!(f, "F"),
42            MoveFace::Back => write!(f, "B"),
43        }
44    }
45}
46
47impl MoveFace {
48    pub fn same_axis(&self, other: &MoveFace) -> bool {
49        matches!(
50            (self, other),
51            (MoveFace::Right, MoveFace::Left)
52                | (MoveFace::Left, MoveFace::Right)
53                | (MoveFace::Up, MoveFace::Down)
54                | (MoveFace::Down, MoveFace::Up)
55                | (MoveFace::Front, MoveFace::Back)
56                | (MoveFace::Back, MoveFace::Front)
57        )
58    }
59}
60
61impl Distribution<MoveFace> for StandardUniform {
62    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> MoveFace {
63        match rng.random_range(0..6) {
64            0 => MoveFace::Left,
65            1 => MoveFace::Right,
66            2 => MoveFace::Up,
67            3 => MoveFace::Down,
68            4 => MoveFace::Front,
69            _ => MoveFace::Back,
70        }
71    }
72}
73
74#[derive(Debug, PartialEq, Eq, Clone, Copy)]
75pub enum MoveType {
76    Double,
77    Prime,
78    Normal,
79}
80
81impl fmt::Display for MoveType {
82    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
83        match self {
84            MoveType::Double => write!(f, "2"),
85            MoveType::Prime => write!(f, "'"),
86            MoveType::Normal => write!(f, ""),
87        }
88    }
89}
90
91impl Distribution<MoveType> for StandardUniform {
92    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> MoveType {
93        match rng.random_range(0..3) {
94            0 => MoveType::Double,
95            1 => MoveType::Normal,
96            _ => MoveType::Prime,
97        }
98    }
99}
100
101#[derive(Debug, PartialEq, Eq, Clone, Copy)]
102pub enum MoveWidth {
103    Single,
104    Wide,
105    ThreeWide,
106}
107
108impl Distribution<MoveWidth> for StandardUniform {
109    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> MoveWidth {
110        match rng.random_range(0..10) {
111            0..=7 => MoveWidth::Single,
112            _ => MoveWidth::Wide,
113        }
114    }
115}
116
117impl fmt::Display for MoveWidth {
118    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
119        match self {
120            MoveWidth::Single => write!(f, ""),
121            MoveWidth::Wide => write!(f, "w"),
122            MoveWidth::ThreeWide => write!(f, ""),
123        }
124    }
125}