Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use rand::prelude::*;
- // Constants for the dimensions of the maze.
- const WIDTH: usize = 30;
- const HEIGHT: usize = 30;
- // The index of the current row being generated.
- static mut CURRENT_ROW: usize = 0;
- // Row information arrays.
- static mut GROUP: [usize; WIDTH] = [0usize; WIDTH];
- static mut WALL: [bool; WIDTH] = [false; WIDTH];
- static mut FLOOR: [bool; WIDTH] = [false; WIDTH];
- // Probabilities for building walls and floors.
- // Wall parameter can be tweaked to introduce bias toward walls or floors.
- const WALL_P: f32 = 0.5;
- const FLOOR_P: f32 = 1.0 - WALL_P;
- // Counter for allocating group IDs.
- static mut COUNTER: usize = 0;
- // Helper function for allocating cell groups, automatically increments COUNTER.
- fn next_group() -> usize {
- unsafe {
- let tmp = COUNTER;
- COUNTER += 1;
- return tmp;
- }
- }
- // returns true or false based on weighted coin flip.
- fn choose(threshold: f32) -> bool {
- let mut rng = rand::thread_rng();
- let sample: f32 = rng.gen();
- return sample < threshold;
- }
- unsafe fn is_first_row() -> bool {
- return CURRENT_ROW == 0;
- }
- unsafe fn is_last_row() -> bool {
- return CURRENT_ROW == HEIGHT - 1;
- }
- fn draw_ceiling() {
- for _ in 0..WIDTH {
- print!(" ___");
- }
- println!("");
- }
- unsafe fn draw_row() {
- print!("|");
- for i in 0..WIDTH {
- let f = if FLOOR[i] { "_" } else { " " };
- let w = if WALL[i] { "|" } else { " " };
- print!("{f}{f}{f}{w}", f=f, w=w);
- }
- println!("");
- }
- unsafe fn prep_row() {
- if is_first_row() {
- for i in 0..WIDTH {
- GROUP[i] = next_group();
- }
- } else {
- for i in 0..WIDTH {
- WALL[i] = false;
- if FLOOR[i] {
- FLOOR[i] = false;
- GROUP[i] = next_group();
- }
- }
- }
- }
- unsafe fn add_walls() {
- for i in 0..WIDTH {
- if i == WIDTH - 1 || (!is_first_row() && GROUP[i] == GROUP[i+1]) || choose(WALL_P) {
- WALL[i] = true;
- } else {
- GROUP[i+1] = GROUP[i];
- }
- }
- }
- unsafe fn add_floors() {
- unsafe fn add_floors_to_group(group_start: usize, group_end: usize) {
- let mut open_floors = group_end - group_start;
- let mut i = group_start;
- while open_floors > 1 && i < group_end {
- if choose(FLOOR_P) {
- FLOOR[i] = true;
- open_floors -= 1;
- }
- i += 1;
- }
- }
- let mut i = 0;
- let mut curr_group = GROUP[0];
- let mut curr_group_start = 0;
- while i <= WIDTH {
- if i == WIDTH {
- add_floors_to_group(curr_group_start, i);
- } else if is_last_row() {
- FLOOR[i] = true;
- } else if GROUP[i] != curr_group {
- add_floors_to_group(curr_group_start, i);
- curr_group = GROUP[i];
- curr_group_start = i;
- }
- i += 1;
- }
- }
- fn main() {
- draw_ceiling();
- unsafe {
- while CURRENT_ROW < HEIGHT {
- prep_row();
- add_walls();
- add_floors();
- // Do special wall cleanup on the last row
- if is_last_row() {
- for i in 0..WIDTH-1 {
- if WALL[i] && GROUP[i] != GROUP[i+1] {
- WALL[i] = false;
- }
- }
- }
- draw_row();
- CURRENT_ROW += 1;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement