cube_core/cube/core/
scramble.rs

1use crate::{
2    utils::{
3        cube_utils::Axis,
4    },
5    cube::{
6        core::grid::{Grid, GridSide, MoveDirection}
7    }
8};
9
10use rand::seq::SliceRandom;
11use rand::thread_rng;
12
13struct Move {
14    mv: &'static str,
15    axis: Axis,
16}
17
18const MOVES: &[Move] = &[
19    Move { mv: "R", axis: Axis::X },
20    Move { mv: "R'", axis: Axis::X },
21    Move { mv: "R2", axis: Axis::X },
22    Move { mv: "L", axis: Axis::X },
23    Move { mv: "L'", axis: Axis::X },
24    Move { mv: "L2", axis: Axis::X },
25
26    Move { mv: "U", axis: Axis::Y },
27    Move { mv: "U'", axis: Axis::Y },
28    Move { mv: "U2", axis: Axis::Y },
29    Move { mv: "D", axis: Axis::Y },
30    Move { mv: "D'", axis: Axis::Y },
31    Move { mv: "D2", axis: Axis::Y },
32
33    Move { mv: "F", axis: Axis::Z },
34    Move { mv: "F'", axis: Axis::Z },
35    Move { mv: "F2", axis: Axis::Z },
36    Move { mv: "B", axis: Axis::Z },
37    Move { mv: "B'", axis: Axis::Z },
38    Move { mv: "B2", axis: Axis::Z },
39];
40
41fn generate_scramble(length: usize) -> Vec<&'static Move> {
42    let mut rng = thread_rng();
43    let mut scramble = Vec::with_capacity(length);
44
45    let mut last_move: Option<&Move> = None;
46    for _ in 0..length {
47        let choices: Vec<&Move> = MOVES.iter()
48            .filter(|m| {
49                match last_move {
50                    Some(prev) => prev.axis != m.axis,
51                    None => true,
52                }
53            })
54            .collect();
55
56        let selected = *choices.choose(&mut rng).unwrap();
57        scramble.push(selected);
58        last_move = Some(selected);
59    }
60
61    scramble
62}
63
64fn _print_scramble(moves: &Vec<&Move>) {
65    println!("Scramble:");
66    for &mv in moves {
67        print!("{} ", mv.mv);
68    }
69    println!();
70}
71
72fn apply_scramble(grid: &mut Grid, moves: Vec<&Move>) {
73    for mv in moves {
74        let (side_char, suffix) = mv.mv.split_at(1);
75        let side = match side_char {
76            "R" => GridSide::Right,
77            "L" => GridSide::Left,
78            "U" => GridSide::Top,
79            "D" => GridSide::Bottom,
80            "F" => GridSide::Front,
81            "B" => GridSide::Back,
82            _ => continue,
83        };
84        let direction = match suffix {
85            "" => MoveDirection::Clockwise,
86            "'" => MoveDirection::CounterClockwise,
87            "2" => {
88                grid.move_face(side, MoveDirection::Clockwise);
89                grid.move_face(side, MoveDirection::Clockwise);
90                continue;
91            },
92            _ => continue,
93        };
94
95        grid.move_face(side, direction);
96    }
97}
98
99pub fn scramble(grid: &mut Grid) {
100    let scramble = generate_scramble(20);
101    apply_scramble(grid, scramble);
102}