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, &mut rng, ); 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 } fn bfs_make_maze(position: (usize, usize), maze: &mut Vec>, rng: &mut Rng) { maze[position.0][position.1].2 = true; 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); } 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); } } } 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() } }