home *** CD-ROM | disk | FTP | other *** search
/ Game Killer / Game_Killer.bin / 109.DISTANCE.INC < prev    next >
Text File  |  1992-07-22  |  4KB  |  142 lines

  1. procedure SetUpInverseArray;
  2. var
  3.   i : sector;
  4.   t : warpindex;
  5.   target : sector;
  6. begin
  7.   if invdone then exit;
  8.   writeln('Setting up inverse array...');
  9.   invdone := true;
  10.   for i := 1 to MaxSector do
  11.     inverses[i].number := 0;
  12.   for i := 1 to MaxSector do
  13.     begin
  14.       for t := 1 to Space.sectors[i].number do
  15.         begin
  16.           target := space.sectors[i].data[t];
  17.           inc( inverses[ target ].number );
  18.           with inverses[ target] do
  19.             data[ number ] := i;
  20.         end;
  21.     end;
  22.   invdone := true;
  23. end;
  24.  
  25. procedure TwoWayDistances( sec : sector; var D : distanceArray;
  26.                            inward, outward : boolean );
  27. { inward = accept TOWARD sec; outward = accept LEAVING sec }
  28. { D[j].d = distance from sec;
  29.   D[j].s = one node close }
  30. var
  31.   si : sectorIndex;
  32.   wi : invIndex;
  33.   breadth : queue;
  34.   s,
  35.   daddy, sonny : sector;
  36.   i : warpindex;
  37.   entered : array [ sector ] of boolean;
  38. begin
  39.   if inward then
  40.     SetUpInverseArray;
  41.   writeln('Computing distances...');
  42.   for s := 1 to maxSector do
  43.     begin
  44.       D[s].d := -1;
  45.       entered[ s ] := false;
  46.     end; {for}
  47.   breadth.front := 0;
  48.   enqueue( breadth, sec, sec );
  49.   entered[sec] := true;
  50.   while breadth.front > 0 do
  51.     begin
  52.       serve( breadth, daddy, sonny );
  53.       if D[ sonny ].d = -1 then {haven't hit him before:}
  54.         begin
  55.           D[ sonny ].d := D[ daddy ].d + 1;
  56.           D[ sonny ].s := daddy;
  57.           if outward then
  58.             with space.sectors[ sonny ] do if number > 0 then
  59.               if (space.sectors[sonny].etc and avoid) = Nothing then
  60.                 for wi := 1 to number do
  61.                   if not entered[ data[wi] ] then
  62.                     begin
  63.                       enqueue( breadth, sonny, data[ wi ] );
  64.                       entered[ data[wi] ] := true;
  65.                     end; {if with for if}
  66.           if inward then
  67.             with inverses[ sonny ] do
  68.               if (number > 0) and ((space.sectors[sonny].etc and avoid) = Nothing) then
  69.                 for wi := 1 to number do
  70.                   if not entered[ data[wi] ] then
  71.                     begin
  72.                       enqueue( breadth, sonny, data[ wi ] );
  73.                       entered[ data[wi] ] := true;
  74.                     end; {if with for if}
  75.         end; {if}
  76.     end; {while}
  77.   for s := 1 to maxSector do if D[s].d = -1 then D[s].d := maxint;
  78. end; {FixDistances}
  79.  
  80. function CountDist(var D : distancearray; howfar : integer ):integer;
  81. var
  82.   c : integer;
  83.   s : sector;
  84. begin
  85.   c := 0;
  86.   for s := 1 to maxSector do
  87.     if D[ s ].d <= howfar then
  88.       c := c + 1;
  89.   countDist := c;
  90. end; {CountDist}
  91.  
  92. procedure quick( start, finish : sector; var X : distancearray );
  93. { This uses C.M. Hoare's quicksort algorithm to sort the distance array
  94.   based on ".d" field. }
  95. var
  96.     left, right   : sectorindex;
  97.     starter, temp : dist;
  98.  
  99. begin
  100.     left := start;
  101.     right := finish;
  102.     starter := x[(start + finish) div 2];    {middle of array}
  103.     repeat
  104.       while x[left].d < starter.d do
  105.           left := left + 1;        {find a bigger value on the left}
  106.       while starter.d < x[right].d do
  107.           right := right -1;        {and find a smaller value on the right}
  108.       if left <= right then        {we haven't gone too far, so}
  109.         begin
  110.           temp := x[left];        {swap the two}
  111.           x[left] := x[right];
  112.           x[right] := temp;
  113.           left := left + 1;
  114.           right := right -1;    {and update the pointers}
  115.         end; {{if}
  116.     until right < left;
  117.     if start < right then quick(start, right, x);
  118.     if left < finish then quick(left, finish, x);
  119. end;  {quicksort}
  120.  
  121. procedure SortDistances( var D : distancearray; largest : sector );
  122. { sort, based upon "d" field.  }
  123. begin
  124.   quick( 1, largest, d );
  125. end; {Sort Distances}
  126.  
  127. function SetupDistances : boolean;
  128. { return false if they aborted }
  129. var
  130.   s, n : integer;
  131. begin
  132.   s := GetSector;
  133.   if s <> 0 then
  134.     begin
  135.       TwoWayDistances( s, distances, false, true );
  136.       for n := 1 to maxSector do distances[ n ].s := n;
  137.       SetUpDistances := true;
  138.     end {if}
  139.   else
  140.     SetUpDistances := false;
  141. end; {SetUpDistances}
  142.