一、掃雷游戲分析 關鍵步驟:兩個二維數組的大小為11*11,但實際上操作的只有中心的9*9的棋盤,創建另外兩行的原因是方便統計一個坐標周圍3*3的雷的個數1.創建兩個二維數組一個存放佈置好的雷(1號),另外一個存放空的棋盤(2號)2.選手選出來的坐標傳到1號棋盤上對坐標進行分析如果是雷就返回被炸死了 ...
一、掃雷游戲分析
關鍵步驟:
兩個二維數組的大小為11*11,但實際上操作的只有中心的9*9的棋盤,創建另外兩行的原因是方便統計一個坐標周圍3*3的雷的個數
1.創建兩個二維數組一個存放佈置好的雷(1號),另外一個存放空的棋盤(2號)
2.選手選出來的坐標傳到1號棋盤上對坐標進行分析如果是雷就返回被炸死了,不是雷就算一下這個坐標周邊一圈
有多少雷,併在2號棋盤上顯示出來
結束標誌:沒被炸死,且棋盤上還剩下雷的個數的位置沒被探索
二、代碼
game.h
#define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <stdlib.h> #include <time.h> #define ROW 9 #define COL 9 #define ROWS ROW+2 #define COLS COL+2 #define MINES 10 //初始化 void InitBoard(char board[ROWS][COLS], int rows, int cols, char ch); //展示 void DisPlay(char board[ROWS][COLS], int row, int col); //佈置雷 void LayMine(char board[ROWS][COLS], int row, int col); //開始游戲 void Play(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
game.c
#define _CRT_SECURE_NO_WARNINGS 1 #include "game.h" //初始化 void InitBoard(char board[ROWS][COLS], int rows, int cols, char ch) { for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { board[i][j] = ch; } } } //展示 void DisPlay(char board[ROWS][COLS], int row, int col) { for (int i = 0; i <= col; i++) { printf("%d ", i); } printf("\n"); for (int i = 1; i <= row; i++) { printf("%d ", i); for (int j = 1; j <= col; j++) { printf("%c ", board[i][j]); } printf("\n"); } } //佈置雷 void LayMine(char board[ROWS][COLS], int row, int col) { int x, y; int count = MINES;//雷的數量 //要把雷佈置在棋盤1-9的位置上 while (count) { x = rand() % 9 + 1; y = rand() % 9 + 1;//生成1-9的隨機坐標 if (board[x][y] == '0') { board[x][y] = '1'; count--; } } } //(x-1,y-1) (x-1,y) (x-1,y+1) //(x,y-1) (x,y) (x,y+1) //(x+1,y-1) (x+1,y) (x+1,y+1) //這個函數是用來統計輸入的坐標旁邊一共有多少個雷的 int CountMine(char mine[ROWS][COLS], int x, int y) { return mine[x - 1][y - 1] + mine[x - 1][y] + mine[x - 1][y + 1] + mine[x][y - 1] + mine[x][y + 1] + mine[x + 1][y - 1] + mine[x + 1][y] + mine[x + 1][y + 1] - 7*'0'; } //該函數通過遞歸來實現一片空白區域的連續展開 void Expand(char show[ROWS][COLS], char mine[ROWS][COLS], int x, int y) { //條件:如果show[x][y]處為'*'就進行展開求值 if(show[x][y]=='*') { show[x][y] = CountMine(mine, x, y); } //&&x>1&&x<9&&y>1&&y<9 //用於調試 if (show[x][y] == '0' && x >= 1 && x <= 9 && y>=1 && y <= 9)//這一句很重要,要不然一次性就把棋盤外面的一起展開了 { if (show[x - 1][y - 1] == '*')//同樣判斷要展開的位置是否是'*'也很重要,要不然就會棧溢出陷入死遞歸 { Expand(show, mine, x - 1, y - 1); } if(show[x - 1][y] == '*') { Expand(show, mine, x - 1, y); } if (show[x - 1][y+1] == '*') { Expand(show, mine, x - 1, y + 1); } if (show[x][y-1] == '*') { Expand(show, mine, x, y - 1); } if (show[x][y+1] == '*') { Expand(show, mine, x, y + 1); } if (show[x+1][y-1] == '*') { Expand(show, mine, x + 1, y-1); } if (show[x + 1][y] == '*') { Expand(show, mine, x + 1, y ); } if (show[x + 1][y +1] == '*') { Expand(show, mine, x + 1, y + 1); } } } //正式游戲 void Play(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) { int x, y; while (1) { int count = 0; printf("請輸入坐標:>"); scanf("%d%d", &x, &y); if (x >= 1 && x <=9 && y >= 1 && y <= 9)//確保合理輸入範圍 { if (mine[x][y] == '1') { printf("Game Over\n"); DisPlay(mine, ROW, COL); //用於顯示失敗後的雷區 break; } //else if (mine[x][y] != '1') //{ // show[x][y] = CountMine(mine,x,y); // /*printf("%d\n", CountMine(show, x, y));*///用於測試 // DisPlay(show, ROW, COL); //} else if (mine[x][y] != '1') { show[x][y] = CountMine(mine, x, y); if (show[x][y] == '0') { Expand(show, mine, x, y); } DisPlay(show, ROW, COL); } } else { printf("Error Location\n"); } //判斷是否成功,當show中剩餘的‘*’等於雷的個數時且還沒被炸死時就贏了 for (int i = 1; i <= row; i++) { for (int j = 1; j <= col; j++) { if (show[i][j] == '*') { count++; } } } if (count == MINES) { printf("Win\n"); DisPlay(mine, ROW, COL); //用於顯示勝利後的雷區 break; } } }
test.c
#define _CRT_SECURE_NO_WARNINGS 1 #include "game.h" menu() //選擇菜單 { printf(" \n"); printf(" 1.Play 0.Exit \n"); printf(" \n"); } void game() { char mine[ROWS][COLS] = { 0 };//用於存放地雷 char show[ROWS][COLS] = { 0 };//用於展示 InitBoard(mine, ROWS, COLS, '0');//將第一個放雷的棋盤全部初始化成'0' InitBoard(show, ROWS, COLS, '*');//將第二個展示的棋盤全部初始化成'*' //DisPlay(mine, ROW, COL);//只展示中心9*9的棋盤 DisPlay(show, ROW, COL); LayMine(mine, ROW, COL);//在mine棋盤裡佈置雷 //DisPlay(mine, ROW, COL);//用於測試 //開始玩掃雷 Play(mine, show,ROW,COL); } int main() { srand((unsigned int)time(NULL));//用於生成隨機雷 int input;//玩家要輸入的選擇 do { menu(); printf("請選擇:>"); scanf("%d", &input); switch (input) { case 1: game();//游戲主體 break; case 0: printf("Exit Game\n"); break; default: printf("Error Choice\n"); break; } } while (input); return 0; }
三、測試結果展示