home *** CD-ROM | disk | FTP | other *** search
/ Game Killer / Game_Killer.bin / 080.VIEWDOS.INC < prev    next >
Text File  |  1992-07-14  |  16KB  |  527 lines

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