SCAR Code:
program New;
function path1: TPointArray;
begin
SetLength(Result, 8);
Result[0] := Point(0, 0);
Result[1] := Point(0, 1);
Result[2] := Point(0, 2);
Result[3] := Point(0, 3);
Result[4] := Point(0, 4);
Result[5] := Point(0, 5);
Result[6] := Point(0, 6);
Result[7] := Point(0, 7);
end;
function path2: TPointArray;
begin
SetLength(Result, 8);
Result[0] := Point(0, 0);
Result[1] := Point(1, 1);
Result[2] := Point(2, 2);
Result[3] := Point(3, 3);
Result[4] := Point(4, 4);
Result[5] := Point(5, 5);
Result[6] := Point(6, 6);
Result[7] := Point(7, 7);
end;
function path3: TPointArray;
begin
SetLength(Result, 8);
Result[0] := Point(0, 0);
Result[1] := Point(1, 0);
Result[2] := Point(2, 0);
Result[3] := Point(3, 0);
Result[4] := Point(4, 0);
Result[5] := Point(5, 0);
Result[6] := Point(6, 0);
Result[7] := Point(7, 0);
end;
function path4: TPointArray;
begin
SetLength(Result, 8);
Result[0] := Point(7, 0);
Result[1] := Point(7, 1);
Result[2] := Point(7, 2);
Result[3] := Point(7, 3);
Result[4] := Point(7, 4);
Result[5] := Point(7, 5);
Result[6] := Point(7, 6);
Result[7] := Point(7, 7);
end;
function path5: TPointArray;
begin
SetLength(Result, 8);
Result[0] := Point(0, 7);
Result[1] := Point(1, 7);
Result[2] := Point(2, 7);
Result[3] := Point(3, 7);
Result[4] := Point(4, 7);
Result[5] := Point(5, 7);
Result[6] := Point(6, 7);
Result[7] := Point(7, 7);
end;
function IntinArr(int:integer; comp:array of integer):boolean;
var i:integer;
begin
result := false;
for i := 0 to High(comp) do
begin
if comp[i] = int then
begin
result := true;
exit;
end;
end;
end;
type path = record
node: TPointArray;
avg, first,last: TPoint;
index: integer;
connection: array of integer;
end;
var paths:array of path;
curindex: integer;
function CalcAvginTPA(tpa:TPointArray):TPoint;
var i:integer;
begin
for i := 0 to high(tpa) do
begin
result.x := result.x + tpa[i].x;
result.y := result.y + tpa[i].y;
end;
result.x := Round(result.x / getarraylength(tpa));
result.y := Round(result.y / getarraylength(tpa));
end;
function CreatePath(node:TPointArray):integer;
begin
SetArrayLength(paths, curindex+1);
paths[curindex].node := node;
paths[curindex].index := curindex;
paths[curindex].avg := CalcAvginTPA(node);
paths[curindex].first := node[0];
paths[curindex].last := node[high(node)];
result := curindex;
curindex := curindex + 1;
end;
procedure LinkPath(i,y:integer);
begin
if IntinArr(i, paths[y].connection) = true then
begin
writeln('Following paths are already linked: ' + inttostr(i) + ':' + inttostr(y) + ' so fix your script because you''re losing efficiency!');
exit;
end;
SetArrayLength(paths[i].connection, GetArrayLength(paths[i].connection)+1);
SetArrayLength(paths[y].connection, GetArrayLength(paths[y].connection)+1);
paths[i].connection[High(paths[i].connection)] := paths[y].index;
paths[y].connection[High(paths[y].connection)] := paths[i].index;
end;
var charx,chary, destx, desty:integer;
arrived: boolean;
function TPt(x,y:integer):TPoint;
begin
result.x := x;
result.y := y;
end;
function AngleBetweenPoints(y1,y2,x1,x2:integer):extended;
begin
result := Abs(Arctan2(y2-y1,x2-x1) * 180 / Pi);
end;
procedure MoveTo(p:TPoint);
begin
charx := p.x;
chary := p.y;
writeln('Moved to :' + inttostr(p.x) + ',' + inttostr(p.y));
end;
procedure Initialize();
begin
CreatePath(path1());
CreatePath(path2());
CreatePath(path3());
CreatePath(path4());
CreatePath(path5());
LinkPath(0,1);
LinkPath(0,2);
LinkPath(1,2);
LinkPath(1,3);
LinkPath(1,4);
LinkPath(3,4);
end;
procedure AutoMoveThroughTPA(start,inc:integer; node:TPointArray);
var i:integer;
begin
i := start - inc;
repeat
i := i + inc;
MoveTo(node[i]);
if (node[i].x = destx) and (node[i].y = desty) then
begin
arrived := true;
exit;
end;
wait(100);
until (((i = 0) and (i <> start)) or ((i = high(node)) and (high(node) <> start)))
end;
function Pathable(path:integer):boolean;
begin
if Distance(charx, chary, paths[path].first.x, paths[path].first.y) < Distance(charx, chary, paths[path].last.x, paths[path].last.y)then
begin
result := ((charx = paths[path].first.x) and (chary = paths[path].first.y));
end else
begin
result := ((charx = paths[path].last.x) and (chary = paths[path].last.y));
end;
end;
procedure TakePath(path:integer);
begin
if Distance(charx, chary, paths[path].first.x, paths[path].first.y) < Distance(charx, chary, paths[path].last.x, paths[path].last.y) then
begin
AutoMoveThroughTPA(0, 1, paths[path].node)
end else
begin
AutoMoveThroughTPA(high(paths[path].node), -1, paths[path].node)
end;
end;
function DegreeDiff(A, B:extended):extended;
begin
result:= Abs(A-B);
if result>180.0 then
result:= 180.0-(result-180.0);
end;
function move(x,y:integer):boolean;
var p, n, curpath, lastpath:integer;
c, cd: extended;
node: TPointArray;
begin
c := 360;
arrived := false;
destx := x;
desty := y;
// Get Closest path
curpath := 0;
node := paths[curpath].node;
// Get Closest Point in TPA
p := 3;
// Finish first TPA
cd := AngleBetweenPoints(chary, y, charx, x);
if DegreeDiff(cd,AngleBetweenPoints(node[p+1].y, y,node[p+1].x,x)) < DegreeDiff(cd,AngleBetweenPoints(node[p-1].y, y,node[p-1].x,x)) then
begin
AutoMoveThroughTPA(p+1, 1, node);
end else
begin
AutoMoveThroughTPA(p-1, -1, node);
end;
repeat
cd := AngleBetweenPoints(chary, y, charx, x);
for p := 0 to high(paths[curpath].connection) do
begin
if (c > DegreeDiff(cd, AngleBetweenPoints(y, paths[paths[curpath].connection[p]].avg.y, x, paths[paths[curpath].connection[p]].avg.x))) {and (p <> lastpath) and (Pathable(p) = true)} then
begin
c := AngleBetweenPoints(y, paths[paths[curpath].connection[p]].avg.y, x, paths[paths[curpath].connection[p]].avg.x);
n := p;
end;
c := 360;
TakePath(n);
lastpath := curpath;
curpath := n;
end;
until (arrived = true)
end;
begin
Initialize;
MoveTo(TPt(0,3));
Move(0,7);
end.