- 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
Function TMainForm.PrimGenerateMaze(Width, Height: Integer): Maze;
Type Point = record
x, y: Integer;
end;
Var
TehMaze: Maze;
Todo: array of Point;
todonum: integer;
x,y,n,d: integer;
Const
dx: array [0..3] of Integer = (0, 0, -1, 1);
dy: array [0..3] of Integer = (-1, 1, 0, 0);
BEGIN
SetLength(TehMaze, Width, Height);
SetLength(Todo, (Width * Height) - 1);
For x:=0 to Width-1 do
For y:=0 to Height-1 do
If (x = 0) or (x = Width-1) or (y = 0) or (y = Height-1) then
TehMaze[x][y]:=32
Else TehMaze[x][y]:=63;
Randomize;
x := Random(Width-2)+1;
y := Random(Height-2)+1;
todonum := 0;
TehMaze[x][y]:= TehMaze[x][y] and not 48; // Пометить клетку как принадлежащую лабиринту
// Пока не обработаны все клетки
Repeat
Begin
// Занести в список todo все ближайшие необработанные клетки
For d:=0 to 3 do
if (TehMaze[x + dx[d]][y + dy[d]] and 16) <> 0 then
Begin
todo[todonum].x := x + dx[d];
todo[todonum].y := y + dy[d];
Inc(todonum);
TehMaze[x + dx[d]][y + dy[d]] := TehMaze[x + dx[d]][y + dy[d]] and not 16;
End;
// Выбрать из списка todo произвольную клетку
n:= Random(todoNum);
x:= ToDo[n].x;
y:= ToDo[n].y;
// Удалить из списка обработанную клетку
Dec(todonum);
ToDo[n]:= todo[todonum];
// Выбрать направление, которое ведет к лабиринту
Repeat
d:=Random(4);
Until ((TehMaze[x + dx[d]][y + dy[d]] and 32) = 0);
// Присоединить выбранную клетку к лабиринту
TehMaze[x][y] := TehMaze[x][y] and not ((1 shl d) or 32);
TehMaze[x + dx[d]][y + dy[d]] := TehMaze[x + dx[d]][y + dy[d]] and not (1 shl (d xor 1));
End;
Until (todonum = 0);
TehMaze[1][1] := TehMaze[1][1] and -2; // начало лабиринта - в левом верхнем углу
TehMaze[Width-2][Height-2] := TehMaze[Width-2][Height-2] and not 2; // конец лабиринта - в правом нижнем углу
Result := TehMaze;
END;
Govnocoder#0xFF 10.02.2013 17:26 # 0
TarasB 10.02.2013 17:49 # +4
лол
TarasB 10.02.2013 17:50 # +2
убивать
Govnocoder#0xFF 10.02.2013 19:16 # 0
TarasB 10.02.2013 20:16 # 0
Govnocoder#0xFF 10.02.2013 20:29 # 0
TarasB 10.02.2013 20:35 # 0
Я в предыдущем посте херню написал.
Правка:
Govnocoder#0xFF 10.02.2013 20:53 # 0
TarasB 10.02.2013 20:59 # 0
Lure Of Chaos 10.02.2013 22:18 # 0
bormand 10.02.2013 22:54 # +1
P.S. Для todo применил бы очередь а не этот массив, код бы чуть понятней стал.
> Random(width*height) - весьма странная конструкция.
Действительно, каждый раз лабиринт будет одинаковый, при одном размере.
P.P.S. Загугли алгоритм Прима (построение остовного дерева?), попробуй понять, как его тут реализовали через эти битоебства. Может багу заметишь какую-то.
bormand 11.02.2013 05:44 # 0
А, тут выборка случайного элемента. Тогда очередь не прокатит. Разве что PriorityQueue с рандомным приоритетом.
Govnocoder#0xFF 11.02.2013 12:00 # 0
Да, вполне.
bormand 11.02.2013 06:12 # 0
Govnocoder#0xFF 11.02.2013 11:50 # 0
TarasB 11.02.2013 11:53 # +2
bormand 11.02.2013 06:22 # +3
Govnocoder#0xFF 11.02.2013 11:57 # 0
bormand 11.02.2013 12:34 # +1
Какой нахуй arraycopy()?! arraycopy() точно так же скопирует ссылки. Надо как-то так:
bormand 11.02.2013 13:50 # 0
P.S. Что за slick кстати?
Govnocoder#0xFF 11.02.2013 14:51 # +1
Lure Of Chaos 12.02.2013 04:12 # 0
guest 12.02.2013 19:29 # −3
anonimb84a2f6fd141 11.02.2013 17:24 # −12