摘要:目錄前言前言前期的準(zhǔn)備前期的準(zhǔn)備游戲代碼的具體實(shí)現(xiàn)游戲代碼的具體實(shí)現(xiàn)完整版的掃雷小游戲代碼完整版的掃雷小游戲代碼總結(jié)總結(jié)前言掃雷是一款大眾類的益智小游戲,于年發(fā)行。
目錄
? ? ? 《掃雷》是一款大眾類的益智小游戲,于1992年發(fā)行。游戲目標(biāo)是在最短的時(shí)間內(nèi)根據(jù)點(diǎn)擊格子出現(xiàn)的數(shù)字找出所有非雷格子,同時(shí)避免踩雷,踩到一個(gè)雷即全盤皆輸。
? ? ? 而現(xiàn)在,學(xué)習(xí)了已有的知識(shí)后,我們不僅有能力自己用代碼寫出簡(jiǎn)單的三字棋小游戲,還可以寫一些稍稍簡(jiǎn)單的掃雷了。怎么樣,雖然比不上用鼠標(biāo)稍稍點(diǎn)擊就可以判斷的發(fā)行版本,但是也可以是使自己感到滿足了。好了,話不多說,讓我們一起去了解掃雷的代碼實(shí)現(xiàn)吧!(本篇博客和上一篇三字棋博客的大致方向是差不多的,如果大家先看一看上一篇博客的話效果會(huì)跟好哦)。
和上一篇博客一樣,同樣需要模塊化的思想,將其分成3個(gè)模塊:text.c,game.c,game.h。
text.c:游戲的測(cè)試邏輯(主函數(shù);游戲的邏輯實(shí)現(xiàn))
game.c:游戲的實(shí)現(xiàn)邏輯(各種所需要的函數(shù)的實(shí)現(xiàn))
game.h:游戲?qū)崿F(xiàn)函數(shù)的聲明;行號(hào)、列號(hào)的聲明;頭文件的包含
游戲的思路:
1.使用do...while循環(huán),讓游戲至少執(zhí)行一次,打印出菜單模塊,設(shè)計(jì)菜單函數(shù);玩家進(jìn)入游戲后,可以根據(jù)自己的選擇決定是否來(lái)玩游戲。提示用戶輸入,根據(jù)輸入值來(lái)確定后續(xù)的游戲進(jìn)程(1代表玩游戲,0代表退出,其他需要重新選擇)。
2.熟練的使用數(shù)組和函數(shù)。若只創(chuàng)建一個(gè)棋盤,把雷放上去之后,玩家就可以直接看見,沒有任何的可玩性,所以我們需要兩個(gè)棋盤。一個(gè)用來(lái)我們內(nèi)部實(shí)現(xiàn)的,存放一些雷,而另一個(gè)則是給玩家看的。
3創(chuàng)建完以后呢,就可以放置一些雷在內(nèi)部數(shù)組中。
4.最后,完成坐標(biāo)的輸入;對(duì)雷的排查,每排查一個(gè)雷所展現(xiàn)在玩家眼前不同的棋盤,以及踩到雷或是掃雷成功的提示和算法實(shí)現(xiàn)。
主函數(shù):
int main(){ test(); return 0;}
test()函數(shù)的具體實(shí)現(xiàn):?
void test(){ int input = 0; srand((unsigned int)time(NULL)); do { menu(); printf("請(qǐng)選擇:>"); scanf("%d", &input); switch(input) { case 1: game(); break; case 0: printf("退出游戲/n"); break; default: printf("選擇錯(cuò)誤,請(qǐng)重新選擇/n"); } } while (input);}
菜單界面(可調(diào)于test函數(shù)):
void menu(){ printf("***********************/n"); printf("***** 1. play ****/n"); printf("***** 0. exit ****/n"); printf("***********************/n");}
游戲函數(shù):
void game(){ //創(chuàng)建布置雷的信息的數(shù)組(內(nèi)部,不給玩家看) char mine[ROWS][COLS] = { 0 }; //創(chuàng)建排查雷的信息的數(shù)組(外部,給玩家看的) char show[ROWS][COLS] = { 0 }; //初始化棋盤 InitBoard(mine, ROWS, COLS, "0");//把內(nèi)部全部初始化為0 InitBoard(show, ROWS, COLS, "*");//把外部全部初始化為* //DisplayBoard(mine, ROW, COL);(打印這個(gè)棋盤可以自己調(diào)試用,但不給玩家看) //DisplayBoard(show, ROW, COL); //布置雷 SetMine(mine, ROW, COL); //打印棋盤(想要打印中間的9*9的棋盤,但傳過去的是11*11的整個(gè)數(shù)組) DisplayBoard(show, ROW, COL); //排查雷 FineMine(mine, show, ROW, COL);}
//頭文件的包含#include
#include #include //符號(hào)的聲明#define ROW 9#define COL 9#define ROWS ROW+2#define COLS COL+2#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);
這個(gè)是整個(gè)游戲的最重要的一步(各個(gè)函數(shù)的作用在上面的游戲函數(shù)寫了,我就直接上代碼了)。
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; } }} void DisplayBoard(char board[ROWS][COLS], int row, int col){ int i = 0; int j = 0; //打印列號(hào),因?yàn)橹按蛴×藗€(gè)行號(hào),所以讓第一列是0,但得多打印一行, //所以前面i=0,后面i<=row for (i = 0; i <= row; i++) { printf("%d ", i); } printf("/n"); for (i = 1; i <= row; i++) { //打印行號(hào) printf("%d ", i); //打印棋盤 for (j = 1; j <= col; j++) { printf("%c ", board[i][j]); } printf("/n"); }} void SetMine(char mine[ROWS][COLS], int row, int col){ int count = EASY_COUNT; while (count) { int x = rand() % row + 1; int y = rand() % col + 1; if (mine[x][y] == "0") { mine[x][y] = "1"; count--; } }} static int get_mine_count(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] - 8 * "0";} void open_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y){ int count = get_mine_count(mine, x, y); if (count == 0) { show[x][y] = " "; if (show[x - 1][y - 1] == "*") open_mine(mine, show, x - 1, y - 1); if (show[x - 1][y] == "*") open_mine(mine, show, x - 1, y); if (show[x - 1][y + 1] == "*") open_mine(mine, show, x - 1, y + 1); if (show[x][y - 1] == "*") open_mine(mine, show, x, y - 1); if (show[x][y + 1] == "*") open_mine(mine, show, x, y + 1); if (show[x + 1][y - 1] == "*") open_mine(mine, show, x + 1, y - 1); if (show[x + 1][y] == "*") open_mine(mine, show, x + 1, y); if (show[x + 1][y + 1] == "*") open_mine(mine, show, x + 1, y + 1); } else show[x][y] = get_mine_count(mine, x, y) + "0";} void FineMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col){ int x = 0; int y = 0; int win = 0; while (win < row * col - EASY_COUNT) { printf("請(qǐng)輸入要排查雷的坐標(biāo):>"); scanf("%d %d",&x, &y); //判斷坐標(biāo)是否合法 if (x >= 1 && x <= row && y >= 1 && y <= col) { //踩雷 if (mine[x][y] == "1") { printf("很遺憾,你被炸死了/n"); DisplayBoard(mine, row, col); break; } //未踩雷 else { //int count = get_mine_count(mine, x, y); //show[x][y] = count + "0";//使用遞歸后不需要這兩個(gè)了,在open_mine中實(shí)現(xiàn)了這 //些功能 open_mine(mine, show, x, y);//如果輸入坐標(biāo)附近無(wú)雷,則向四周展開直到遇到雷 DisplayBoard(show, ROW, COL);//每次排雷后再次打印棋盤 win++; } } else { printf("坐標(biāo)非法,請(qǐng)重新輸入/n"); } } if (win == row * col - EASY_COUNT) { printf("恭喜你,排雷成功/n"); DisplayBoard(mine, row, col); }}
上面使用遞歸實(shí)現(xiàn)的,如果不想實(shí)現(xiàn)展開的話,可以這樣做(刪除open_mine,并且解除上面注釋的內(nèi)容)
//open_mine函數(shù)刪除全部?jī)?nèi)容void open_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y) void FineMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col){ int x = 0; int y = 0; int win = 0; while (win < row * col - EASY_COUNT) { printf("請(qǐng)輸入要排查雷的坐標(biāo):>"); scanf("%d %d",&x, &y); //判斷坐標(biāo)是否合法 if (x >= 1 && x <= row && y >= 1 && y <= col) { //踩雷 if (mine[x][y] == "1") { printf("很遺憾,你被炸死了/n"); DisplayBoard(mine, row, col); break; } //未踩雷 else { int count = get_mine_count(mine, x, y); show[x][y] = count + "0"; //使用上面這兩個(gè) //open_mine(mine, show, x, y);//刪除該函數(shù) DisplayBoard(show, ROW, COL);//每次排雷后再次打印棋盤 win++; } } else { printf("坐標(biāo)非法,請(qǐng)重新輸入/n"); } } if (win == row * col - EASY_COUNT) { printf("恭喜你,排雷成功/n"); DisplayBoard(mine, row, col); }}
//頭文件的包含#include
#include #include //符號(hào)的聲明#define ROW 9#define COL 9#define ROWS ROW+2#define COLS COL+2#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);
#include "game.h"void menu(){ printf("***********************/n"); printf("***** 1. play ****/n"); printf("***** 0. exit ****/n"); printf("***********************/n");}void game(){ //創(chuàng)建布置雷的信息的數(shù)組(內(nèi)部,不給玩家看) char mine[ROWS][COLS] = { 0 }; //創(chuàng)建排查雷的信息的數(shù)組(外部,給玩家看的) char show[ROWS][COLS] = { 0 }; //初始化棋盤 InitBoard(mine, ROWS, COLS, "0");//把內(nèi)部全部初始化為0 InitBoard(show, ROWS, COLS, "*");//把外部全部初始化為* //DisplayBoard(mine, ROW, COL);(打印這個(gè)棋盤可以自己調(diào)試用,但不給玩家看) //DisplayBoard(show, ROW, COL); //布置雷 SetMine(mine, ROW, COL); //打印棋盤(想要打印中間的9*9的棋盤,但傳過去的是11*11的整個(gè)數(shù)組) DisplayBoard(show, ROW, COL); //排查雷 FineMine(mine, show, ROW, COL);}void test(){ int input = 0; srand((unsigned int)time(NULL)); do { menu(); printf("請(qǐng)選擇:>"); scanf("%d", &input); switch(input) { case 1: game(); break; case 0: printf("退出游戲/n"); break; default: printf("選擇錯(cuò)誤,請(qǐng)重新選擇/n"); } } while (input);}int main(){ test(); return 0;}
#include "game.h" 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; } }} void DisplayBoard(char board[ROWS][COLS], int row, int col){ int i = 0; int j = 0; //打印列號(hào),因?yàn)樵谥按蛴×藗€(gè)行號(hào),所以讓第一列是0,但得多打印一行, //所以前面i=0,后面i<=row for (i = 0; i <= row; i++) { printf("%d ", i); } printf("/n"); for (i = 1; i <= row; i++) { //打印行號(hào) printf("%d ", i); //打印棋盤 for (j = 1; j <= col; j++) { printf("%c ", board[i][j]); } printf("/n"); }} void SetMine(char mine[ROWS][COLS], int row, int col){ int count = EASY_COUNT; while (count) { int x = rand() % row + 1; int y = rand() % col + 1; if (mine[x][y] == "0") { mine[x][y] = "1"; count--; } }} static int get_mine_count(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] - 8 * "0";} void open_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y){ int count = get_mine_count(mine, x, y); if (count == 0) { show[x][y] = " "; if (show[x - 1][y - 1] == "*") open_mine(mine, show, x - 1, y - 1); if (show[x - 1][y] == "*") open_mine(mine, show, x - 1, y); if (show[x - 1][y + 1] == "*") open_mine(mine, show, x - 1, y + 1); if (show[x][y - 1] == "*") open_mine(mine, show, x, y - 1); if (show[x][y + 1] == "*") open_mine(mine, show, x, y + 1); if (show[x + 1][y - 1] == "*") open_mine(mine, show, x + 1, y - 1); if (show[x + 1][y] == "*") open_mine(mine, show, x + 1, y); if (show[x + 1][y + 1] == "*") open_mine(mine, show, x + 1, y + 1); } else show[x][y] = get_mine_count(mine, x, y) + "0";} void FineMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col){ int x = 0; int y = 0; int win = 0; while (win < row * col - EASY_COUNT) { printf("請(qǐng)輸入要排查雷的坐標(biāo):>"); scanf("%d %d",&x, &y); //判斷坐標(biāo)是否合法 if (x >= 1 && x <= row && y >= 1 && y <= col) { //踩雷 if (mine[x][y] == "1") { printf("很遺憾,你被炸死了/n"); DisplayBoard(mine, row, col); break; } //未踩雷 else { open_mine(mine, show, x, y);//如果輸入坐標(biāo)附近無(wú)雷,則向四周展開直到遇到雷 DisplayBoard(show, ROW, COL);//每次排雷后再次打印棋盤 win++; } } else { printf("坐標(biāo)非法,請(qǐng)重新輸入/n"); } } if (win == row * col - EASY_COUNT) { printf("恭喜你,排雷成功/n"); DisplayBoard(mine, row, col); }}
?本次博客到這里就接近尾聲了,有啥不足的地方,歡迎提出來(lái)一起共同進(jìn)步哦!如果喜歡這篇博客的話,歡迎鐵汁們動(dòng)動(dòng)你們的小手,一鍵三連哦!
?
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/123504.html
摘要:通過二維數(shù)組的學(xué)習(xí)以及之前學(xué)的一些知識(shí),實(shí)現(xiàn)初階掃雷小游戲。整體思路菜單一把不夠,再來(lái)一把利用二維數(shù)組創(chuàng)建兩個(gè)的棋盤,那為什么不是呢,下面代碼有解釋。中進(jìn)行函數(shù)調(diào)用和部分函數(shù)實(shí)現(xiàn)。 通過二維數(shù)組的學(xué)習(xí)以及之前學(xué)的一些知識(shí),實(shí)現(xiàn)初階掃雷(9×9)小游戲。 ? ? ? ? ? ? ? ? ? ?...
摘要:玩家選擇開始游戲后,出現(xiàn)雷盤,并且隨機(jī)布置雷。雷盤的數(shù)組大小為,方便計(jì)算掃雷時(shí)周圍雷的數(shù)量,并防止數(shù)組越界。放置布置的雷的信息放置排查出雷的信息初始化雷盤初始化展示界面打印展示界面效果如下布置雷隨機(jī)在數(shù)組中讓十個(gè)變成作為雷。 目錄 前言 一、游戲思路 二、游戲框架 1.菜單界面 1.菜單:...
摘要:也可以理解成二維數(shù)組有三個(gè)元素,每個(gè)元素是一個(gè)一維數(shù)組我們可以把二維數(shù)組想象成一個(gè)幾行幾列的數(shù)組但是本質(zhì)上的二維數(shù)組是一列的。數(shù)組名,計(jì)算整個(gè)數(shù)組的大小,內(nèi)部單獨(dú)放一個(gè)數(shù)組名,數(shù)組名表示整個(gè)數(shù)組。數(shù)組名,數(shù)組名表示整個(gè)數(shù)組。 目錄 1. 一維數(shù)組 1.1?數(shù)組的創(chuàng)建和初始化 數(shù)組的創(chuàng)建: 數(shù)...
摘要:作者時(shí)間網(wǎng)站地址摘要語(yǔ)言實(shí)現(xiàn)我們小時(shí)候玩過的掃雷游戲,最近看到了一些掃雷游戲的簡(jiǎn)單實(shí)現(xiàn),但是總有功能上的缺失,玩起來(lái)不那么的原汁原味,因此我增加了一些新功能確保玩家首次排雷一定不會(huì)炸死。 ...
摘要:頭文件部分進(jìn)行符號(hào)常量的聲明,宏定義等源文件和用時(shí)需要引用。包括布置雷區(qū),埋雷,掃雷,判斷輸贏等。游戲規(guī)則掃雷就是要把所有非地雷的格子揭開即勝利踩到地雷格子就算失敗。一次就可以完成兩次函數(shù)調(diào)用的實(shí)現(xiàn)。這是因?yàn)榉乐乖趻呃椎臅r(shí)候數(shù)組越界。 ...
閱讀 1222·2021-11-24 10:27
閱讀 3520·2021-11-18 10:02
閱讀 2568·2021-11-16 11:45
閱讀 3314·2021-11-15 18:10
閱讀 1001·2021-09-22 15:23
閱讀 1690·2019-08-30 15:53
閱讀 3185·2019-08-30 13:20
閱讀 1833·2019-08-30 12:53