procedure RecursiveSolve(TheMaze : Maze; xs, ys, xf, yf : Integer); var Visited : array of array of Boolean; { карта посещенных локаций } x, y, xc, yc : Integer; i : Integer; Path : array of TPoint; { результирующий маршрут } Height, Width : Integer; const dx : array[1..4] of Integer = (1, 0, -1, 0); { смещения } dy : array[1..4] of Integer = (0, -1, 0, 1); { служебная функция: определяет, можно ли пройти из локации Листинг 4.1 (продолжение) (x, y) в локацию (x + dx, y + dy), то есть нет ли между ними стены } function CanGo(x, y, dx, dy : Integer) : Boolean; 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; { поиск финишной локации из точки (x, y) } function Solve(x, y, depth : Integer) : Boolean; var i : Integer; begin Visited[x, y] := true; { пометить локацию как посещенную } Path[depth] := Point(x, y); { добавить ее в описание маршрута } Path[depth + 1] := Point(-1, -1); { добавить признак конца маршрута } if (x = xf) and (y = yf) then { если финишная локация найдена } begin Solve := true; { конец алгоритма } Exit; end; for i := 1 to 4 do { если дорожка свободна, идем по ней } if CanGo(x, y, dx[i], dy[i]) and not Visited[x + dx[i], y + dy[i]] then if Solve(x + dx[i], y + dy[i], depth + 1) then begin Solve := true; { если решение найдено } Exit; { конец алгоритма } end; Visited[x, y] := false; { пометить локацию как непосещенную } Solve := false; { решение не найдено } end; begin { главная процедура }<>br Width := High(TheMaze); Height := High(TheMaze[0]); SetLength(Path, Height * Width + 1); { выделяем память для маршрута } SetLength(Visited, Width, Height); { и для списка посещенных локаций } for x := 0 to Width - 1 do for y := 0 to Height - 1 do Visited[x, y] := false; { изначально ни одна не посещена } if Solve(xs, ys, 0) then { если найдено решение, рисуем его } begin i := 0; while not ((Path[i].X = -1) and (Path[i].Y = -1)) do begin xc := CellSize * (2 * Path[i].X + 1) div 2; yc := CellSize * (2 * Path[i].Y + 1) div 2; Form1.Screen.Canvas.Ellipse(xc - 5, yc - 5, xc + 5, yc + 5); i := i + 1; end; end; end;