procedure WaveTracingSolve(TheMaze : Maze; xs, ys, xf, yf : Integer); var Mark : array of array of Integer; { метки локаций } x, y, xc, yc : Integer; N, i : Integer; Height, Width : Integer; const dx : array[1..4] of Integer = (1, 0, -1, 0); { смещения } dy : array[1..4] of Integer = (0, -1, 0, 1); { neo?aaiay ooieoey: ii?aaaeyao, ii?ii ee i?ieoe ec eieaoee (x, y) в локацию (x + dx, y + dy), то есть нет ли между ними стены } function CanGo(x, y, dx, dy : Integer) : Boolean; Листинг 4.2 (продолжение) begin if dx = -1 then CanGo := not TheMaze[x, y].left_wall else if dx = 1 then CanGo := not TheMaze[x + 1, y].left_wall else if dy = -1 then CanGo := not TheMaze[x, y].up_wall else CanGo := not TheMaze[x, y + 1].up_wall; end; function Solve : Boolean; { поиск решения } var i, N, x, y : Integer; NoSolution : Boolean; begin N := 1; { начинаем с итерации номер 1 } repeat NoSolution := true; { пессимистично полагаем, что решения нет } for x := 0 to Width - 1 do for y := 0 to Height - 1 do if Mark[x, y] = N then { найти локации, помеченные числом N } for i := 1 to 4 do { просмотр соседних локаций } if CanGo(x, y, dx[i], dy[i]) and (Mark[x + dx[i], y + dy[i]] = 0) then begin { локация доступна и помечена нулем } NoSolution := false; { есть шанс найти решение } { помечаем соседнюю локацию числом N + 1 } Mark[x + dx[i], y + dy[i]] := N + 1; if (x + dx[i] = xf) and (y + dy[i] = yf) then begin Solve := true; { дошли до финишной локации } Exit; { конец алгоритма } end; end; N := N + 1; { переход к следующей итерации } until NoSolution; { повторять, если есть надежда найти решение } Solve := false; { нет, решение не найдено } end; begin Width := High(TheMaze); Height := High(TheMaze[0]); SetLength(Mark, Width, Height); { выделение памяти для пометок } for x := 0 to Width - 1 do { изначально все заполняется нулями } for y := 0 to Height - 1 do Mark[x, y] := 0; Mark[xs, ys] := 1; { стартовой локации соответствует единица } if Solve then { если найдено решение, рисуем его } begin x := xf; y := yf; for N := Mark[xf, yf] downto 1 do begin { рисуем окружность на очередной локации маршрута } xc := CellSize * (2 * x + 1) div 2; yc := CellSize * (2 * y + 1) div 2; Form1.Screen.Canvas.Ellipse(xc - 5, yc - 5, xc + 5, yc + 5); for i := 1 to 4 do if CanGo(x, y, dx[i], dy[i]) and (Mark[x + dx[i], y + dy[i]] = N - 1) then begin x := x + dx[i]; { ищем следующую локацию маршрута } y := y + dy[i]; Break; end; end; end; end;