Advertisement
Guest User

0.0

a guest
Apr 22nd, 2019
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 11.76 KB | None | 0 0
  1. /*   ** 遊戲設計說明:
  2.      1. 踩地雷有9*9的格子,共10顆地雷
  3.      2. 顯示數字為那一格附近的八個地區共有幾顆地雷
  4.         未顯示數字則表示附近的八個地區沒地雷
  5.  
  6.      ** 程式設計說明:
  7.      1. 將格子宣告成int cells[9][9]的陣列,存放資訊之用
  8.             0  代表安全的地區,且附近沒地雷
  9.          1~ 8  代表安全的地區,但附近有地雷,數字為地雷數
  10.            -1  代表尚未被踩到的地雷區
  11.         10~18  代表已被選取的安全地區
  12.            -2  代表已被踩到的地雷區,遊戲結束
  13.            
  14.      2. 在螢幕上印出格子
  15.      3. 請使用者輸入第一個要打開的位置(x, y)
  16.      2. 利用亂數放置地雷十顆,在不重複的位置且不是使用者輸入的位址
  17.      4. 在安全地區計算其資訊(附近幾顆地雷)
  18.      5. 將剛被選取到的安全地區值加10(代表已選取)
  19.      6. 清除螢幕
  20.      7. 顯示cells陣列中,值>10的資訊(>10代表已經選取)
  21.      8. 請使用者輸入接下來要打開的位置(x2, y2)
  22.      9. 計算(x2, y2)的值 (安全-> cells[x2][y2] += 10;地雷-> cells[x2][y2] = -2,遊戲結束)
  23.     10. 如果cells[x2, y2]的值為10,則打開附近的格子
  24.     10. 若未結束則重複step 6 ~ 9,直到贏(全部都>10 or ==-1 )就跳出
  25.     11. 詢問是否再玩一次,若再玩一次則重複2~10
  26. */
  27.  
  28. #include<stdio.h>
  29. #include<stdlib.h>
  30. #include<time.h>
  31.  
  32. void assign_initial(int cells[][11]);                                           //將格子內資訊初始化為0
  33. void print_blanks(void);                                                        //印出遊戲初始的格子
  34. void open_cell(int *op_x, int *op_y);                                           //請使用者輸入要打開的位置
  35. void put_mine(int cells[][11], int op_x, int op_y);                             //放置地雷
  36. void calculate_num_of_cells(int cells[][11]);                                   //計算非地雷區附近有幾顆地雷
  37. void assign_inf_after_open(int cells[][11], int op_x, int op_y);                //改變使用者打開的位置之資訊
  38. void open_surrounding(int cells[][11], int p_x, int op_y);                      //打開附近的區域(當格子附近無地雷時)
  39. void check_no_mine(int cells[][11], int op_x, int op_y);                        //檢查附近的區域有沒有地雷
  40. int  check_over(int cells[][11], int op_x, int op_y);                           //檢查遊戲是否結束(輸或贏)
  41. void print_cells(int cells[][11], int op_x, int op_y, int over);                //印出目前的狀況
  42. void print_condition_playing(int cells[][11]);                                  //印出尚未結束的狀況
  43. void print_condition_over(int cells[][11], int over);                           //印出遊戲結束的狀況(每個格子之資訊)
  44. char play_again(void);                                                          //詢問是否再玩一次
  45.  
  46. int main(void) {
  47.     int  cells[11][11],
  48.          open_x, open_y,
  49.          over;
  50.     char again;
  51.  
  52.     do {
  53.        system("cls");
  54.        assign_initial(cells);                                                   //將格子內資訊初始化為0
  55.        print_blanks();                                                          //印出遊戲初始的格子
  56.        open_cell(&open_x, &open_y);                                             //請使用者輸入要打開的位置
  57.        put_mine(cells, open_x, open_y);                                         //放置地雷
  58.        calculate_num_of_cells(cells);                                           //計算非地雷區附近有幾彈地雷
  59.        assign_inf_after_open(cells, open_x, open_y);                            //改變使用者打開的位置之資訊
  60.        check_no_mine(cells, open_x, open_y);                                    //檢查附近的區域有沒有地雷,並將無地雷的區域打開
  61.        over = check_over(cells, open_x, open_y);                                //檢查遊戲是否結束(輸或贏)
  62.        print_cells(cells, open_x, open_y, over);                                //印出目前的狀況
  63.        while (over == 0) {
  64.              open_cell(&open_x, &open_y);
  65.              assign_inf_after_open(cells, open_x, open_y);                      //請使用者輸入要打開的位置
  66.              check_no_mine(cells, open_x, open_y);                              //檢查附近的區域有沒有地雷,並將無地雷的區域打開
  67.              over = check_over(cells, open_x, open_y);                          //檢查遊戲是否結束(輸或贏)
  68.              print_cells(cells, open_x, open_y, over);                          //印出目前的狀況
  69.        }
  70.        again = play_again();                                                    //詢問是否再玩一次
  71.     } while (again == 'Y' || again == 'y');
  72.  
  73.     return(0);
  74. }
  75.  
  76. void assign_initial(int cells[][11]) {                                          //將格子內資訊初始化為0
  77.      int i, j;
  78.      for (i = 0; i < 11; i++)
  79.          for (j = 0; j < 11; j++)
  80.              cells[i][j] = 0;
  81. }
  82.  
  83. void print_blanks(void) {                                                       //印出遊戲初始的格子
  84.      int i, j;
  85.      printf("              遊戲說明:\n");
  86.      printf("---------------------------------------\n");
  87.      printf("※ 要開啟最左上角那格請輸入1 1\n");
  88.      printf("   往下一格則左邊的值+1(輸入:2 1)\n");
  89.      printf("   往右一格則右邊的值+1(輸入:1 2)\n");
  90.      printf("   其餘以此類推,從1 1 ~ 9 9\n");
  91.      printf("   輸入格式為:數字空格數字,如:8 2\n\n");
  92.      printf("※ 可一次輸入多格座標,\n");
  93.      printf("   座標間只需以非數字符號隔開就可以了!\n");
  94.      printf("   祝您遊戲愉快!:)\n");
  95.      printf("---------------------------------------\n\n");
  96.      printf("    ");
  97.      for (i = 1; i <= 9; i++)
  98.          printf("%2d", i);
  99.      printf("\n");
  100.      for (i = 1; i <= 9; i++) {
  101.          for (j = 0; j <= 9; j++) {
  102.              if (j == 0)
  103.                 printf("%4d", i);
  104.              else
  105.                  printf("口");
  106.          }
  107.          printf("\n");
  108.      }
  109. }
  110.  
  111. void open_cell(int *op_x, int *op_y) {                                          //請使用者輸入要打開的位置
  112.      int x, y;
  113.      printf("\n輸入您要開啟的座標 >> ");
  114.      scanf("%d%d", op_x, op_y);
  115. }
  116.  
  117. void put_mine(int cells[][11], int op_x, int op_y) {                            //放置地雷
  118.      srand(time(NULL));          //  亂數種子
  119.      int  n = 0,
  120.           rand_num,
  121.           cell_x,
  122.           cell_y;
  123.  
  124.      do {
  125.          rand_num = rand() % 81;     // ( rand() % (最大值-最小值+1)) + 最小值
  126.          cell_x = (rand_num % 9) + 1;
  127.          cell_y = ((rand_num - cell_x) / 9) + 1;
  128.          if (cells[cell_x][cell_y] != -1 && !(cell_x == op_x && cell_y == op_y)) {
  129.              cells[cell_x][cell_y] = -1;
  130.              n++;
  131.          }
  132.      } while (n < 10);
  133. }
  134.  
  135. void calculate_num_of_cells(int cells[][11]) {                                  //計算非地雷區附近有幾彈地雷
  136.      int i, j, u, v;
  137.      for (i = 1; i <= 9; i++)
  138.          for (j = 1; j <= 9; j++)
  139.              if (cells[i][j] == 0)
  140.                 for (u = i - 1; u <= i + 1; u++)
  141.                     for (v = j - 1; v <= j + 1; v++)
  142.                         if (cells[u][v] == -1)
  143.                            cells[i][j]++;
  144. }
  145.  
  146. void assign_inf_after_open(int cells[][11], int op_x, int op_y) {               //改變使用者打開的位置之資訊
  147.      if (cells[op_x][op_y] == -1)
  148.         cells[op_x][op_y] = -2;
  149.      if (cells[op_x][op_y] >= 0 && cells[op_x][op_y] <= 8)
  150.         cells[op_x][op_y] += 10;
  151. }
  152.  
  153. void open_surrounding(int cells[][11], int op_x, int op_y) {                    //打開附近的區域(當格子附近無地雷時)
  154.      int i, j;
  155.      for (i = op_x - 1; i <= op_x + 1; i++) {
  156.          for (j = op_y - 1; j <= op_y + 1; j++) {
  157.              if (cells[i][j] >= 0 && cells[i][j] <=8 && i % 10 != 0 && j %10 != 0) {
  158.                 cells[i][j] += 10;
  159.                 check_no_mine(cells, i, j);
  160.              }
  161.          }
  162.      }
  163. }
  164.  
  165. void check_no_mine(int cells[][11], int op_x, int op_y) {                       //檢查附近的區域有沒有地雷
  166.      if (cells[op_x][op_y] == 10)        //附近沒地雷
  167.         open_surrounding(cells, op_x, op_y);
  168. }
  169.  
  170. void print_condition_playing(int cells[][11]) {                                 //印出尚未結束的狀況
  171.      int i, j;
  172.      printf("      ");
  173.      for (i = 1; i <= 9; i++)
  174.          printf("%2d", i);
  175.      printf("\n    ┌---------┐\n");
  176.      for (i = 1; i <= 9; i++) {
  177.              for (j = 0; j <= 9; j++) {
  178.                  if (j == 0)
  179.                     printf("%4d|", i);
  180.                  else if (cells[i][j] < 10)
  181.                       printf("口");
  182.                  else if (cells[i][j] == 10)
  183.                       printf(" 0");
  184.                  else if (cells[i][j] > 10 && cells[i][j] <= 18)
  185.                       printf(" %d", cells[i][j] - 10);
  186.                  if (j == 9)
  187.                     printf("|%d", i);
  188.          }
  189.          printf("\n");
  190.      }
  191.      printf("    └---------┘\n");
  192.      printf("      ");
  193.      for (i = 1; i <= 9; i++)
  194.          printf("%2d", i);
  195.      printf("\n");
  196. }
  197.      
  198.      
  199. void print_condition_over(int cells[][11], int over) {                          //印出遊戲結束的狀況(每個格子之資訊)
  200.      int i, j;
  201.      printf("  ┌---------┐\n");
  202.      for (i = 1; i <= 9; i++) {
  203.          for (j = 0; j <= 10; j++) {
  204.              if (j  == 0)
  205.                 printf("  |");
  206.              else if (j == 10)
  207.                   printf("|");
  208.              else if(cells[i][j] % 10 == 0)
  209.                   printf(".");
  210.              else if (cells[i][j] == -1)
  211.                   printf(" *");
  212.              else if (cells[i][j] == -2)
  213.                   printf("⊕");
  214.              else
  215.                  printf("%2d", cells[i][j] % 10);
  216.          }
  217.          printf("\n");
  218.      }
  219.      printf("  └---------┘\n");
  220.      if (over == 1)
  221.         printf(".ˇ.恭喜你~~贏了!\n\n");
  222.      else
  223.          printf("ˊ_ˋ爆了…… \n\n");
  224.      printf("數字代表周圍八格地雷總數量\n");
  225.      printf("*代表地雷\n");
  226.      printf(".代表周圍沒地雷\n");
  227.      printf("⊕代表爆掉的地雷。\n");
  228.      printf("感謝您的賞光~~~\n");
  229. }
  230.      
  231. void print_cells(int cells[][11], int op_x, int op_y, int over) {               //印出目前的狀況
  232.      system("cls");
  233.      printf("\n");
  234.      int i, j;
  235.      if (over == 0) {
  236.         print_condition_playing(cells);
  237.      } else
  238.            print_condition_over(cells, over);
  239. }
  240.  
  241. int  check_over(int cells[][11], int op_x, int op_y) {                          //檢查遊戲是否結束(輸或贏)
  242.     //result == 0 ->尚未結束,result == 1 ->贏,result == -1 ->
  243.     int i, j, result = 1;
  244.     if (cells[op_x][op_y] == -2) {
  245.        result = -1;
  246.     } else {
  247.            for (i = 1; i <= 9 && result == 1; i++)
  248.                for (j = 1; j <= 9 && result == 1; j++)
  249.                    if ((cells[i][j] >= 0 && cells[i][j] <= 8))
  250.                       result = 0;
  251.     }
  252.     return(result);
  253. }
  254.  
  255. char play_again(void) {                                                         //詢問是否再玩一次
  256.      char again;
  257.      printf("\n還要再玩一次嗎?");
  258.      do {
  259.         printf("\n要再玩一次的話請輸入Y,\n");
  260.         printf("或輸入N關閉程式。 >>");
  261.         scanf(" %c", &again);
  262.      } while (again != 'Y' && again != 'y' && again != 'N' && again != 'n');
  263.      return(again);
  264. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement