- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
// 1 - ая часть
uses Graph,CRT;
const WindSize = 10;
SizeX=63;
SizeY=48;
dx : array [0..3] of integer = (0,0,-1,1);
dy : array [0..3] of integer = (-1,1,0,0);
type
PRec = ^TPoint;
TPoint = record // Запись необработанного блока
mX,mY : integer;
mNext : PRec;
end;
var
Maze: array [0..SizeX-1] of array [0..SizeY-1] of integer;
Stack : PRec;
procedure Push(const aX,aY : integer);
var p : PRec;
begin
New(p);
p^.mX:= aX;
p^.mY:= aY;
{ Размещаем в голове стека }
p^.mNext:=Stack;
Stack:=p;
end;
function Pop(var aX,aY : integer): boolean;
var p : PRec;
begin
Pop:=Assigned(Stack);
if Assigned(Stack) then
begin
aX:= Stack^.mX;
aY:= Stack^.mY;
p:=Stack; { Временно сохраняем указатель на голову}
Stack:= Stack^.mNext;
Dispose(p); { удаляем ненужный элемент }
end;
end;
procedure InvertDraw;
var x,y: integer;
begin
SetColor(0);
for x:=1 to SizeX-2 do
for y:=1 to SizeY-2 do
begin
if ((maze[x][y] and 1) = 0) then
Line(x * WindSize, y * WindSize, x * WindSize + WindSize + 1, y * WindSize);
if ((maze[x][y] and 2) = 0) then
Line(x * WindSize, y * WindSize + WindSize, x * WindSize + WindSize + 1, y * WindSize + WindSize);
if ((maze[x][y] and 4) = 0) then
Line(x * WindSize, y * WindSize, x * WindSize, y * WindSize + WindSize + 1);
if ((maze[x][y] and 8) = 0) then
Line(x * WindSize + WindSize, y * WindSize, x * WindSize + WindSize, y * WindSize + WindSize + 1);
end;
end;
procedure InitMaze; { Генерация лабиринта }
var x,y,dir: integer; { dir - направление }
s : set of byte;
begin
for x:=1 to SizeX-2 do
for y:=1 to SizeY-2 do
begin
Line(x * WindSize, y * WindSize, x * WindSize + WindSize + 1, y * WindSize);
Line(x * WindSize, y * WindSize + WindSize, x * WindSize + WindSize + 1, y * WindSize + WindSize);
Line(x * WindSize, y * WindSize, x * WindSize, y * WindSize + WindSize + 1);
Line(x * WindSize + WindSize, y * WindSize, x * WindSize + WindSize, y * WindSize + WindSize + 1);
end;
for x:=0 to SizeX-1 do
for y:=0 to SizeY-1 do
if (x = 0) or (x = SizeX-1) or (y = 0) or (y = SizeY-1)
then Maze[x][y]:=32 { Отмечаем край лабиринта }
else Maze[x][y]:=63; { Центр поля заполняем блоками }
Randomize; //11 1111 - Поле 10 0000 - граница
x := 1+Random(SizeX-2); //Берём любой блок внутри границ
y := 1+Random(SizeY-2);
Maze[x][y]:=Maze[x][y] and not 48; //Помечаем - 00 1111 и ставим стенки.
for dir := 0 to 3 do
if (Maze[x+dx[dir]][y+dy[dir]] and 16) <> 0 then // Ищем необработанных соседей
begin
Push(x + dx[dir],y + dy[dir]);
Maze[x+dx[dir]][y+dy[dir]]:= Maze[x+dx[dir]][y+dy[dir]] and not 16; // Метим как "в очереди"
end;
while Pop(x,y) do // Пока стек не пуст
begin
repeat
dir:=Random(4);
until not ((Maze[x+dx[dir]][y+dy[dir]] and 32) <> 0); //Ищем откуда пришли, тоесть не помеченные вида 00 ????
Maze[x][y]:=Maze[x][y] and not ((1 shl dir) or 32); //Сносим стенку и убираем метку обработки теперь: 00 ????
Maze[x + dx[dir]][y + dy[dir]] := Maze[x + dx[dir]][y + dy[dir]] and not (1 shl (dir xor 1)); //Сносим у соседа эту же стенку для открытия прохода
s:=[];
Соедините со второй частью и просто полюбуйтесь как вырисовывается лабиринт. Знаю скучно, но всё же...
Комментарии (0) RSS
Добавить комментарий