-------------------------------------------------------------------------- -- Maze 19991109 <> 20020509 by Joe Wingbermuehle -- This is a random maze generator -------------------------------------------------------------------------- with Ada.Text_IO; use Ada.Text_IO; with Ada.Integer_Text_IO; use Ada.Integer_Text_IO; with Ada.Numerics.Discrete_Random; with Ada.Calendar; use Ada.Calendar; with Ada.Command_Line; procedure Maze is Block : constant string := "[]"; -- Block for maze Space : constant string := " "; -- Blank space for maze Release : constant string := "20020509"; -- Release date subtype Random_Range is integer range 0 .. 3; package Random4 is new Ada.Numerics.Discrete_Random(Random_Range); type Array_Type is array(positive range <>, positive range <>) of integer range 0..1; type Array_Pointer is access Array_Type; maze : Array_Pointer; -- The maze array seed : Random4.Generator; -- Random number seed width : integer range 1 .. integer'last; -- Maze width height : integer range 1 .. integer'last; -- Maze height ------------------------------------------------------------------ -- Display the maze ------------------------------------------------------------------ procedure Display_Maze is begin for j in 1 .. height loop for k in 1 .. width loop if maze(j, k) = 0 then Put(Block); else Put(Space); end if; end loop; New_Line; end loop; end Display_Maze; ------------------------------------------------------------------ -- Initialize the maze array ------------------------------------------------------------------ procedure Initialize_Board is begin for j in 1 .. height loop for k in 2 .. width - 1 loop maze(j, k) := 0; end loop; maze(j, 1) := 1; maze(j, width) := 1; end loop; for k in 1 .. width loop maze(1, k) := 1; maze(height, k) := 1; end loop; maze(3, 3) := 1; end Initialize_Board; ------------------------------------------------------------------ -- Carve out a section of the maze ------------------------------------------------------------------ procedure Carve_Maze(startx : in integer; starty : in integer) is d : integer range 0 .. 3; -- Direction j : integer range 0 .. 5; -- Number of directions tried x : integer; -- Carving x position y : integer; -- Carving y position begin x := startx; y := starty; j := 0; d := Random4.Random(seed); if maze(x, y) = 0 then return; end if; loop case d is when 0 => if maze(x + 1, y) + maze(x + 2, y) = 0 then maze(x + 1, y) := 1; x := x + 2; j := 0; end if; when 1 => if maze(x - 1, y) + maze(x - 2, y) = 0 then maze(x - 1, y) := 1; x := x - 2; j := 0; end if; when 2 => if maze(x, y + 1) + maze(x, y + 2) = 0 then maze(x, y + 1) := 1; y := y + 2; j := 0; end if; when 3 => if maze(x, y - 1) + maze(x, y - 2) = 0 then maze(x, y - 1) := 1; y := y - 2; j := 0; end if; end case; if j = 0 then maze(x, y) := 1; d := Random4.Random(seed); else d := (d + 1) rem 4; exit when j = 5; end if; j := j + 1; end loop; end Carve_Maze; ------------------------------------------------------------------ -- Generate the maze ------------------------------------------------------------------ procedure Generate_Maze is begin Initialize_Board; for j in 2 .. height / 2 loop for k in 2 .. width / 2 loop Carve_Maze(2 * j - 1, 2 * k - 1); end loop; end loop; maze(3, 2) := 1; maze(height - 2, width - 1) := 1; end Generate_Maze; begin -- Display the header Put("Maze " & Release & " by Joe Wingbermuehle"); New_Line; if Ada.Command_Line.Argument_Count /= 2 then Put_Line("usage: " & Ada.Command_Line.Command_Name & " "); return; end if; -- Read the size from the command line begin width := integer'value(Ada.Command_Line.Argument(1)); height := integer'value(Ada.Command_Line.Argument(2)); exception when others => Put_Line("Invalid size"); return; end; -- Create the maze array height := height * 2 + 3; width := width * 2 + 3; maze := new Array_Type(1 .. height, 1 .. width); -- Generate the maze Random4.Reset(seed, integer(Seconds(Clock))); Generate_Maze; Display_Maze; end Maze;