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}