2024-08-15 16:12:41 +00:00
|
|
|
use std::time::{SystemTime, UNIX_EPOCH};
|
|
|
|
|
|
|
|
pub fn draw_maze(height: usize, width: usize) -> String {
|
|
|
|
let mut maze = vec![vec![(false, false, false); width]; height];
|
|
|
|
let mut rng = Rng::new();
|
|
|
|
|
|
|
|
bfs_make_maze(
|
|
|
|
(
|
|
|
|
rng.random_number(0, height as u128) as usize,
|
|
|
|
rng.random_number(0, width as u128) as usize,
|
|
|
|
),
|
|
|
|
&mut maze,
|
2024-08-15 19:45:17 +00:00
|
|
|
&mut rng,
|
2024-08-15 16:12:41 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
let mut res = "+---".repeat(width) + "+";
|
|
|
|
for c in 0..height {
|
|
|
|
res = format!("{}\n|", res);
|
|
|
|
for r in maze.get(c).unwrap() {
|
|
|
|
res = format!("{} ", res);
|
|
|
|
if r.1 {
|
|
|
|
res = format!("{} ", res);
|
|
|
|
} else {
|
|
|
|
res = format!("{}|", res);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
res = format!("{}\n+", res);
|
|
|
|
for r in maze.get(c).unwrap() {
|
|
|
|
if r.0 {
|
|
|
|
res = format!("{} +", res);
|
|
|
|
} else {
|
|
|
|
res = format!("{}---+", res);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
res
|
|
|
|
}
|
|
|
|
|
2024-08-15 19:45:17 +00:00
|
|
|
fn bfs_make_maze(position: (usize, usize), maze: &mut Vec<Vec<(bool, bool, bool)>>, rng: &mut Rng) {
|
2024-08-15 16:12:41 +00:00
|
|
|
maze[position.0][position.1].2 = true;
|
2024-08-15 19:45:17 +00:00
|
|
|
let mut nums = [0, 1, 2, 3];
|
|
|
|
for i in (0..4).rev() {
|
|
|
|
let rand_index = rng.random_number(0, i + 1);
|
|
|
|
nums.swap(rand_index as usize, i as usize);
|
2024-08-15 16:12:41 +00:00
|
|
|
}
|
2024-08-15 19:45:17 +00:00
|
|
|
for num in nums {
|
|
|
|
if num == 0 && position.1 + 1 < maze[0].len() && !maze[position.0][position.1 + 1].2 {
|
|
|
|
let mut new_position = position;
|
|
|
|
new_position.1 += 1;
|
|
|
|
maze[position.0][position.1].1 = true;
|
|
|
|
bfs_make_maze(new_position, maze, rng);
|
|
|
|
}
|
|
|
|
if num == 1 && position.1 > 0 && !maze[position.0][position.1 - 1].2 {
|
|
|
|
let mut new_position = position;
|
|
|
|
new_position.1 -= 1;
|
|
|
|
maze[new_position.0][new_position.1].1 = true;
|
|
|
|
bfs_make_maze(new_position, maze, rng);
|
|
|
|
}
|
|
|
|
if num == 2 && position.0 + 1 < maze.len() && !maze[position.0 + 1][position.1].2 {
|
|
|
|
let mut new_position = position;
|
|
|
|
new_position.0 += 1;
|
|
|
|
maze[position.0][position.1].0 = true;
|
|
|
|
bfs_make_maze(new_position, maze, rng);
|
|
|
|
}
|
|
|
|
if num == 3 && position.0 > 0 && !maze[position.0 - 1][position.1].2 {
|
|
|
|
let mut new_position = position;
|
|
|
|
new_position.0 -= 1;
|
|
|
|
maze[new_position.0][new_position.1].0 = true;
|
|
|
|
bfs_make_maze(new_position, maze, rng);
|
|
|
|
}
|
2024-08-15 16:12:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct Rng {
|
|
|
|
seed: u128,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Rng {
|
|
|
|
pub fn new() -> Rng {
|
|
|
|
let time_since_epoch = SystemTime::now()
|
|
|
|
.duration_since(UNIX_EPOCH)
|
|
|
|
.expect("Error in getting time")
|
|
|
|
.as_millis();
|
|
|
|
Rng {
|
|
|
|
seed: time_since_epoch,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn linear_congruent_generator(&mut self, a: u128, c: u128, m: u128) -> u128 {
|
|
|
|
let result = (a * self.seed + c) % m;
|
|
|
|
self.seed = result;
|
|
|
|
result
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn random_number(&mut self, from: u128, to: u128) -> u128 {
|
|
|
|
let random_number = self.linear_congruent_generator(1103515245, 12345, 2u128.pow(31));
|
|
|
|
(random_number % (to - from)) + from
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for Rng {
|
|
|
|
fn default() -> Self {
|
|
|
|
Self::new()
|
|
|
|
}
|
|
|
|
}
|