unit uMap4Way;

{$mode delphi}

interface

uses
  Classes, SysUtils;
type

  TWayPoint = record
    X, Y : Integer;
  end;

  TWayObj = class
    Way  : array of TWayPoint;
    WayN : Integer;
    tX, tY : Integer;
    procedure AddWay(wX_, wY_ : Integer);
  end;

  TMap4Way = class
    // Координаты последнего тайла
    W, H : Integer;
    FreeTile : array of array of Boolean;
    function  SetWay(DynObj : TWayObj; FinishX, FinishY : Integer) : Boolean; virtual;
  end;



implementation
uses
  uGlobal;

{ TMap4Way }

function TMap4Way.SetWay(DynObj : TWayObj; FinishX, FinishY: Integer): Boolean;
var
  I, X, Y, Alg, nX, nY, StartX, StartY, Step : integer;
  WayMap : array of array of array[0..3] of integer;
  Added : Boolean;
begin
  SetLength(WayMap, W + 1, H + 1);
  Added := true;
  Step := 0;
  StartX := DynObj.tX;
  StartY := DynObj.tY;
  FreeTile[StartX, StartY] := true;

  for X := 0 to W do
  for Y := 0 to H do
    WayMap[X, Y, 0] := -1;

  WayMap[FinishX, FinishY, 0] := 0;

  while ((Added) and (WayMap[StartX, StartY, 0] = -1)) do
  begin
    Added := false;
    Step := Step + 1;

    for X := 0 to W do
    for Y := 0 to H do
    if (WayMap[X, Y, 0] = Step - 1) then
    for Alg := 0 to 3 do
    begin

      nX := X + cAngleX[Alg];
      nY := Y + cAngleY[Alg];

      if (nX >= 0) and (nY >= 0) and (nX <= W) and (nY <= H)
      and (FreeTile[nX, nY]) and (WayMap[nX, nY, 0] = -1) then
      begin

  	WayMap[nX, nY, 0] := Step;
  	WayMap[nX, nY, 1] := X;
  	WayMap[nX, nY, 2] := Y;
  	Added := true;
      end;

    end;
  end;

  if (WayMap[StartX, StartY, 0] = -1) then
    result := false
  else
  begin
    SetLength(DynObj.Way, 0);

    X := StartX;
    Y := StartY;
    Step := 150;

    while (WayMap[X, Y, 0] <> 0) and (Step > 0) do
    begin
      Step := Step - 1;
      DynObj.AddWay(X, Y);
      nX := X;
      X := WayMap[nX, Y, 1];
      Y := WayMap[nX, Y, 2];
    end;
    DynObj.AddWay(FinishX, FinishY);
    DynObj.WayN:=0;

    result := true;
  end;
end;

procedure TWayObj.AddWay(wX_, wY_: Integer);
var
  vL_ : Integer;
begin
  vL_ := Length(Way);
  SetLength(Way, vL_ + 1);
  Way[vL_].X := wX_;
  Way[vL_].Y := wY_;
end;
end.

