mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-22 07:10:42 -08:00
add 00_Alternate_Langage folder and move alternate ports there
This commit is contained in:
279
00_Alternate_Languages/02_Amazing/pascal/object-pascal/maze.pas
Normal file
279
00_Alternate_Languages/02_Amazing/pascal/object-pascal/maze.pas
Normal file
@@ -0,0 +1,279 @@
|
||||
unit Maze;
|
||||
|
||||
{$IFDEF FPC}
|
||||
{$mode ObjFPC}{$H+}
|
||||
{$ENDIF}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes
|
||||
, SysUtils
|
||||
, Room
|
||||
;
|
||||
|
||||
type
|
||||
TDirection = (dUp, dRight, dDown, dLeft);
|
||||
TDirections = set of TDirection;
|
||||
{ TMaze }
|
||||
TMaze = class(TObject)
|
||||
private
|
||||
FWidth: Integer;
|
||||
FLength: Integer;
|
||||
FEntry: Integer;
|
||||
FLabyrinth: Array of Array of TRoom;
|
||||
|
||||
function GetRandomDirection(const ADirections: TDirections): TDirection;
|
||||
|
||||
procedure DebugVisited;
|
||||
procedure DebugWalls;
|
||||
protected
|
||||
public
|
||||
constructor Create(const AWidth, ALength: Integer);
|
||||
destructor Destroy; override;
|
||||
|
||||
procedure Build;
|
||||
procedure Print;
|
||||
published
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
const
|
||||
EXIT_DOWN = 1;
|
||||
EXIT_RIGHT = 2;
|
||||
|
||||
{ TMaze }
|
||||
|
||||
function TMaze.GetRandomDirection(const ADirections: TDirections): TDirection;
|
||||
var
|
||||
count: Integer;
|
||||
position: Integer;
|
||||
directions: array [0..3] of TDirection;
|
||||
begin
|
||||
count:= 0;
|
||||
position:= 0;
|
||||
if dUp in ADirections then
|
||||
begin
|
||||
Inc(count);
|
||||
directions[position]:= dUp;
|
||||
Inc(position);
|
||||
end;
|
||||
if dRight in ADirections then
|
||||
begin
|
||||
Inc(count);
|
||||
directions[position]:= dRight;
|
||||
Inc(position);
|
||||
end;
|
||||
if dDown in ADirections then
|
||||
begin
|
||||
Inc(count);
|
||||
directions[position]:= dDown;
|
||||
Inc(position);
|
||||
end;
|
||||
if dLeft in ADirections then
|
||||
begin
|
||||
Inc(count);
|
||||
directions[position]:= dLeft;
|
||||
Inc(position);
|
||||
end;
|
||||
Result:= directions[Random(count)];
|
||||
end;
|
||||
|
||||
procedure TMaze.DebugVisited;
|
||||
var
|
||||
indexW: Integer;
|
||||
indexL: Integer;
|
||||
begin
|
||||
WriteLN('Visited');
|
||||
for indexL:= 0 to Pred(FLength) do
|
||||
begin
|
||||
for indexW:= 0 to Pred(FWidth) do
|
||||
begin
|
||||
Write(FLabyrinth[indexW][indexL].Visited:3,' ');
|
||||
end;
|
||||
WriteLN;
|
||||
end;
|
||||
WriteLN;
|
||||
end;
|
||||
|
||||
procedure TMaze.DebugWalls;
|
||||
var
|
||||
indexW: Integer;
|
||||
indexL: Integer;
|
||||
begin
|
||||
WriteLN('Walls');
|
||||
for indexL:= 0 to Pred(FLength) do
|
||||
begin
|
||||
for indexW:= 0 to Pred(FWidth) do
|
||||
begin
|
||||
Write(FLabyrinth[indexW][indexL].Walls:3,' ');
|
||||
end;
|
||||
WriteLN;
|
||||
end;
|
||||
WriteLN;
|
||||
end;
|
||||
|
||||
constructor TMaze.Create(const AWidth, ALength: Integer);
|
||||
var
|
||||
indexW: Integer;
|
||||
indexL: Integer;
|
||||
begin
|
||||
Randomize;
|
||||
FWidth:= AWidth;
|
||||
FLength:= ALength;
|
||||
FEntry:= Random(FWidth);
|
||||
SetLength(FLabyrinth, FWidth, FLength);
|
||||
for indexW:= 0 to Pred(FWidth) do
|
||||
begin
|
||||
for indexL:= 0 to Pred(FLength) do
|
||||
begin
|
||||
FLabyrinth[indexW][indexL]:= TRoom.Create;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
destructor TMaze.Destroy;
|
||||
var
|
||||
indexW: Integer;
|
||||
indexL: Integer;
|
||||
begin
|
||||
for indexW:= 0 to Pred(FWidth) do
|
||||
begin
|
||||
for indexL:= 0 to Pred(FLength) do
|
||||
begin
|
||||
if Assigned(FLabyrinth[indexW][indexL]) then
|
||||
begin
|
||||
FLabyrinth[indexW][indexL].Free;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TMaze.Build;
|
||||
var
|
||||
indexW: Integer;
|
||||
indexL: Integer;
|
||||
direction: TDirection;
|
||||
directions: TDirections;
|
||||
count: Integer;
|
||||
begin
|
||||
FEntry:= Random(FWidth);
|
||||
indexW:= FEntry;
|
||||
indexL:= 0;
|
||||
count:= 1;
|
||||
FLabyrinth[indexW][indexL].Visited:= count;
|
||||
Inc(count);
|
||||
repeat
|
||||
directions:= [dUp, dRight, dDown, dLeft];
|
||||
if (indexW = 0) or (FLabyrinth[Pred(indexW)][indexL].Visited <> 0) then
|
||||
begin
|
||||
Exclude(directions, dLeft);
|
||||
end;
|
||||
if (indexL = 0) or (FLabyrinth[indexW][Pred(indexL)].Visited <> 0) then
|
||||
begin
|
||||
Exclude(directions, dUp);
|
||||
end;
|
||||
if (indexW = Pred(FWidth)) or (FLabyrinth[Succ(indexW)][indexL].Visited <> 0) then
|
||||
begin
|
||||
Exclude(directions, dRight);
|
||||
end;
|
||||
if (indexL = Pred(FLength)) or (FLabyrinth[indexW][Succ(indexL)].Visited <> 0) then
|
||||
begin
|
||||
Exclude(directions, dDown);
|
||||
end;
|
||||
|
||||
if directions <> [] then
|
||||
begin
|
||||
direction:= GetRandomDirection(directions);
|
||||
case direction of
|
||||
dLeft:begin
|
||||
Dec(indexW);
|
||||
FLabyrinth[indexW][indexL].Walls:= EXIT_RIGHT;
|
||||
end;
|
||||
dUp:begin
|
||||
Dec(indexL);
|
||||
FLabyrinth[indexW][indexL].Walls:= EXIT_DOWN;
|
||||
end;
|
||||
dRight:begin
|
||||
FLabyrinth[indexW][indexL].Walls:= FLabyrinth[indexW][indexL].Walls + EXIT_RIGHT;
|
||||
Inc(indexW);
|
||||
end;
|
||||
dDown:begin
|
||||
FLabyrinth[indexW][indexL].Walls:= FLabyrinth[indexW][indexL].Walls + EXIT_DOWN;
|
||||
Inc(indexL);
|
||||
end;
|
||||
end;
|
||||
FLabyrinth[indexW][indexL].Visited:= count;
|
||||
Inc(count);
|
||||
end
|
||||
else
|
||||
begin
|
||||
while True do
|
||||
begin
|
||||
if indexW <> Pred(FWidth) then
|
||||
begin
|
||||
Inc(indexW);
|
||||
end
|
||||
else if indexL <> Pred(FLength) then
|
||||
begin
|
||||
Inc(indexL);
|
||||
indexW:= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
indexW:= 0;
|
||||
indexL:= 0;
|
||||
end;
|
||||
if FLabyrinth[indexW][indexL].Visited <> 0 then
|
||||
begin
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
until count = (FWidth * FLength) + 1;
|
||||
indexW:= Random(FWidth);
|
||||
indexL:= Pred(FLength);
|
||||
FLabyrinth[indexW][indexL].Walls:= FLabyrinth[indexW][indexL].Walls + 1;
|
||||
end;
|
||||
|
||||
procedure TMaze.Print;
|
||||
var
|
||||
indexW:Integer;
|
||||
indexL: Integer;
|
||||
begin
|
||||
|
||||
//DebugVisited;
|
||||
//DebugWalls;
|
||||
|
||||
for indexW:= 0 to Pred(FWidth) do
|
||||
begin
|
||||
if indexW = FEntry then
|
||||
begin
|
||||
Write('. ');
|
||||
end
|
||||
else
|
||||
begin
|
||||
Write('.--');
|
||||
end;
|
||||
end;
|
||||
WriteLN('.');
|
||||
|
||||
for indexL:= 0 to Pred(FLength) do
|
||||
begin
|
||||
Write('I');
|
||||
for indexW:= 0 to Pred(FWidth) do
|
||||
begin
|
||||
FLabyrinth[indexW][indexL].PrintRoom;
|
||||
end;
|
||||
WriteLN;
|
||||
for indexW:= 0 to Pred(FWidth) do
|
||||
begin
|
||||
FLabyrinth[indexW][indexL].PrintWall;
|
||||
end;
|
||||
WriteLN('.');
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
Reference in New Issue
Block a user