C語言掃雷排雷小游戲?qū)崿F(xiàn)全程
test.c
在這個文件中,我們主要是完成游戲邏輯的測試,在這里我們要注意的點,我們建立了二個數(shù)組,mine數(shù)組我們用來存放布置雷的信息,show數(shù)組存放排查出雷的信息。本次排雷區(qū)域是9*9的格子,為了防止數(shù)組出現(xiàn)越界,我們特意把數(shù)組的下標定義大點變?yōu)?1*11。
#define _CRT_SECURE_NO_WARNINGS #include"game.h" void game() { char mine[ROWS][COLS] = { 0 };//存放布置雷的信息 char show[ROWS][COLS] = { 0 };//存放排查出雷的信息 //初始化棋盤 InitBoard(mine, ROWS, COLS, '0'); InitBoard(show, ROWS, COLS, '*'); //打印棋盤 DisplayBoard(show, ROW, COL); //設(shè)置雷 SetMine(mine, ROW, COL); //找雷 /*DisplayBoard(mine, ROW, COL);*///開局顯示雷的位置 FindMine(mine,show, ROW, COL); } void menu() { printf("*************************\n"); printf("****** 1.play *****\n"); printf("****** 0.exit *****\n"); printf("*************************\n"); } int main() { srand((unsigned int)time(NULL)); int input = 0; do { menu(); printf("請選擇>: "); scanf("%d", &input); switch (input) { case 1: game(); break; case 0: printf("退出游戲\n"); break; default: printf("選擇錯誤,請重新選擇:>\n"); } } while (input); return 0; }
game.h
這個文件,我們用來實現(xiàn)游戲所用頭文件的包含,游戲常量的定義,函數(shù)的聲明。
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<time.h> #include<stdlib.h> //定義棋盤數(shù) #define ROW 9 #define COL 9 #define ROWS ROW+2 #define COLS COL+2 //定義雷數(shù) #define EASY_COUNT 10 //函數(shù)的聲明 void InitBoard(char board[ROWS][COLS], int rows, int cols, char set); void DisplayBoard(char board[ROWS][COLS], int row, int col); void SetMine(char mine[ROWS][COLS], int row, int col); void FindMine(char mine[ROWS][COLS],char show[ROWS][COLS], int row, int col); void UnfoldMine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y, int row, int col, int* win);
game.c
在這里,我們實現(xiàn)掃雷游戲的整體過程,我們可以分為:初化掃雷區(qū),打印掃雷區(qū),設(shè)置雷和排雷。
#define _CRT_SECURE_NO_WARNINGS #include"game.h" //初化掃雷區(qū) void InitBoard(char board[ROWS][COLS], int rows, int cols, char set) { int i = 0; int j = 0; for (i = 0;i < rows;i++) { for (j = 0;j < cols;j++) { board[i][j] = set; } } } //打印掃雷區(qū) void DisplayBoard(char board[ROWS][COLS], int row, int col) { int i = 0; int j = 0; printf("--------掃雷游戲--------\n"); //打印列提示數(shù) for (j = 0;j <= col;j++) { printf("%d ", j); } printf("\n"); for (i = 1;i <= row;i++) { printf("%d ", i);//打印行提示數(shù) for (j = 1;j <=col;j++) { printf("%c ", board[i][j]); } printf("\n"); } printf("---------掃雷游戲-------\n"); } //設(shè)置雷 void SetMine(char mine[ROWS][COLS], int row, int col) { int count = EASY_COUNT; while (count) { int x = rand() % row + 1;//生成0~9之間的數(shù) int y = rand() % col + 1;//生成0~9之間的數(shù) if (mine[x][y] == '0') { mine[x][y] = '1'; count--; } } } //返回周圍雷的個數(shù) int get_mine_count(char board[ROWS][COLS], int x, int y) { return ( board[x - 1][y] + board[x + 1][y] + board[x - 1][y - 1] + board[x][y - 1] + board[x + 1][y - 1] + board[x - 1][y + 1] + board[x][y + 1] + board[x + 1][y + 1] - 8 * '0'); } //展開一片沒有雷的地區(qū),用遞歸實現(xiàn) //遞歸結(jié)束的條件: //1 該坐標不是雷 //2 該坐標不是空格(防止死遞歸) void UnfoldMine(char mine[ROWS][COLS], char show[ROWS][COLS],int x,int y,int row,int col,int* win) { if ((show[x][y]!=' ' &&mine[x][y]!='1')|| (show[x][y]) == '#') { int count = get_mine_count(mine, x, y); if (count == 0) { show[x][y] = ' ';//無雷設(shè)置為空格 (*win)--;//無雷的位置減1 int i = 0; int j = 0; for (i = -1;i <= 1;i++) { for (j = -1;j <= 1;j++) { UnfoldMine(mine, show, x + i, y + j, row, col, &win); } } } //不符合遞歸的條件 else { show[x][y] = count + '0'; (*win)--; } } } //排雷 void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) { int x = 0; int y = 0; int m = 0;//標記的橫坐標 int n = 0;//標記的縱坐標 int sign = 0;//標記的選擇 int win = ROW*COL-EASY_COUNT;//找到不是雷的次數(shù) while (win) { do { printf("請選擇是否要標記雷:>0/1\n"); scanf("%d", &sign); switch(sign) { case 1: printf("請輸入要標記的坐標:>"); again: scanf("%d%d", &m, &n); if (show[m][n] == '*') { show[m][n] = '#';//用'#'標記雷 DisplayBoard(show, ROW, COL);//展示標記 } else { printf("該位置不需要標記,請重新選擇:>\n"); goto again; } break; case 0: break; default: printf("選擇錯誤,請重新選擇:>"); break; } } while (sign); printf("\n"); printf("請選擇要排查雷的坐標:>"); scanf("%d%d", &x, &y); if (x >= 1 && x <= row && y >= 1 && y <= col) { if ((show[x][y] != '*') && (show[x][y] != '#')) { printf("該坐標以前被排查過了,請重新選擇\n"); } else { if (mine[x][y] == '1') { printf("很遺憾,你被炸死了\n"); DisplayBoard(mine, ROW, COL);//打印雷區(qū) break; } else { UnfoldMine(mine, show, x, y, ROW,COL, &win);//注意這里要傳win的地址,讓形參和實參建立聯(lián)系 DisplayBoard(show, ROW, COL);//展示棋盤 } } } else { printf("選擇坐標違規(guī),請重新選擇:>\n"); } } if (win == 0)//判斷位置是否都找完 { printf("恭喜你,排雷成功\n"); DisplayBoard(mine, ROW, COL);//顯示埋雷的棋盤 } }
詳解游戲代碼的實現(xiàn)
1初化掃雷區(qū)
這里我們規(guī)定:
無雷我們用0表示;
初始界面用*表示;
為了解決二個數(shù)組的初始化問題,我們將數(shù)組mine和數(shù)組show要初始化的內(nèi)容直接傳過來,我們用set接收.
/初化掃雷區(qū) void InitBoard(char board[ROWS][COLS], int rows, int cols, char set) { int i = 0; int j = 0; for (i = 0;i < rows;i++) { for (j = 0;j < cols;j++) { board[i][j] = set; } } }
2打印掃雷區(qū)
這部分主要實現(xiàn)的功能是為了我們能夠打印出現(xiàn)掃雷游戲的界面
//打印掃雷區(qū) void DisplayBoard(char board[ROWS][COLS], int row, int col) { int i = 0; int j = 0; printf("--------掃雷游戲--------\n"); //打印列提示數(shù) for (j = 0;j <= col;j++) { printf("%d ", j); } printf("\n"); for (i = 1;i <= row;i++) { printf("%d ", i);//打印行提示數(shù) for (j = 1;j <=col;j++) { printf("%c ", board[i][j]); } printf("\n"); } printf("---------掃雷游戲-------\n"); }
3 設(shè)置雷
這里我們用字符1來表示雷,這里我們?nèi)匀挥玫搅穗S機數(shù)生成rand與設(shè)置隨機數(shù)的種子srand
//設(shè)置雷 void SetMine(char mine[ROWS][COLS], int row, int col) { int count = EASY_COUNT; while (count) { int x = rand() % row + 1;//生成0~9之間的數(shù) int y = rand() % col + 1;//生成0~9之間的數(shù) if (mine[x][y] == '0') { mine[x][y] = '1'; count--; } } }
4 排雷
為了實現(xiàn)排雷的功能,我們在排雷過程中根據(jù)自己推斷,就知道那個位置有雷,所有我們要標記,在這里我們規(guī)定用'#'來標記,有時候在我們輸入坐標附近都是沒有雷的,為了提高游戲的體驗,我們可以把這片區(qū)域都展開。
4.1展開一片的功能
這里為了實現(xiàn)展開一片的功能,我們需要用遞歸來進行實現(xiàn)。這里我們繼續(xù)用在之前博客和大家分享的寫遞歸的思路
明確你的函數(shù)要實現(xiàn)什么功能
這里我們就是為了實現(xiàn)當x和y坐標附近周圍沒有雷的時候就用空格展示
尋找遞歸結(jié)束的條件:
1該坐標不是雷
2該坐標周圍沒有雷
3該坐標沒有被排查過
if ((show[x][y]!=' '&&mine[x][y]!='1') || (show[x][y]) == '#')
找出函數(shù)的等價條件
這里我們?yōu)榱藢ふ襵和y周圍是否有雷,我們可以用二層循環(huán)遍歷周圍是否存在遞歸結(jié)束的條件,沒有我們就繼續(xù)尋找,函數(shù)的等價為UnfoldMine(mine, show, x + i, y + j, row, col, &win)。
/展開一片沒有雷的地區(qū),用遞歸實現(xiàn) //遞歸結(jié)束的條件: //1 該坐標不是雷 //2 該坐標不是空格(防止死遞歸) void UnfoldMine(char mine[ROWS][COLS], char show[ROWS][COLS],int x,int y,int row,int col,int* win) { if ((show[x][y]!=' '&&mine[x][y]!='1') || (show[x][y]) == '#') { int count = get_mine_count(mine, x, y); if (count == 0) { show[x][y] = ' ';//無雷設(shè)置為空格 (*win)--;//無雷的位置減1 int i = 0; int j = 0; for (i = -1;i <= 1;i++) { for (j = -1;j <= 1;j++) { UnfoldMine(mine, show, x + i, y + j, row, col, &win); } } } //不符合遞歸的條件 else { show[x][y] = count + '0'; (*win)--; } } }
4.2雷標記功能的實現(xiàn)
這里我們猜出雷的位置,就可以用#標記,但我們要注意,標記的地方show[x][y]=='*'應(yīng)該要滿足這個條件。
//排雷 void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) { int x = 0; int y = 0; int m = 0;//標記的橫坐標 int n = 0;//標記的縱坐標 int sign = 0;//標記的選擇 int win = ROW*COL-EASY_COUNT;//找到不是雷的次數(shù) while (win) { do { printf("請選擇是否要標記雷:>0/1\n"); scanf("%d", &sign); switch(sign) { case 1: printf("請輸入要標記的坐標:>"); again: scanf("%d%d", &m, &n); if (show[m][n] == '*') { show[m][n] = '#';//用'#'標記雷 DisplayBoard(show, ROW, COL);//展示標記 } else { printf("該位置不需要標記,請重新選擇:>\n"); goto again; } break; case 0: break; default: printf("選擇錯誤,請重新選擇:>"); break; } } while (sign); printf("\n"); printf("請選擇要排查雷的坐標:>"); scanf("%d%d", &x, &y); if (x >= 1 && x <= row && y >= 1 && y <= col) { if ((show[x][y] != '*') && (show[x][y] != '#')) { printf("該坐標以前被排查過了,請重新選擇\n"); } else { if (mine[x][y] == '1') { printf("很遺憾,你被炸死了\n"); DisplayBoard(mine, ROW, COL);//打印雷區(qū) break; } else { UnfoldMine(mine, show, x, y, ROW,COL, &win);//注意這里要傳win的地址,讓形參和實參建立聯(lián)系 DisplayBoard(show, ROW, COL);//展示棋盤 } } } else { printf("選擇坐標違規(guī),請重新選擇:>\n"); } } if (win == 0)//判斷位置是否都找完 { printf("恭喜你,排雷成功\n"); DisplayBoard(mine, ROW, COL);//顯示埋雷的棋盤 } }
游戲過程
視頻預(yù)覽點擊掃雷游戲的過程
到此這篇關(guān)于C語言掃雷排雷小游戲?qū)崿F(xiàn)全程的文章就介紹到這了,更多相關(guān)C語言掃雷內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語言設(shè)計實現(xiàn)掃描器的自動機的示例詳解
這篇文章主要為大家詳細介紹了如何利用C語言設(shè)計實現(xiàn)掃描器的自動機,可識別的單詞包括:關(guān)鍵字、界符、標識符和常整型數(shù),感興趣的小伙伴可以了解一下2022-12-12Qt實現(xiàn)網(wǎng)絡(luò)聊天室的示例代碼
本文主要介紹了Qt實現(xiàn)網(wǎng)絡(luò)聊天室,實現(xiàn)一個在線聊天室, 使用tcp對客戶端和服務(wù)器端進行通訊。具有一定的參考價值,具有一定的參考價值,2021-06-06