Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <time.h>
- enum State { Playing, Lost, Won };
- enum FieldState { Empty, Checked, Questioned, Turned, Mine };
- struct Field
- {
- bool mine;
- FieldState state;
- };
- void init(Field **fields, int width, int height, int mineAmount, int *unturnedAmount, State *state);
- int countNeighbours(Field **fields, int width, int height, int x, int y);
- void floodTurnField(Field **fields, int width, int height, int x, int y, int *unturnedAmount);
- void turnField(Field **fields, int width, int height, int x, int y, int mineAmount, int *unturnedAmount, State *state);
- void markField(Field **fields, int width, int height, int x, int y, State state);
- void printFields(Field **fields, int width, int height);
- void main()
- {
- srand((unsigned int)time(0));
- Field **fields;
- int width, height;
- int mineAmount;
- int unturnedAmount;
- State state;
- printf("Enter width: ");
- scanf("%d", &width);
- printf("Enter height: ");
- scanf("%d", &height);
- printf("Enter amount of mines: ");
- scanf("%d", &mineAmount);
- fields = new Field*[width];
- for (int i = 0; i < width; ++i)
- fields[i] = new Field[height];
- init(fields, width, height, mineAmount, &unturnedAmount, &state);
- while (state == Playing)
- {
- printFields(fields, width, height);
- char action[4 + 1];
- int x, y;
- printf("Enter action (mark/turn x y): ");
- scanf("%s %d %d", action, &x, &y);
- switch (action[0])
- {
- case 'm': case 'M': markField(fields, width, height, x - 1, y - 1, state); break;
- case 't': case 'T': turnField(fields, width, height, x - 1, y - 1, mineAmount, &unturnedAmount, &state); break;
- }
- }
- printFields(fields, width, height);
- printf((state == Won) ? "You won!\n" : "You lost!\n");
- for (int i = 0; i < width; ++i)
- delete[] fields[i];
- delete[] fields;
- }
- void init(Field **fields, int width, int height, int mineAmount, int *unturnedAmount, State *state)
- {
- *unturnedAmount = width*height;
- for (int x = 0; x < width; ++x)
- {
- for (int y = 0; y < height; ++y)
- {
- fields[x][y].mine = false;
- fields[x][y].state = Empty;
- }
- }
- for (int m = 0; m < mineAmount; ++m)
- {
- int x, y;
- do {
- x = rand()%width;
- y = rand()%height;
- } while (fields[x][y].mine);
- fields[x][y].mine = true;
- }
- *state = Playing;
- }
- int countNeighbours(Field **fields, int width, int height, int x, int y)
- {
- int count = 0;
- int xm1 = x - 1;
- int xp1 = x + 1;
- int ym1 = y - 1;
- int yp1 = y + 1;
- if (xm1 >= 0)
- {
- count += fields[xm1][y].mine ? 1 : 0;
- if (ym1 >= 0)
- count += fields[xm1][ym1].mine ? 1 : 0;
- }
- if (ym1 >= 0)
- {
- count += fields[x][ym1].mine ? 1 : 0;
- if (xp1 < width)
- count += fields[xp1][ym1].mine ? 1 : 0;
- }
- if (xp1 < width)
- {
- count += fields[xp1][y].mine ? 1 : 0;
- if (yp1 < height)
- count += fields[xp1][yp1].mine ? 1 : 0;
- }
- if (yp1 < height)
- {
- count += fields[x][yp1].mine ? 1 : 0;
- if (xm1 >= 0)
- count += fields[xm1][yp1].mine ? 1 : 0;
- }
- return count;
- }
- void floodTurnField(Field **fields, int width, int height, int x, int y, int *unturnedAmount)
- {
- if (fields[x][y].state == Turned)
- return;
- fields[x][y].state = Turned;
- --(*unturnedAmount);
- if (!countNeighbours(fields, width, height, x, y))
- {
- int xm1 = x - 1;
- int xp1 = x + 1;
- int ym1 = y - 1;
- int yp1 = y + 1;
- if (xm1 >= 0)
- {
- floodTurnField(fields, width, height, xm1, y, unturnedAmount);
- if (ym1 >= 0)
- floodTurnField(fields, width, height, xm1, ym1, unturnedAmount);
- }
- if (ym1 >= 0)
- {
- floodTurnField(fields, width, height, x, ym1, unturnedAmount);
- if (xp1 < width)
- floodTurnField(fields, width, height, xp1, ym1, unturnedAmount);
- }
- if (xp1 < width)
- {
- floodTurnField(fields, width, height, xp1, y, unturnedAmount);
- if (yp1 < height)
- floodTurnField(fields, width, height, xp1, yp1, unturnedAmount);
- }
- if (yp1 < height)
- {
- floodTurnField(fields, width, height, x, yp1, unturnedAmount);
- if (xm1 >= 0)
- floodTurnField(fields, width, height, xm1, yp1, unturnedAmount);
- }
- }
- }
- void turnField(Field **fields, int width, int height, int x, int y, int mineAmount, int *unturnedAmount, State *state)
- {
- if ((*state != Playing) || (fields[x][y].state == Turned) || (fields[x][y].state == Mine))
- return;
- if (fields[x][y].mine)
- {
- *state = Lost;
- for (int ix = 0; ix < width; ++ix)
- for (int iy = 0; iy < height; ++iy)
- fields[ix][iy].state = fields[ix][iy].mine ? Mine : Turned;
- return;
- }
- floodTurnField(fields, width, height, x, y, unturnedAmount);
- if (*unturnedAmount == mineAmount)
- {
- *state = Won;
- for (int ix = 0; ix < width; ++ix)
- for (int iy = 0; iy < height; ++iy)
- fields[ix][iy].state = fields[ix][iy].mine ? Checked : Turned;
- return;
- }
- }
- void markField(Field **fields, int width, int height, int x, int y, State state)
- {
- if (state != Playing)
- return;
- switch (fields[x][y].state)
- {
- case Empty: fields[x][y].state = Checked; break;
- case Checked: fields[x][y].state = Questioned; break;
- case Questioned: fields[x][y].state = Empty; break;
- }
- }
- void printFields(Field **fields, int width, int height)
- {
- printf(" ");
- for (int x = 0; x < width; ++x)
- printf("%2d ", x + 1);
- printf("\n");
- for (int y = 0; y < height; ++y)
- {
- printf("%2d", y + 1);
- for (int x = 0; x < width; ++x)
- {
- switch (fields[x][y].state)
- {
- case Empty: printf(" "); break;
- case Checked: printf(" ! "); break;
- case Questioned: printf(" ? "); break;
- case Turned: printf(" %d ", countNeighbours(fields, width, height, x, y)); break;
- case Mine: printf(" * "); break;
- }
- }
- printf("\n");
- }
- }
Add Comment
Please, Sign In to add comment