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