Advertisement
DaWoblefet

Minesweeper in C

Apr 20th, 2017
283
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.95 KB | None | 0 0
  1. /* Leonard Craft, 700636514
  2. Minesweeper.c
  3. Update log:
  4.     Start - 4/13/17
  5.     Boards - 4/15/17
  6.     Primary work - 4/20/17
  7.     Flood fill - 4/24/17
  8. This program plays a game of Minesweeper.
  9. */
  10.  
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <time.h>
  14.  
  15. typedef struct tile
  16. {
  17.   int isMine;
  18.   int isRevealed;
  19.   int numberOfMines;
  20. } tile_t;
  21.  
  22. /* Prints the board. If the tile hasn't been revealed yet, print -; if
  23. the tile was revealed and was a mine, print *; if the tile was revealed
  24. and wasn't a mine, print the number of mines in its neighboring squares.
  25. */
  26.  
  27. void printBoard(tile_t** grid)
  28. {
  29.   int i, j;
  30.  
  31.   printf("\nColumn: ");
  32.   for (j = 0; j < 10; j++)
  33.   {
  34.     printf("%-3d", j);
  35.   }
  36.  
  37.   printf("\nRow:\n");
  38.  
  39.   for (i = 0; i < 10; i++)
  40.   {
  41.     printf("    %d   ", i);
  42.     for (j = 0; j < 10; j++)
  43.     {
  44.       if (grid[i][j].isRevealed)
  45.       {
  46.         if (grid[i][j].isMine)
  47.         {
  48.           printf("%-3c", '*');
  49.         }
  50.         else
  51.         {
  52.           printf("%-3d", grid[i][j].numberOfMines);
  53.         }
  54.       }
  55.       else
  56.       {
  57.         printf("%-3c", '-');
  58.       }
  59.     }
  60.     printf("\n");
  61.   }
  62. }
  63.  
  64. /* Cycles through neighboring squares, and returns the number of mines
  65. found. */
  66.  
  67. int numberOfMines(tile_t** grid, int i, int j)
  68. {
  69.   int result = 0;
  70.  
  71.   //Top-Left
  72.   if (i - 1 >= 0 && j - 1 >= 0)
  73.   {
  74.     if (grid[i - 1][j - 1].isMine)
  75.     {
  76.       result++;
  77.     }
  78.   }
  79.  
  80.   //Top-Center
  81.   if (i - 1 >= 0)
  82.   {
  83.     if (grid[i - 1][j].isMine)
  84.     {
  85.       result++;
  86.     }
  87.   }
  88.  
  89.   //Top-Right
  90.   if (i - 1 >= 0 && j + 1 < 10)
  91.   {
  92.     if (grid[i - 1][j + 1].isMine)
  93.     {
  94.       result++;
  95.     }
  96.   }
  97.  
  98.   //Middle-Right
  99.   if (j + 1 < 10)
  100.   {
  101.     if (grid[i][j + 1].isMine)
  102.     {
  103.       result++;
  104.     }
  105.   }
  106.  
  107.   //Bottom-Right
  108.   if (i + 1 < 10 && j + 1 < 10)
  109.   {
  110.     if (grid[i + 1][j + 1].isMine)
  111.     {
  112.       result++;
  113.     }
  114.   }
  115.  
  116.   //Bottom-Middle
  117.   if (i + 1 < 10)
  118.   {
  119.     if (grid[i + 1][j].isMine)
  120.     {
  121.       result++;
  122.     }
  123.   }
  124.  
  125.   //Bottom-Left
  126.   if (i + 1 < 10 && j - 1 >= 0)
  127.   {
  128.     if (grid[i + 1][j - 1].isMine)
  129.     {
  130.       result++;
  131.     }
  132.   }
  133.  
  134.   //Middle-Left
  135.   if (j - 1 >= 0)
  136.   {
  137.     if (grid[i][j - 1].isMine)
  138.     {
  139.       result++;
  140.     }
  141.   }
  142.  
  143.   return result;
  144. }
  145.  
  146. /* Checks each tile surrounding the current tile; if that tile also has
  147. no mines surrounding it, check each tile surrounding that tile, and so
  148. on. */
  149.  
  150. void floodFill(tile_t** grid, int i, int j)
  151. {
  152.   //Top-Left
  153.   if (i - 1 >= 0 && j - 1 >= 0)
  154.   {
  155.     if (!(grid[i-1][j-1].isRevealed))
  156.     {
  157.       grid[i-1][j-1].isRevealed = 1;
  158.       if (grid[i-1][j-1].numberOfMines == 0)
  159.       {
  160.         floodFill(grid, i-1, j-1);
  161.       }
  162.     }
  163.   }
  164.  
  165.   //Top-Center
  166.   if (i - 1 >= 0)
  167.   {
  168.     if (!(grid[i-1][j].isRevealed))
  169.     {
  170.       grid[i-1][j].isRevealed = 1;
  171.       if (grid[i-1][j].numberOfMines == 0)
  172.       {
  173.         floodFill(grid, i-1, j);
  174.       }
  175.     }
  176.   }
  177.  
  178.   //Top-Right
  179.   if (i - 1 >= 0 && j + 1 < 10)
  180.   {
  181.     if (!(grid[i-1][j+1].isRevealed))
  182.     {
  183.       grid[i-1][j+1].isRevealed = 1;
  184.       if (grid[i-1][j+1].numberOfMines == 0)
  185.       {
  186.         floodFill(grid, i-1, j+1);
  187.       }
  188.     }
  189.   }
  190.  
  191.   //Middle-Right
  192.   if (j + 1 < 10)
  193.   {
  194.     if (!(grid[i][j+1].isRevealed))
  195.     {
  196.       grid[i][j+1].isRevealed = 1;
  197.       if (grid[i][j+1].numberOfMines == 0)
  198.       {
  199.         floodFill(grid, i, j+1);
  200.       }
  201.     }
  202.   }
  203.  
  204.   //Bottom-Right
  205.   if (i + 1 < 10 && j + 1 < 10)
  206.   {
  207.     if (!(grid[i+1][j+1].isRevealed))
  208.     {
  209.       grid[i+1][j+1].isRevealed = 1;
  210.       if (grid[i+1][j+1].numberOfMines == 0)
  211.       {
  212.         floodFill(grid, i+1, j+1);
  213.       }
  214.     }
  215.   }
  216.  
  217.   //Bottom-Middle
  218.   if (i + 1 < 10)
  219.   {
  220.     if (!(grid[i+1][j].isRevealed))
  221.     {
  222.       grid[i+1][j].isRevealed = 1;
  223.       if (grid[i+1][j].numberOfMines == 0)
  224.       {
  225.         floodFill(grid, (i+1), j);
  226.       }
  227.     }
  228.   }
  229.  
  230.   //Bottom-Left
  231.   if (i + 1 < 10 && j - 1 >= 0)
  232.   {
  233.     if (!(grid[i+1][j-1].isRevealed))
  234.     {
  235.       grid[i+1][j-1].isRevealed = 1;
  236.       if (grid[i+1][j-1].numberOfMines == 0)
  237.       {
  238.         floodFill(grid, (i+1), (j-1));
  239.       }
  240.     }
  241.   }
  242.  
  243.   //Middle-Left
  244.   if (j - 1 >= 0)
  245.   {
  246.     if (!(grid[i][j-1].isRevealed))
  247.     {
  248.       grid[i][j-1].isRevealed = 1;
  249.       if (grid[i][j-1].numberOfMines == 0)
  250.       {
  251.         floodFill(grid, i, (j-1));
  252.       }
  253.     }
  254.   }
  255. }
  256.  
  257. /* Cycles through the board to check if the player has won. */
  258. int checkWin(tile_t** grid)
  259. {
  260.   int hasWon = 1;
  261.   int i, j;
  262.  
  263.   for (i = 0; i < 10; i++)
  264.   {
  265.     for (j = 0; j < 10; j++)
  266.     {
  267.       //If there is an unrevealed non-mine tile, the player continues.
  268.       if (grid[i][j].isRevealed == 0 && grid[i][j].isMine == 0)
  269.       {
  270.         hasWon = 0;
  271.         break;
  272.       }
  273.     }
  274.   }
  275.   return hasWon;
  276. }
  277.  
  278. int main(int argc, char* argv[])
  279. {
  280.   srand(time(NULL));
  281.   tile_t** grid;
  282.   int i, j, m;
  283.   int mineNotSet;
  284.   int hasWon;
  285.  
  286.   //Allocating memory for the grid.
  287.   grid = (tile_t**) malloc(sizeof(tile_t*) * 10);
  288.   for (i = 0; i < 10; i++)
  289.   {
  290.     grid[i] = (tile_t*) malloc(sizeof(tile_t) * 10);
  291.     for (j = 0; j < 10; j++)
  292.     {
  293.       grid[i][j].isMine = 0;
  294.       grid[i][j].isRevealed = 0;
  295.     }
  296.   }
  297.  
  298.   //Randomly fills grid with 10 mines.
  299.   for (m = 0; m < 10; m++)
  300.   {
  301.     /* Checks for extra conditions; don't put a mine at 0x0 or where one
  302.     has already been placed. */
  303.     mineNotSet = 1;
  304.     while (mineNotSet)
  305.     {
  306.       i = rand() % 10;
  307.       j = rand() % 10;
  308.       if (!((i == 0 && j == 0) || grid[i][j].isMine == 1))
  309.       {
  310.         grid[i][j].isMine = 1;
  311.         mineNotSet = 0;
  312.       }
  313.     }
  314.   }
  315.  
  316.   //Calculates the number of mines surrounding each tile.
  317.   for (i = 0; i < 10; i++)
  318.   {
  319.     for (j = 0; j < 10; j++)
  320.     {
  321.       grid[i][j].numberOfMines = numberOfMines(grid, i, j);
  322.     }
  323.   }
  324.  
  325.   printf("********************************\nWelcome to Minesweeper!\n");
  326.   printBoard(grid);
  327.   hasWon = 0;
  328.  
  329.   while (!hasWon)
  330.   {
  331.     printf("Please enter the row and column to sweep: ");
  332.     scanf("%d %d", &i, &j);
  333.  
  334.     //Cheat code to insta-win so I don't have to play through a full game.
  335.     if (i == 99 && j == 99)
  336.     {
  337.       hasWon = 1;
  338.       break;
  339.     }
  340.    
  341.     //Checks to make sure user entered a valid row / column.
  342.     while (i < 0 || i > 9 || j < 0 || j > 9)
  343.     {
  344.       printf("Invalid row / column. Please enter the row and column to sweep: ");
  345.       scanf("%d %d", &i, &j);
  346.     }
  347.  
  348.     grid[i][j].isRevealed = 1;
  349.  
  350.     /*If the square revealed has 0 mines around it, keep revealing
  351.       squares until ones with mines are found. */
  352.     if (!(grid[i][j].isMine) && grid[i][j].numberOfMines == 0)
  353.     {
  354.       floodFill(grid, i, j);
  355.     }
  356.  
  357.     printBoard(grid);
  358.     if (grid[i][j].isMine)
  359.     {
  360.       printf("You hit a mine! You lose.\n");
  361.       break;
  362.     }
  363.     hasWon = checkWin(grid);
  364.   }
  365.  
  366.   if (hasWon)
  367.   {
  368.     printf("Congratulations! You revealed all the squares correctly.\n");
  369.   }
  370.  
  371.   free(grid);
  372.  
  373.   return 0;
  374. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement