Guest User

Untitled

a guest
May 20th, 2018
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.56 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4.  
  5. enum State { Playing, Lost, Won };
  6. enum FieldState { Empty, Checked, Questioned, Turned, Mine };
  7.  
  8. struct Field
  9. {
  10.     bool mine;
  11.     FieldState state;
  12. };
  13.  
  14. void init(Field **fields, int width, int height, int mineAmount, int *unturnedAmount, State *state);
  15. int countNeighbours(Field **fields, int width, int height, int x, int y);
  16. void floodTurnField(Field **fields, int width, int height, int x, int y, int *unturnedAmount);
  17. void turnField(Field **fields, int width, int height, int x, int y, int mineAmount, int *unturnedAmount, State *state);
  18. void markField(Field **fields, int width, int height, int x, int y, State state);
  19. void printFields(Field **fields, int width, int height);
  20.  
  21. void main()
  22. {
  23.     srand((unsigned int)time(0));
  24.  
  25.     Field **fields;
  26.     int width, height;
  27.     int mineAmount;
  28.  
  29.     int unturnedAmount;
  30.     State state;
  31.  
  32.     printf("Enter width: ");
  33.     scanf("%d", &width);
  34.  
  35.     printf("Enter height: ");
  36.     scanf("%d", &height);
  37.  
  38.     printf("Enter amount of mines: ");
  39.     scanf("%d", &mineAmount);
  40.  
  41.     fields = new Field*[width];
  42.     for (int i = 0; i < width; ++i)
  43.         fields[i] = new Field[height];
  44.  
  45.     init(fields, width, height, mineAmount, &unturnedAmount, &state);
  46.  
  47.     while (state == Playing)
  48.     {
  49.         printFields(fields, width, height);
  50.  
  51.         char action[4 + 1];
  52.         int x, y;
  53.  
  54.         printf("Enter action (mark/turn x y): ");
  55.         scanf("%s %d %d", action, &x, &y);
  56.  
  57.         switch (action[0])
  58.         {
  59.         case 'm': case 'M': markField(fields, width, height, x - 1, y - 1, state); break;
  60.         case 't': case 'T': turnField(fields, width, height, x - 1, y - 1, mineAmount, &unturnedAmount, &state); break;
  61.         }
  62.     }
  63.    
  64.     printFields(fields, width, height);
  65.  
  66.     printf((state == Won) ? "You won!\n" : "You lost!\n");
  67.  
  68.     for (int i = 0; i < width; ++i)
  69.         delete[] fields[i];
  70.     delete[] fields;
  71. }
  72.  
  73. void init(Field **fields, int width, int height, int mineAmount, int *unturnedAmount, State *state)
  74. {
  75.     *unturnedAmount = width*height;
  76.  
  77.     for (int x = 0; x < width; ++x)
  78.     {
  79.         for (int y = 0; y < height; ++y)
  80.         {
  81.             fields[x][y].mine = false;
  82.             fields[x][y].state = Empty;
  83.         }
  84.     }
  85.  
  86.     for (int m = 0; m < mineAmount; ++m)
  87.     {
  88.         int x, y;
  89.         do {
  90.             x = rand()%width;
  91.             y = rand()%height;
  92.         } while (fields[x][y].mine);
  93.         fields[x][y].mine = true;
  94.     }
  95.  
  96.     *state = Playing;
  97. }
  98.  
  99. int countNeighbours(Field **fields, int width, int height, int x, int y)
  100. {
  101.     int count = 0;
  102.  
  103.     int xm1 = x - 1;
  104.     int xp1 = x + 1;
  105.     int ym1 = y - 1;
  106.     int yp1 = y + 1;
  107.  
  108.     if (xm1 >= 0)
  109.     {
  110.         count += fields[xm1][y].mine ? 1 : 0;
  111.         if (ym1 >= 0)
  112.             count += fields[xm1][ym1].mine ? 1 : 0;
  113.     }
  114.     if (ym1 >= 0)
  115.     {
  116.         count += fields[x][ym1].mine ? 1 : 0;
  117.         if (xp1 < width)
  118.             count += fields[xp1][ym1].mine ? 1 : 0;
  119.     }
  120.     if (xp1 < width)
  121.     {
  122.         count += fields[xp1][y].mine ? 1 : 0;
  123.         if (yp1 < height)
  124.             count += fields[xp1][yp1].mine ? 1 : 0;
  125.     }
  126.     if (yp1 < height)
  127.     {
  128.         count += fields[x][yp1].mine ? 1 : 0;
  129.         if (xm1 >= 0)
  130.             count += fields[xm1][yp1].mine ? 1 : 0;
  131.     }
  132.  
  133.     return count;
  134. }
  135.  
  136. void floodTurnField(Field **fields, int width, int height, int x, int y, int *unturnedAmount)
  137. {
  138.     if (fields[x][y].state == Turned)
  139.         return;
  140.  
  141.     fields[x][y].state = Turned;
  142.  
  143.     --(*unturnedAmount);
  144.  
  145.     if (!countNeighbours(fields, width, height, x, y))
  146.     {
  147.         int xm1 = x - 1;
  148.         int xp1 = x + 1;
  149.         int ym1 = y - 1;
  150.         int yp1 = y + 1;
  151.  
  152.         if (xm1 >= 0)
  153.         {
  154.             floodTurnField(fields, width, height, xm1, y, unturnedAmount);
  155.             if (ym1 >= 0)
  156.                 floodTurnField(fields, width, height, xm1, ym1, unturnedAmount);
  157.         }
  158.         if (ym1 >= 0)
  159.         {
  160.             floodTurnField(fields, width, height, x, ym1, unturnedAmount);
  161.             if (xp1 < width)
  162.                 floodTurnField(fields, width, height, xp1, ym1, unturnedAmount);
  163.         }
  164.         if (xp1 < width)
  165.         {
  166.             floodTurnField(fields, width, height, xp1, y, unturnedAmount);
  167.             if (yp1 < height)
  168.                 floodTurnField(fields, width, height, xp1, yp1, unturnedAmount);
  169.         }
  170.         if (yp1 < height)
  171.         {
  172.             floodTurnField(fields, width, height, x, yp1, unturnedAmount);
  173.             if (xm1 >= 0)
  174.                 floodTurnField(fields, width, height, xm1, yp1, unturnedAmount);
  175.         }
  176.     }
  177. }
  178.  
  179. void turnField(Field **fields, int width, int height, int x, int y, int mineAmount, int *unturnedAmount, State *state)
  180. {
  181.     if ((*state != Playing) || (fields[x][y].state == Turned) || (fields[x][y].state == Mine))
  182.         return;
  183.  
  184.     if (fields[x][y].mine)
  185.     {
  186.         *state = Lost;
  187.         for (int ix = 0; ix < width; ++ix)
  188.             for (int iy = 0; iy < height; ++iy)
  189.                 fields[ix][iy].state = fields[ix][iy].mine ? Mine : Turned;
  190.         return;
  191.     }
  192.  
  193.     floodTurnField(fields, width, height, x, y, unturnedAmount);
  194.  
  195.     if (*unturnedAmount == mineAmount)
  196.     {
  197.         *state = Won;
  198.         for (int ix = 0; ix < width; ++ix)
  199.             for (int iy = 0; iy < height; ++iy)
  200.                 fields[ix][iy].state = fields[ix][iy].mine ? Checked : Turned;
  201.         return;
  202.     }
  203. }
  204. void markField(Field **fields, int width, int height, int x, int y, State state)
  205. {
  206.     if (state != Playing)
  207.         return;
  208.  
  209.     switch (fields[x][y].state)
  210.     {
  211.         case Empty:      fields[x][y].state = Checked; break;
  212.         case Checked:    fields[x][y].state = Questioned; break;
  213.         case Questioned: fields[x][y].state = Empty; break;
  214.     }
  215. }
  216.  
  217. void printFields(Field **fields, int width, int height)
  218. {
  219.     printf("  ");
  220.     for (int x = 0; x < width; ++x)
  221.         printf("%2d ", x + 1);
  222.     printf("\n");
  223.  
  224.     for (int y = 0; y < height; ++y)
  225.     {
  226.         printf("%2d", y + 1);
  227.         for (int x = 0; x < width; ++x)
  228.         {
  229.             switch (fields[x][y].state)
  230.             {
  231.             case Empty:      printf("   "); break;
  232.             case Checked:    printf(" ! "); break;
  233.             case Questioned: printf(" ? "); break;
  234.             case Turned:     printf(" %d ", countNeighbours(fields, width, height, x, y)); break;
  235.             case Mine:       printf(" * "); break;
  236.             }
  237.         }
  238.         printf("\n");
  239.     }
  240. }
Add Comment
Please, Sign In to add comment