HoangMinhNguyen

Minesweeper

Oct 26th, 2022 (edited)
12
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.11 KB | Source Code | 0 0
  1. #include <bits/stdc++.h>
  2. #include <conio.h>
  3. #define ii pair<int,int>
  4. #define fi first
  5. #define se second
  6.  
  7. using namespace std;
  8.  
  9. //----Variables----//
  10. int level;
  11. int bombs_level[5] = {0, 10 , 40 , 99 , -1 };
  12. ii grid_level[5] = {ii(1,1), ii(9,9) , ii(16,16) , ii(16,30), ii(-1,-1) };
  13. bool is_bomb[35*35];//
  14. char board[35][35]; //real board state
  15. char cur_board[35][35]; //display board state
  16. int dx[8] = {1,-1,0,0,1,1,-1,-1}; // direction
  17. int dy[8] = {0,0,1,-1,1,-1,1,-1};
  18. ii DIR[260];
  19. int cur_x = 1, cur_y = 1;
  20. int flag = 0;
  21.  
  22.  
  23. //----------------Clear the console screen-----------------------------//
  24. void Clear(){
  25. #if defined _WIN32
  26.     system("cls");
  27. #elif defined (__LINUX__) || defined(__gnu_linux__) || defined(__linux__)
  28.     system("clear");\
  29. #elif defined (__APPLE__)
  30.     system("clear");
  31. #endif
  32. }
  33.  
  34.  
  35. //-----------Welcome the player-------------------------//
  36. void Welcome(){
  37.     cout << "--------Welcome to the Minesweeper game!-------";
  38.     cout << endl;
  39.     cout << endl;
  40.     cout << endl;
  41.     cout << "           -------------------------           "; cout << endl;
  42.     cout << "           |Press enter key to play|           "; cout << endl;
  43.     cout << "           -------------------------           ";
  44.     cin.ignore();
  45.     Clear();
  46. }
  47.  
  48.  
  49. //---Chosing level---//
  50. void Chosing_level(){
  51.     cout << "Chose your level:" << endl;
  52.     cout << "1 is for begginer \n";
  53.     cout << "2 is for intermediate \n";
  54.     cout << "3 is for expert \n";
  55.     cout << "4 is custom game \n";
  56.     cout << "Which level do you want to play? \n";
  57.     cin >> level;
  58.     Clear();
  59. }
  60.  
  61. //---Randomize---//
  62. int Rand(int l, int r){
  63.     return rand()%(r-l+1);
  64. }
  65.  
  66. //---Convert 2D to 1D and vice versa---//
  67. int Convert_to_1D(int x, int y){
  68.     return grid_level[level].se*(x-1) + y;
  69. }
  70.  
  71. ii Convert_to_2D(int val){
  72.     int x, y;
  73.     if (val%grid_level[level].se==0){
  74.         y = grid_level[level].se;
  75.         x = val/grid_level[level].se;
  76.     }
  77.     else{
  78.         x = val/grid_level[level].se+1;
  79.         y = val%grid_level[level].se;
  80.     }
  81.     return ii(x,y);
  82. }
  83.  
  84.  
  85. //---Display the board---//
  86. void Display_the_board(){
  87.     for(int i=1; i<=grid_level[level].fi; i++){
  88.         if (cur_x==i && cur_y==1) cout << "[";
  89.         else cout << " ";
  90.         for(int j=1; j<=grid_level[level].se; j++){
  91.             cout << cur_board[i][j];
  92.             if (cur_x==i && cur_y==j) cout << "]";
  93.             else if (cur_x==i && j==cur_y-1) cout << "[";
  94.             else cout << " ";
  95.         }
  96.         cout << endl;
  97.     }
  98.     cout << endl;
  99.     cout << "Flag left: " << bombs_level[level] - flag << '\n';
  100.     cout << endl << endl << endl;
  101.     system("Color E4");
  102.     cout << "------------Basic movement keys------------" << endl;
  103.     cout << "Use the arrow keys to move around the board" << endl;
  104.     cout << "'Enter' to open a cell" << endl;
  105.     cout << "'Space' to flag a cell" << endl;
  106.     cout << "'Z' to open every cell around the number cell that all bombs are flagged" << endl;
  107.     cout << "'ESC' to exit the game";
  108. }
  109.  
  110.  
  111. //---checking border---//
  112. bool ok(int x, int y){
  113.     return 1 <= x && x <= grid_level[level].fi && 1 <= y && y <= grid_level[level].se;
  114. }
  115.  
  116.  
  117. //---Preprocess---//
  118. void Preprocess_the_board(){
  119.     //Preprocess the arrow keys
  120.     DIR[75] = ii(0,-1);
  121.     DIR[77] = ii(0,1);
  122.     DIR[80] = ii(1,0);
  123.     DIR[72] = ii(-1,0);
  124.  
  125.     //Input custom level
  126.     if (level==4){
  127.         int grid_x, grid_y, bombs;
  128.         cout << "Input your width: "; cin >> grid_x;
  129.         cout << "Input your length: "; cin >> grid_y;
  130.         cout << "Input your number of bombs: "; cin >> bombs;
  131.         Clear();
  132.         bombs_level[4] = bombs;
  133.         grid_level[4] = ii(grid_x,grid_y);
  134.     }
  135.  
  136.     //generate a board with no bomb
  137.     int wid = grid_level[level].fi;
  138.     int len = grid_level[level].se;
  139.     int num_bomb = bombs_level[level];
  140.     for(int i=1; i<=wid; i++){
  141.         for(int j=1; j<=len; j++){
  142.             board[i][j] = 'O';
  143.         }
  144.     }
  145.  
  146.     //reset bombs state
  147.     for(int i=1; i <= wid*len; i++) is_bomb[i] = false;
  148.  
  149.     //randomize bombs
  150.     srand(time(NULL));
  151.     for(int i=1; i<=num_bomb; i++){
  152.         while (1){
  153.             int Cur_bomb = Rand(1,wid*len);
  154.             if (is_bomb[Cur_bomb]) continue;
  155.             else{
  156.                 is_bomb[Cur_bomb] = true;
  157.                 ii pos = Convert_to_2D(Cur_bomb);
  158.                 board[pos.fi][pos.se] = '*';
  159.                 break;
  160.             }
  161.         }
  162.     }
  163.  
  164.     //"Number" the board
  165.     for(int i=1; i<=wid; i++){
  166.         for(int j=1; j<=len; j++){
  167.             //init the current gameplay board
  168.             cur_board[i][j] = '.';
  169.  
  170.             if (board[i][j]!='*'){
  171.                 int num = 0;
  172.                 for(int k=0; k<8; k++){
  173.                     int x = i + dx[k];
  174.                     int y = j + dy[k];
  175.                     if (ok(x,y) && board[x][y]=='*') num++;
  176.                 }
  177.                 if (num!=0) board[i][j] = (char)(num+'0');
  178.             }
  179.         }
  180.     }
  181. }
  182.  
  183. //---Move---//
  184. void Move(ii add){
  185.     int x = cur_x + add.fi;
  186.     int y = cur_y + add.se;
  187.     if (ok(x,y)){
  188.         cur_x = x;
  189.         cur_y = y;
  190.     }
  191. }
  192.  
  193. //---BFS---//
  194. void bfs(){
  195.     queue<ii> q;
  196.     q.push(ii(cur_x,cur_y));
  197.     cur_board[cur_x][cur_y] = board[cur_x][cur_y];
  198.     while (q.size()){
  199.         int u = q.front().fi;
  200.         int v = q.front().se;
  201.         q.pop();
  202.         if (board[u][v]!='O') continue;
  203.         for(int k=0; k<8; k++){
  204.             int x = u + dx[k];
  205.             int y = v + dy[k];
  206.             if (ok(x,y) && cur_board[x][y]=='.'){
  207.                 cur_board[x][y] = board[x][y];
  208.                 if (board[x][y]=='O') q.push(ii(x,y));
  209.             }
  210.         }
  211.     }
  212. }
  213.  
  214. //---End game---//
  215. void End_game(){
  216.     Clear();
  217.     for(int i=1; i<=grid_level[level].fi; i++){
  218.         if (cur_x==i && cur_y==1) cout << "[";
  219.         else cout << " ";
  220.         for(int j=1; j<=grid_level[level].se; j++){
  221.             cout << cur_board[i][j];
  222.             if (cur_x==i && cur_y==j) cout << "]";
  223.             else if (cur_x==i && j==cur_y-1) cout << "[";
  224.             else cout << " ";
  225.         }
  226.         cout << endl;
  227.     }
  228.     cout << endl << "YOU LOSE \n";
  229.     cin.ignore();
  230.     exit(0);
  231. }
  232.  
  233. //---process enter query---//
  234. void Process_Enter(){
  235.     if (board[cur_x][cur_y]=='O'){
  236.         bfs();
  237.     }
  238.     else if (board[cur_x][cur_y]=='*'){
  239.         cur_board[cur_x][cur_y] = board[cur_x][cur_y];
  240.         End_game();
  241.     }
  242.     else{
  243.         cur_board[cur_x][cur_y] = board[cur_x][cur_y];
  244.     }
  245. }
  246.  
  247. //---process space query---//
  248. void Process_Space(){
  249.     if (cur_board[cur_x][cur_y]!='.' && cur_board[cur_x][cur_y]!='F') return;
  250.     if (cur_board[cur_x][cur_y] == '.') cur_board[cur_x][cur_y] = 'F', flag++;
  251.     else cur_board[cur_x][cur_y] = '.', flag--;
  252. }
  253.  
  254. //---process Z query---//
  255. void Process_Z(){
  256.     if (cur_board[cur_x][cur_y]=='P' || cur_board[cur_x][cur_y]=='O') return; //If not number cell then do nothing
  257.     int num_flag = 0;
  258.     queue<ii> q;
  259.     for(int k=0; k<8; k++){
  260.         int x = cur_x + dx[k];
  261.         int y = cur_y + dy[k];
  262.         if (ok(x,y) && cur_board[x][y]=='F') num_flag++;
  263.         if (ok(x,y) && cur_board[x][y]=='.'){
  264.             cur_board[x][y] = board[x][y];
  265.             if (board[x][y]=='*') End_game();
  266.             if (board[x][y]=='O') q.push(ii(x,y));
  267.         }
  268.     }
  269.     if (num_flag != cur_board[cur_x][cur_y]-'0') return; //If not enough flag around then do nothing
  270.     while (q.size()){
  271.         int u = q.front().fi;
  272.         int v = q.front().se;
  273.         q.pop();
  274.         for(int k=0; k<8; k++){
  275.             int x = u + dx[k];
  276.             int y = v + dy[k];
  277.             if (ok(x,y) && cur_board[x][y]=='.' && board[x][y]!='*'){
  278.                 cur_board[x][y] = board[x][y];
  279.                 if (board[x][y]=='O') q.push(ii(x,y));
  280.             }
  281.         }
  282.     }
  283. }
  284.  
  285. //---Check winning state---//
  286. bool Check_win(){
  287.     bool ok = true;
  288.     for(int i=1; i<=grid_level[level].fi; i++){
  289.         for(int j=1; j<=grid_level[level].se; j++){
  290.             if (cur_board[i][j]=='F' && board[i][j]=='*') continue;
  291.             if (cur_board[i][j]!=board[i][j]) ok = false;
  292.         }
  293.     }
  294.     return ok;
  295. }
  296.  
  297. //----Main Game Structure----//
  298. void Play(){
  299.     while(1){
  300.         Display_the_board();
  301.         if (Check_win()){
  302.             Clear();
  303.             system("Color E1");
  304.             cout << "----Congratulations----" << endl;
  305.             cout << " You have win the game " << endl;
  306.             cout << "Number of bombs defused: " << bombs_level[level] << endl;
  307.             cin.ignore();
  308.             exit(0);
  309.         }
  310.         char key_pressed = getch();
  311.         int ascii = key_pressed;
  312.         if (ascii==75 || ascii==80 || ascii==77 || ascii==72){
  313.             Move(DIR[ascii]);
  314.         }
  315.         else if (ascii==13){
  316.             Process_Enter();
  317.         }
  318.         else if (ascii==32){
  319.             Process_Space();
  320.         }
  321.         else if (ascii==122){
  322.             Process_Z();
  323.         }
  324.         Clear();
  325.         if (ascii==27) break;
  326.     }
  327. }
  328.  
  329. int main()
  330. {
  331.     Welcome();
  332.     Chosing_level();
  333.     Preprocess_the_board();
  334.     Play();
  335.     return 0;
  336. }
  337.  
Advertisement
Add Comment
Please, Sign In to add comment