Skip to content

Commit 1970943

Browse files
authored
Merge pull request #1 from Earthmark/earthmark-dev
Fixed up some of the clippy findings.
2 parents 8906b0b + c0505e4 commit 1970943

1 file changed

Lines changed: 54 additions & 67 deletions

File tree

src/maze.rs

Lines changed: 54 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,64 @@ use std::{
44
rc::{Rc, Weak},
55
};
66

7+
#[allow(dead_code)]
78
#[derive(PartialEq)]
89
pub enum MazeMoveDir {
910
Forward,
1011
Backward,
1112
}
1213

13-
pub trait Maze<const DIMS: usize> {
14-
fn can_move(
15-
&self,
16-
point: &[usize; DIMS],
17-
dimension: usize,
18-
direction: MazeMoveDir,
19-
) -> Option<bool>;
20-
}
21-
22-
struct WalkMaze<const DIMS: usize> {
14+
pub struct Maze<const DIMS: usize> {
2315
walks: std::collections::HashSet<([usize; DIMS], [usize; DIMS])>,
2416
lengths: [usize; DIMS],
2517
}
2618

27-
impl<const DIMS: usize> WalkMaze<DIMS> {
19+
#[allow(dead_code)]
20+
impl<const DIMS: usize> Maze<DIMS> {
21+
// Generate a maze with the provided number of side lengths.
22+
pub fn new(lengths: &[usize; DIMS], rng: &mut impl rand::Rng) -> Maze<DIMS> {
23+
let mut maze = Maze::<DIMS> {
24+
lengths: *lengths,
25+
walks: Default::default(),
26+
};
27+
28+
let cell_count = lengths.iter().product();
29+
30+
// Indexed by dimension sums (higher is higher power).
31+
let mut cells = HashMap::<[usize; DIMS], MazeGenCellRef>::with_capacity(cell_count);
32+
for index in 0..cell_count {
33+
let pos = unwrap_index(lengths, index).unwrap();
34+
cells.insert(pos, MazeGenCell::new(index));
35+
}
36+
37+
let mut pending_edges = BinaryHeap::with_capacity(cell_count * DIMS);
38+
for index in 0..cell_count {
39+
for dim in 0..DIMS {
40+
pending_edges.push((rng.next_u32(), index, dim))
41+
}
42+
}
43+
44+
while let Some((_, target_index, dim)) = pending_edges.pop() {
45+
let a = unwrap_index(lengths, target_index).unwrap();
46+
// Skip the ends of each dimension, as that's checking outside the bounds of the space.
47+
// In the future do this check on insertion into the heap.
48+
if a[dim] == lengths[dim] {
49+
continue;
50+
}
51+
let mut b = a;
52+
b[dim] += 1;
53+
if let Some(cell_a) = cells.get(&a) {
54+
if let Some(cell_b) = cells.get(&b) {
55+
if MazeGenCell::try_merge(cell_a, cell_b) {
56+
maze.walks.insert((a, b));
57+
}
58+
}
59+
}
60+
}
61+
62+
maze
63+
}
64+
2865
fn check_pair(&self, a: &[usize; DIMS], b: &[usize; DIMS]) -> Option<bool> {
2966
for index in 0..DIMS {
3067
let length = self.lengths[index];
@@ -35,21 +72,16 @@ impl<const DIMS: usize> WalkMaze<DIMS> {
3572

3673
// Check for either direction because it's cheaper to check twice
3774
// than store an exponential memory problem.
38-
return Some(
39-
self.walks.contains(&(a.clone(), b.clone()))
40-
|| self.walks.contains(&(b.clone(), a.clone())),
41-
);
75+
Some(self.walks.contains(&(*a, *b)) || self.walks.contains(&(*b, *a)))
4276
}
43-
}
4477

45-
impl<const DIMS: usize> Maze<DIMS> for WalkMaze<DIMS> {
46-
fn can_move(
78+
pub fn can_move(
4779
&self,
4880
point: &[usize; DIMS],
4981
dimension: usize,
5082
direction: MazeMoveDir,
5183
) -> Option<bool> {
52-
let mut target_point = point.clone();
84+
let mut target_point = *point;
5385
if let Some(shift_axis) = target_point.get_mut(dimension) {
5486
if let Some(new_shifted) = match direction {
5587
MazeMoveDir::Forward => shift_axis.checked_add(1),
@@ -59,7 +91,7 @@ impl<const DIMS: usize> Maze<DIMS> for WalkMaze<DIMS> {
5991
return self.check_pair(point, &target_point);
6092
}
6193
}
62-
return None;
94+
None
6395
}
6496
}
6597

@@ -115,51 +147,6 @@ fn unwrap_index<const DIMS: usize>(lengths: &[usize; DIMS], index: usize) -> Opt
115147
}
116148
}
117149

118-
// Generate a maze with the provided number of side lengths.
119-
pub fn generate_maze<const DIMS: usize>(
120-
lengths: &[usize; DIMS],
121-
rng: &mut impl rand::Rng,
122-
) -> impl Maze<DIMS> {
123-
let mut maze = WalkMaze::<DIMS> {
124-
lengths: lengths.clone(),
125-
walks: Default::default(),
126-
};
127-
128-
let cell_count = lengths.iter().product();
129-
130-
// Indexed by dimension sums (higher is higher power).
131-
let mut cells = HashMap::<[usize; DIMS], MazeGenCellRef>::with_capacity(cell_count);
132-
for index in 0..cell_count {
133-
let pos = unwrap_index(lengths, index).unwrap();
134-
cells.insert(pos, MazeGenCell::new(index));
135-
}
136-
137-
let mut pending_edges = BinaryHeap::with_capacity(cell_count * DIMS);
138-
for index in 0..cell_count {
139-
for dim in 0..DIMS {
140-
pending_edges.push((rng.next_u32(), index, dim))
141-
}
142-
}
143-
144-
while let Some((_, target_index, dim)) = pending_edges.pop() {
145-
let a = unwrap_index(lengths, target_index).unwrap();
146-
if a[dim] == lengths[dim] {
147-
continue;
148-
}
149-
let mut b = a.clone();
150-
b[dim] += 1;
151-
if let Some(cell_a) = cells.get(&a) {
152-
if let Some(cell_b) = cells.get(&b) {
153-
if MazeGenCell::try_merge(cell_a, cell_b) {
154-
maze.walks.insert((a, b));
155-
}
156-
}
157-
}
158-
}
159-
160-
maze
161-
}
162-
163150
#[cfg(test)]
164151
mod tests {
165152
use super::*;
@@ -203,7 +190,7 @@ mod tests {
203190
#[test]
204191
fn verify_generates() {
205192
let mut rng = StdRng::seed_from_u64(684153987);
206-
let maze = generate_maze(&[5, 5, 5, 5, 5], &mut rng);
193+
let maze = Maze::new(&[5, 5, 5, 5, 5], &mut rng);
207194

208195
assert_eq!(
209196
maze.can_move(&[1, 2, 3214, 2, 2], 2, MazeMoveDir::Forward),
@@ -214,7 +201,7 @@ mod tests {
214201
#[test]
215202
fn verify_generates_single() {
216203
let mut rng = StdRng::seed_from_u64(684153987);
217-
let maze = generate_maze(&[5, 1, 1], &mut rng);
204+
let maze = Maze::new(&[5, 1, 1], &mut rng);
218205

219206
assert_eq!(
220207
maze.can_move(&[0, 0, 0], 0, MazeMoveDir::Forward),

0 commit comments

Comments
 (0)