home *** CD-ROM | disk | FTP | other *** search
/ Game Killer / Game_Killer.bin / 286.VIEWMAC.INC < prev    next >
Text File  |  1991-07-08  |  13KB  |  443 lines

  1. {$S View }
  2. const
  3.   xmax = 470;
  4.   ymax = 270;
  5.   XDimMax  = 20;
  6.   YDimMax  = 15;
  7.   xoffset  = 10;
  8.   yoffset  = -2;
  9.   size     = 11;
  10.  
  11. type
  12.   Vertex = record
  13.              sectorNum: integer;  { 0 if not in use }
  14.            end;
  15.   XIndex = 1..XDimMax;
  16.   YIndex = 1..YDimMax;
  17.   Screen = array [XIndex, YIndex ] of Vertex;
  18.   Pair   = record
  19.              visible : boolean;
  20.              row : XIndex;
  21.              col : YIndex;
  22.            end;
  23.   SectorToScreen = array [ sector ] of pair;
  24.  
  25. procedure View;
  26.   
  27. var
  28.   Grid      : screen;
  29.   OnScreen  : SectorToScreen;
  30.   XDim      : XIndex;
  31.   XLength   : integer;
  32.   YDim      : YIndex;
  33.   YLength   : integer;
  34.  
  35. function xpixel( i,j : integer ) : integer;
  36. begin
  37.   if not odd( j ) then
  38.     xpixel := (2 * i - 1) * XLength
  39.   else
  40.     xpixel := 2 * i * XLength;
  41. end;
  42.  
  43. function ypixel( i,j : integer ) : integer;
  44. begin
  45.   ypixel := (2 * j - 1) * Ylength + 4;
  46. end;
  47.  
  48. function NumVal( n : integer ) : string;
  49. var
  50.   temp : string;
  51. begin
  52.   temp := '';
  53.   while n > 0 do
  54.     begin
  55.       temp := chr( n mod 10 + ord('0') ) + temp;
  56.       n := n div 10;
  57.     end;
  58.   if length( temp ) = 1 then
  59.     temp := ' ' + temp + ' '
  60.   else if length( temp ) = 2 then
  61.     temp := ' ' + temp;
  62.   NumVal := temp;
  63. end; {NumVal}
  64.  
  65. procedure Tag( var STS : sectorToScreen;
  66.                var scr : screen;
  67.                    num : sector;
  68.                   irow : XIndex;
  69.                   jcol : YIndex );
  70. { put sector num into screen scr at irow, jcol; update sts accordingly }
  71. begin
  72.   if sts[ num].visible then
  73.     writeln('sector ', num, ' already placed before Tag!')
  74.   else if scr[ irow, jcol ].sectorNum <> 0 then
  75.     writeln('row ', irow, ', col ', jcol, ' already in use!')
  76.   else
  77.     begin
  78.       with STS[ num ] do
  79.         begin
  80.           visible := true;
  81.           row     := irow;
  82.           col     := jcol;
  83.         end; {with}
  84.       scr[ irow, jcol ].SectorNum := num;
  85.     end; {else}
  86. end; {tag}
  87.  
  88. procedure GoDirection( d : integer;
  89.                    var Row   : XIndex;
  90.                    var Col   : YIndex);
  91. { 0 is upleft, 1 left, 2 downleft, 3 downright, etc mod 6 }
  92. begin
  93.   d := abs( d ) mod 6;
  94.   if odd( Col ) then
  95.     case d of
  96.       0 : begin
  97.             if Col > 1 then col := col - 1;
  98.             if Row < XDim then row := row + 1;
  99.           end;
  100.       1 : if Row < XDim then row := row + 1;
  101.       2 : begin
  102.             if Col < YDim then col := col + 1;
  103.             if Row < XDim then row := row + 1;
  104.           end;
  105.       3 : if Col < YDim then col := col + 1;
  106.       4 : if row > 1 then row := row - 1;
  107.       5 : if Col > 1 then col := col - 1;
  108.     end {case}
  109.   else
  110.     case d of
  111.     0 : if Col > 1 then col := col - 1;
  112.     1 : if Row < XDim then row := row + 1;
  113.     2 : if Col < YDim then col := col + 1;
  114.     3 : begin
  115.           if Col < YDim then col := col + 1;
  116.           if Row > 1 then row := row - 1;
  117.         end;
  118.     4 : if Row > 1 then row := row - 1;
  119.     5 : begin
  120.           if Col > 1 then col := col - 1;
  121.           if Row > 1 then row := row - 1;
  122.         end;
  123.     end; {case}
  124. end;
  125.  
  126. procedure seek( var freerow : Xindex; var freecol : Yindex; home : sector );
  127. const
  128.   MaxTries = 100;
  129. var
  130.   one, two, three, n : integer;
  131. { Trying to find a home for the new guy, close to the home sector.
  132. one, two, and three will be random directions to try (of radius 1, 2, and
  133. 3).  When we are successful, we just break out of the procedure, hopefully
  134. returning a freerow and freecol. }
  135. begin
  136.   one := die( 6 );
  137.   for one := one to one + 5 do { from random start, advance 5 positions }
  138.     begin
  139.       freerow := OnScreen[ home ].row;
  140.       freecol := OnScreen[ home ].col;
  141.       GoDirection( one, freerow, freecol );
  142.       if grid[ freerow, freecol ].SectorNum = 0 then
  143.         exit;
  144.     end; {one}
  145.   one := die( 6 );
  146.   two := die( 6 );
  147.   for one := one to one + 5 do
  148.     for two := two to two + 5 do
  149.       begin
  150.         freerow := OnScreen[ home ].row;
  151.         freecol := OnScreen[ home ].col;
  152.         GoDirection( one, freerow, freecol );
  153.         GoDirection( two, freerow, freecol );
  154.         if grid[ freerow, freecol ].SectorNum = 0 then
  155.           exit;
  156.       end; {one two}
  157.   one := die( 6 );
  158.   two := die( 6 );
  159.   three := die( 6 );
  160.   for one := one to one + 5 do
  161.     for two := two to two + 5 do
  162.       for three := three to three + 5 do
  163.         begin
  164.           freerow := OnScreen[ home ].row;
  165.           freecol := OnScreen[ home ].col;
  166.           GoDirection( one, freerow, freecol );
  167.           GoDirection( two, freerow, freecol );
  168.           GoDirection( three, freerow, freecol );
  169.           if grid[ freerow, freecol ].SectorNum = 0 then
  170.             exit;
  171.         end; {one two three}
  172.   writeln('couldn''t place anything near ', home );
  173.   n := 0;
  174.   repeat
  175.     freerow := die( xdim );
  176.     freecol := die( ydim );
  177.     n := n + 1;
  178.   until (n = MaxTries) or (grid[ freerow, freecol ].sectorNum = 0);
  179. end; {seek}
  180.  
  181. procedure FindHome( var Grid : screen;
  182.                     var Showing : SectorToScreen;
  183.                         home, near : sector );
  184. { This is an interesting bit: given the home sector, find an open slot
  185. in the Grid to place the near sector. }
  186. var
  187.   basedir : integer;
  188.   baserow : XIndex;
  189.   basecol : YIndex;
  190. begin
  191. {  writeln('Trying to find a home for ', near, ' close to ', home );
  192.   writeln('starting at ', showing[ home ].row, showing[ home ].col ); }
  193.   seek( baserow, basecol, home );
  194.   if grid[ baserow, basecol ].SectorNum <> 0 then
  195.     writeln('Seek Failed!')
  196.   else
  197.     Tag( Showing, Grid, near, baserow, basecol );
  198. {  writeln('chose ', baserow, ' ', basecol );
  199.   readln; }
  200. end;
  201.  
  202. procedure DistanceSortedQueueLoad( var q : queue; max : integer );
  203. { Load all pairs (parent, offspring) from the distance array whose distance
  204. is less than max, but do so in priority order sorted by distance. }
  205. var
  206.   r : integer;
  207.   sec : sector;
  208. begin
  209.   for r := 1 to max do
  210.     for sec := 1 to maxSector do
  211.       if distances[sec].d = r then
  212.         enqueue( q, distances[sec].s, sec );
  213. end; {DistanceSortedQueueLoad}
  214.  
  215. procedure PlaceSectors( var Grid  : screen;
  216.                         var Showing : SectorToScreen;
  217.                         var maxDist : integer;
  218.                         var BaseSect : sector );
  219. var
  220.   PlaceMe : Queue;
  221.   daddy, sonny : sector;
  222. begin
  223.   Tag( showing, Grid, baseSect, XDim div 2, YDim div 2 ); { put first in center}
  224.   PlaceMe.front := 0;
  225.   DistanceSortedQueueLoad( PlaceMe, maxdist );
  226.   While PlaceMe.front <> 0 do
  227.     begin
  228.       serve( PlaceMe, daddy, sonny );
  229.       if showing[ daddy ].visible then
  230.         FindHome( Grid, Showing, daddy, sonny );
  231.     end; {while}
  232. end; {while}
  233.  
  234. procedure InitSectorToScreen( var s : SectorToScreen );
  235. var
  236.   n : sector;
  237. begin
  238.   for n := 1 to maxSector do
  239.     s[ n ].visible := false;
  240. end;
  241.  
  242. procedure InitScreen( var s : Screen );
  243. var
  244.   r : XIndex;
  245.   c : YIndex;
  246. begin
  247.   for r := 1 to XDim do for c := 1 to YDim do
  248.     s[ r, c ].sectorNum := 0;
  249. end;
  250.  
  251. procedure FillGrid( var Grid : screen;
  252.                     var Showing : SectorToScreen;
  253.                     var Distances : distanceArray );
  254. { Choose a sector, and fill Distances with distance to that sector,
  255. as well as Showing and Grid based on nearby vertices. }
  256. var
  257.   maxD : integer;
  258.   sn   : sector;
  259.   ch   : char;
  260. begin
  261.   repeat
  262.     write('Starting at which sector? ');
  263.     readln( sn );
  264.     if space.sectors[ sn ].number = 0 then
  265.       writeln('You have never visited ', sn );
  266.   until space.sectors[ sn ].number > 0;
  267.   write( 'Sectors <L>eaving ', sn, ', sectors coming <T>oward ', sn, ', or <B>oth? ');
  268.   readln( ch );
  269.   if ch in ['l','L'] then
  270.     TwoWayDistances( sn, distances, false, true )
  271.   else if ch in ['t','T'] then
  272.     TwoWayDistances( sn, distances, true, false )
  273.   else
  274.     TwoWayDistances( sn, distances, true, true );
  275.   repeat
  276.     write( 'Max distance to include? ');
  277.     readln( maxD );
  278.     writeln( 'Total of ', CountDist(Distances, maxD), ' at distance at most ', MaxD );
  279.     write('Is this okay?  (y/n) ');
  280.     readln( ch );
  281.   until ch in ['Y','y'];
  282.   InitSectorToScreen( Showing );
  283.   InitScreen( Grid );
  284.   PlaceSectors( Grid, Showing, maxD, sn );
  285. end; {FillGrid}
  286.  
  287.  
  288.  
  289. procedure CircleSector( x : XIndex; y : YIndex; s : sector );
  290. var
  291.   r, c, n : integer;
  292.   q    : rect;
  293. begin
  294.   r := xpixel( x, y );
  295.   c := ypixel( x, y );
  296.   SetRect( q, r - size, c - size, r + size, c + size );
  297.   eraseOval( q );
  298.   with space.sectors[ s ] do
  299.     if number > 0 then
  300.       if portType <> NotAPort then
  301.         FrameRect( q )
  302.       else
  303.         FrameOval( q );
  304.   if space.sectors[s].number = 1 then {dead end}
  305.     begin
  306.       setRect( q, r-size+3, c-size+3, r+size-3, c+size-3);
  307.       if space.sectors[s].portType <> NotAPort then
  308.         FrameRect( q )
  309.       else
  310.         FrameOval( q );      
  311.     end; {dead end}
  312.   MoveTo( r - xoffset, c - yoffset );
  313.   Drawstring( NumVal( s ) );
  314.   if space.sectors[s].etc and SpaceLane <> Nothing then
  315.     if space.sectors[s].portType = NotAPort then
  316.       begin
  317.         MoveTo( r - size div 2, c - size div 2 );
  318.         line( size, size );
  319.       end
  320.     else
  321.       begin
  322.         MoveTo( r-size, c-size );
  323.         line( 2*size,2*size);
  324.       end;
  325. end;
  326.  
  327. procedure NormalPenStats;
  328. begin
  329.   PenSize( 1, 1 );
  330. end;
  331.  
  332. procedure UnknownPenStats;
  333. begin
  334.   Pensize( 3, 3 );
  335. {  PenPat( ltGray ); }
  336. end;
  337.  
  338. procedure ConnectVertices( i1, i2 : XIndex; j1, j2 : YIndex;
  339.                            TwoWay : boolean );
  340. var
  341.   x1, y1, x2, y2 : integer;
  342. begin
  343.   x1 := xpixel( i1, j1 );
  344.   y1 := ypixel( i1, j1 );
  345.   x2 := xpixel( i2, j2 );
  346.   y2 := ypixel( i2, j2 );
  347.   if TwoWay then
  348.     NormalPenStats
  349.   else
  350.     UnknownPenStats;
  351.   MoveTo( x1, y1 );
  352.   LineTo( x2, y2 );
  353. end;
  354.  
  355. procedure DrawGrid( var G : screen; STS : SectorToScreen );
  356. var
  357.   i : XIndex;
  358.   j : YIndex;
  359.   t : WarpIndex;
  360.   temp : integer;
  361. begin
  362.   clearScreen;
  363.   for i := 1 to XDim do
  364.     for j := 1 to YDim do
  365.       if G[ i, j ].sectorNum <> 0 then
  366.         with G[ i, j ] do
  367.           with space.sectors[ sectorNum ] do if number > 0 then
  368.             for t := 1 to number do
  369.               if STS[ data[ t ] ].visible then
  370.                 ConnectVertices( i, STS[data[t] ].row, j, STS[data[t]].col,
  371.                                  IsWarp( data[t], sectorNum ) );
  372.   NormalPenStats; 
  373.   for i := 1 to XDim do
  374.     for j := 1 to YDim do
  375.       if G[ i, j ].sectorNum <> 0 then
  376.           CircleSector( i, j, G[i,j].sectorNum );
  377. end;
  378.  
  379. procedure GetDimensions( var x : XIndex; var xl : integer;
  380.                          var y : YIndex; var yl : integer );
  381. var
  382.   line : string;
  383.   ok   : boolean;
  384.   tempx, tempy,
  385.   position : integer;
  386. begin
  387.   ok := false;
  388.   repeat
  389.     write('Max dimensions? [', XDimMax, ' by ', YDimMax, ']  ');
  390.     readln( line );
  391.     if line = '' then
  392.       begin
  393.         ok := true;
  394.         x := XDimMax * 2 div 3;
  395.         y := YDimMax * 2 div 3;
  396.       end
  397.     else
  398.       begin
  399.         position := 1;
  400.         tempx := 0;
  401.         while (position <= length( line )) and
  402.               (line[position] in ['0'..'9']) do
  403.           begin
  404.             tempx := 10 * tempx + ord( line[ position ] ) - ord( '0' );
  405.             position := position + 1;
  406.           end; {while}
  407.         position := position + 1;
  408.         while (position <= length( line ) ) and
  409.               (line[position] in [' ', #9, #10, #13 ]) do
  410.           position := position + 1;
  411.         tempy := 0;
  412.         while (position <= length( line )) and
  413.               (line[position] in ['0'..'9']) do
  414.           begin
  415.             tempy := 10 * tempy + ord( line[position] ) - ord('0');
  416.             position := position + 1;
  417.           end; {while}
  418.         ok := (tempx>0) and (tempx<=XDimMax) and (tempy>0) and (tempy<=YDimMax);
  419.         if ok then
  420.           begin
  421.             x := tempx;
  422.             y := tempy;
  423.           end {if}
  424.         else
  425.           begin
  426.             writeln('I don''t understand ', line );
  427.             writeln('Please give two integers separated by a space.');
  428.           end; {else}
  429.       end; {else}
  430.   until ok;
  431.   xl := trunc( XMax / x / 2 );
  432.   yl := trunc( YMax / y / 2);
  433. end;
  434.  
  435. begin {view}
  436.   GetDimensions( XDim, XLength, YDim, Ylength );
  437.   FillGrid( Grid, OnScreen, Distances );
  438.   DrawGrid( Grid, Onscreen );
  439.   readln;
  440.   clearscreen;
  441. end; {view}
  442.  
  443. {$S }