Maze generation: Difference between revisions

→‎{{header|Ada}}: Neighbouring cells are tested only once.
(→‎{{header|Ada}}: Simplified way of detecting unvisited neighbours.)
(→‎{{header|Ada}}: Neighbouring cells are tested only once.)
Line 51:
<lang Ada>with Ada.Numerics.Discrete_Random;
with Ada.Text_IO;
 
package body Mazes is
package RNG is new Ada.Numerics.Discrete_Random (Positive);
package Random_Direction is new Ada.Numerics.Discrete_Random (Directions);
 
Generator : RNG.Generator;
Dir_Generator : Random_Direction.Generator;
 
function "-" (Dir : Directions) return Directions;
 
procedure Depth_First_Algorithm
(Maze : in out Maze_Grid;
Row : Height_Type;
Column : Width_Type);
 
procedure Move
(Row : in out Height_Type;
Column : in out Width_Type;
Direction : Directions;
Valid_Move : out Boolean);
 
function "-" (Dir : Directions) return Directions is
begin
Line 85 ⟶ 72:
end case;
end "-";
 
procedure Move
(Row : in out Height_Type;
Column : in out Width_Type;
Direction : Directions;
Valid_Move : out Boolean)
is
begin
Valid_Move := False;
case Direction is
when North =>
if Row > Height_Type'First then
Valid_Move := True;
Row := Row - 1;
end if;
when East =>
if Column < Width_Type'Last then
Valid_Move := True;
Column := Column + 1;
end if;
when West =>
if Column > Width_Type'First then
Valid_Move := True;
Column := Column - 1;
end if;
when South =>
if Row < Height_Type'Last then
Valid_Move := True;
Row := Row + 1;
end if;
end case;
end Move;
procedure Depth_First_Algorithm
(Maze : in out Maze_Grid;
Line 100 ⟶ 119:
-- mark as visited
Maze (Row, Column).Visited := True;
-- continue as long as there are unvisited neighbours left
loop
All_Tested-- :=use True;random direction
for D in Directions loop
All_Tested Next_Direction := All_Tested and Tested_WallRandom_Direction.Random (DDir_Generator);
exit when not Tested_Wall (Next_Direction);
end loop;
-- all directions are either visited from here,
-- or previously visited, or invalid.
exit when All_Tested;
-- use random direction
Next_Direction := Random_Direction.Random (Dir_Generator);
Next_Row := Row;
Next_Column := Column;
Move (Next_Row, Next_Column, Next_Direction, Valid_Direction);
if Valid_Direction then
-- connect the two cells
if not Maze (Next_Row, Next_Column).Visited then
-- connect the two cells
Maze (Row, Column).Walls (Next_Direction) :=
False;
Line 125 ⟶ 139:
end if;
Tested_Wall (Next_Direction) := True;
-- continue as long as there are unvisited neighbours left
All_Tested := True;
for D in Directions loop
All_Tested := All_Tested and Tested_Wall (D);
end loop;
-- all directions are either visited (from here,
-- or previously visited), or invalid.
exit when All_Tested;
end loop;
end Depth_First_Algorithm;
 
procedure Initialize (Maze : in out Maze_Grid) is
Row, Column : Positive;
Line 144 ⟶ 166:
Depth_First_Algorithm (Maze, Row, Column);
end Initialize;
 
procedure Move
(Row : in out Height_Type;
Column : in out Width_Type;
Direction : Directions;
Valid_Move : out Boolean)
is
begin
Valid_Move := False;
case Direction is
when North =>
if Row > Height_Type'First then
Valid_Move := True;
Row := Row - 1;
end if;
when East =>
if Column < Width_Type'Last then
Valid_Move := True;
Column := Column + 1;
end if;
when West =>
if Column > Width_Type'First then
Valid_Move := True;
Column := Column - 1;
end if;
when South =>
if Row < Height_Type'Last then
Valid_Move := True;
Row := Row + 1;
end if;
end case;
end Move;
 
procedure Put (Item : Maze_Grid) is
begin
for Row in Item'Range (1) loop
if Row = Item'First (1) then
Ada.Text_IO.Put ('+');
for Col in Item'Range (2) loop
if Col = Item'First (2) then
Ada.Text_IO.Put ('+');
end if;
if Item (Row, Col).Walls (North) then
Ada.Text_IO.Put ("---+");
else
Ada.Text_IO.Put (" +");
end if;
Ada.Text_IO.Put ('+');
end loop;
Ada.Text_IO.New_Line;
Line 216 ⟶ 203:
else
Ada.Text_IO.Put ("???");
end if;
if Col = Item'Last (2) then
if Item (Row, Col).Walls (East) then
Ada.Text_IO.Put ('|');
else
Ada.Text_IO.Put (' ');
end if;
end if;
end loop;
if Item (Row, Item'Last (2)).Walls (East) then
Ada.Text_IO.New_Line;
Ada.Text_IO.Put_Line ("|");
else
Ada.Text_IO.Put_Line (" ");
end if;
Ada.Text_IO.Put ('+');
for Col in Item'Range (2) loop
--for Col in Item'Range (2) loop
if Col = Item'First (2) then
Ada.Text_IO.Put ('+');
end if;
if Item (Row, Col).Walls (South) then
Ada.Text_IO.Put ("---+");
else
Ada.Text_IO.Put (" +");
end if;
Ada.Text_IO.Put ('+');
--end loop;
end loop;
Ada.Text_IO.New_Line;
end loop;
end Put;
end Mazes;</lang>
</lang>
Example main.adb:
<lang Ada>with Mazes;
Anonymous user