\ Minesweeper - /g/pasta 2.4
From Jittery Gorilla, 4 Years ago, written in Pascal.
Embed
  1. program Minesweeper;
  2.  
  3. type
  4.   TBlock = record
  5.     Revealed: Boolean;
  6.     case IsMine: Boolean of
  7.       True: ( );
  8.       False: (NearbyMines: 0..8);
  9.   end;
  10.  
  11.   TField = array of array of TBlock;
  12.  
  13. var
  14.   Field: TField;
  15.   Width, Height, Mines, MineCount, x, y: Integer;
  16.   GameOver: Boolean;
  17. begin
  18.   { Initialise field }
  19.   Randomize;
  20.  
  21.   Write('Enter width, height, and number of mines: ');
  22.   ReadLn(Width, Height, Mines);
  23.  
  24.   SetLength(Field, Width, Height);
  25.  
  26.   for x := 0 to Pred(Width) do
  27.   for y := 0 to Pred(Height) do
  28.   begin
  29.     Field[x,y].Revealed := False;
  30.     Field[x,y].IsMine := False
  31.   end;
  32.  
  33.   MineCount := Mines;
  34.  
  35.   { Place mines }
  36.   repeat
  37.     x := Random(Width);
  38.     y := Random(Height);
  39.     if not Field[x,y].IsMine then
  40.     begin
  41.       Field[x,y].IsMine := True;
  42.       Dec(MineCount)
  43.     end
  44.   until MineCount = 0;
  45.  
  46.   { Place numbered blocks }
  47.   for x := 0 to Pred(Width) do
  48.   for y := 0 to Pred(Height) do
  49.     if not Field[x,y].IsMine then
  50.     begin
  51.       MineCount := 0;
  52.  
  53.       { Count nearby mines }
  54.       Inc(MineCount, Integer(
  55.         (x>0) and Field[x-1,y].IsMine));
  56.       Inc(MineCount, Integer(
  57.         (x<Pred(Width)) and Field[x+1,y].IsMine));
  58.       Inc(MineCount, Integer(
  59.         (y>0) and Field[x,y-1].IsMine));
  60.       Inc(MineCount, Integer(
  61.         (y<Pred(Height)) and Field[x,y+1].IsMine));
  62.       Inc(MineCount, Integer(
  63.         (x>0) and (y>0) and Field[x-1,y-1].IsMine));
  64.       Inc(MineCount, Integer(
  65.         (x<Pred(Width)) and (y>0) and Field[x+1,y-1].IsMine));
  66.       Inc(MineCount, Integer(
  67.         (x>0) and (y<Pred(Height)) and Field[x-1,y+1].IsMine));
  68.       Inc(MineCount, Integer(
  69.         (x<Pred(Width)) and (y<Pred(Height)) and Field[x+1,y+1].IsMine));
  70.  
  71.       Field[x,y].NearbyMines := MineCount
  72.     end;
  73.  
  74.   GameOver := False;
  75.  
  76.   repeat
  77.     { Draw minefield }
  78.     for x := 0 to Pred(Width) do
  79.     begin
  80.       for y := 0 to Pred(Height) do
  81.         with Field[x,y] do
  82.           if Revealed then
  83.             if IsMine then
  84.               Write('*')
  85.             else
  86.               Write(NearbyMines)
  87.           else
  88.             Write('?');
  89.       WriteLn
  90.     end;
  91.  
  92.     if GameOver then
  93.     begin
  94.       WriteLn('GAME OVER');
  95.       Break
  96.     end;
  97.  
  98.     WriteLn;
  99.  
  100.     { Player action }
  101.     Write('Reveal: ');
  102.     ReadLn(x, y);
  103.  
  104.     with Field[x,y] do
  105.       if not Revealed then
  106.       begin
  107.         Revealed := True;
  108.         if IsMine then
  109.           GameOver := True
  110.       end
  111.  
  112.   until False
  113. end.