source: trunk/class/mazebuilderdepthfirst.pas

Last change on this file was 1, checked in by chronos, 11 years ago
  • Import original code of Lazes 0.1 by Nijland (eny)

http://wiki.lazarus.freepascal.org/Lazarus_Mazes_demo

File size: 3.8 KB
Line 
1{
2 Maze builder class of the Lazarus Mazes program.
3
4 For more detais on the implementation, see wikipedia:
5 http://en.wikipedia.org/wiki/Maze_generation_algorithm#Recursive_backtracker
6
7 Copyright (C) 2012 G.A. Nijland (eny @ lazarus forum http://www.lazarus.freepascal.org/)
8
9 This source is free software; you can redistribute it and/or modify it under the terms of the GNU General Public
10 License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later
11 version.
12
13 This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
14 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
15 details.
16
17 A copy of the GNU General Public License is available on the World Wide Web at
18 <http://www.gnu.org/copyleft/gpl.html>. You can also obtain it by writing to the Free Software Foundation, Inc., 59
19 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20}
21unit MazeBuilderDepthFirst;
22
23{$mode objfpc}{$H+}
24
25interface
26
27uses
28 Maze,
29 Classes, SysUtils;
30
31type
32
33 { TMazeBuilderDepthFirst }
34
35 TMazeBuilderDepthFirst = class
36 private
37 Queue: TFPList;
38
39 procedure ProcessCell(pCell: TMazeCell);
40 function ExtractFromQueue(const pIndex: integer): TMazeCell;
41
42 public
43 function BuildMaze(const pWidth, pHeight: integer;
44 const pStartRow: integer = 0; const pStartCol: integer = 0): TMaze;
45 end;
46
47implementation
48
49{ TMazeBuilderDepthFirst }
50
51// Retrieve the requested element from the backtrack queue and delete it
52// from the queue so it doesn't get processed anymore.
53function TMazeBuilderDepthFirst.ExtractFromQueue(const pIndex: integer): TMazeCell;
54begin
55 result := TMazeCell(Queue[pIndex]);
56 Queue.Delete(pIndex);
57end;
58
59
60// Scant the given cell for all neighbours and generate a new path
61// for those neighbours in a random way.
62procedure TMazeBuilderDepthFirst.ProcessCell(pCell: TMazeCell);
63
64 // Check if the cell is valid and available for the next step
65 procedure CheckForAvailability(const pCell: TMazeCell);
66 begin
67 if assigned(pCell) then
68 if pCell.Tag = 0 then
69 Queue.Add(pCell)
70 end;
71
72var EOQ : integer; // End Of Queue
73 cell: TMazeCell; // Next cell to visit
74 dir : TDirection; // Loop control var
75begin
76 // Set the cell as visited
77 pCell.Tag := 1;
78
79 // Remember where we are in the queue
80 EOQ := Queue.Count;
81
82 // Find all neighbours that have not been visited yet
83 for dir in TDirection do
84 CheckForAvailability(pCell.Neighbour[dir]);
85
86 // Process all neighbours that were found (and added to the queue)
87 while Queue.Count <> EOQ do
88 begin
89 // If only 1 then use that one else select one randomly.
90 if EOQ = Queue.Count-1 then
91 Cell := ExtractFromQueue(Queue.Count-1)
92 else
93 Cell := ExtractFromQueue(EOQ + random(Queue.Count - EOQ));
94
95 // Determine the direction and enable that direction, but do check if
96 // this cell has not been processed in the mean time via another route!
97 if Cell.Tag = 0 then
98 begin
99 for dir in TDirection do
100 if Cell.Neighbour[dir] = pCell then
101 begin
102 Cell.CanGo[dir] := true;
103 break
104 end;
105
106 // Process neighbours of this one
107 ProcessCell(Cell);
108 end;
109 end;
110end;
111
112function TMazeBuilderDepthFirst.BuildMaze(const pWidth, pHeight: integer; const pStartRow: integer;
113 const pStartCol: integer): TMaze;
114begin
115 // Init the queue that will hold cells for backtracking
116 Queue := TFPList.Create;
117
118 // Create a new maze object and populate it
119 result := TMaze.Create(pWidth, pHeight);
120 result.SetStartCell(pStartRow, pStartCol);
121 ProcessCell(result.StartCell);
122
123 // Clean up
124 Queue.Free;
125end;
126
127end.
128
Note: See TracBrowser for help on using the repository browser.