home *** CD-ROM | disk | FTP | other *** search
/ Game Killer / Game_Killer.bin / 282.VIEWDOS.INC < prev    next >
Text File  |  1991-06-04  |  14KB  |  478 lines

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