摘要:函數(shù)游戲菜單請(qǐng)選擇掃雷游戲退出游戲選擇錯(cuò)誤解析函數(shù)內(nèi)部利用時(shí)間戳,形成隨機(jī)數(shù),主要目的是實(shí)現(xiàn)游戲中地雷的隨機(jī)埋放。
本篇文章使用C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單小游戲---掃雷。(文章最后有完整代碼鏈接)
想必大多數(shù)人都玩過(guò)或者了解過(guò)掃雷的游戲規(guī)則,但是在這里,我們?cè)谝黄鹬販匾幌聮呃椎挠螒蛞?guī)則,也更好的讓我們了解程序的實(shí)現(xiàn)目的。
掃雷:掃雷就是要把所有非地雷的格子揭開(kāi)即勝利;踩到地雷格子就算失敗。游戲主區(qū)域由很多個(gè)方格組成。使用鼠標(biāo)左鍵隨機(jī)點(diǎn)擊一個(gè)方格,方格即被打開(kāi)并顯示出方格中的數(shù)字;方格中數(shù)字則表示其周?chē)?個(gè)方格隱藏了幾顆雷。
在了解游戲規(guī)則后,我們就用C語(yǔ)言來(lái)實(shí)現(xiàn)這個(gè)簡(jiǎn)單小游戲。
這是我們解決資源管理器內(nèi)所創(chuàng)建的文件,下來(lái)我們就進(jìn)入代碼內(nèi)部。
一,游戲使用到的頭文件和游戲聲明
#include #include #include
#define ROW 9#define COL 9#define ROWS ROW+2#define COLS COL+2#define EASY_COUNT 10
初始化棋盤(pán)
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);
二,游戲測(cè)試
和三子棋一樣,主函數(shù)仍然簡(jiǎn)單,函數(shù)內(nèi)部調(diào)用test()測(cè)試函數(shù)。
int main(){?? ?test();?? ?return 0;}
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ò)誤/n"); break; } } while (input);}
解析test()函數(shù)內(nèi)部:
利用時(shí)間戳,形成隨機(jī)數(shù),主要目的是實(shí)現(xiàn)游戲中地雷的隨機(jī)埋放。
void menu()// 游戲菜單{ printf("********************/n"); printf("**** 1. play *****/n"); printf("**** 0. exit *****/n"); printf("********************/n");}
創(chuàng)建菜單,實(shí)現(xiàn)效果演示:
使用此語(yǔ)句實(shí)現(xiàn)玩家的自主選擇,當(dāng)輸入1時(shí)進(jìn)行掃雷游戲,當(dāng)輸入0時(shí),退出游戲。顯示效果如下:
? ? ?
game()函數(shù)是主要游戲?qū)崿F(xiàn)函數(shù),以下是game函數(shù)主要是實(shí)現(xiàn)邏輯圖和實(shí)現(xiàn)順序
?這里先讓大家看一下完整代碼,實(shí)現(xiàn)順序如上所示:
下面主要進(jìn)入我們的游戲?qū)崿F(xiàn)邏輯當(dāng)中......劃重點(diǎn)
三,游戲?qū)崿F(xiàn)
// 創(chuàng)建數(shù)組 // 創(chuàng)建雷的數(shù)組(mine) 顯示的數(shù)組(show) 兩個(gè)數(shù)組一樣規(guī)模 一樣類(lèi)型 char mine[ROWS][COLS] = { 0 }; // 存放布置好的雷的信息 char show[ROWS][COLS] = { 0 }; // 存放排查出的雷的信息
在這里我們需要?jiǎng)?chuàng)建2個(gè)相同大小,相同類(lèi)型的二維數(shù)組。
問(wèn):我們?yōu)槭裁匆獎(jiǎng)?chuàng)建2個(gè)相同的數(shù)組呢?
答:是因?yàn)槲覀冊(cè)谕鎾呃椎臅r(shí)候我們首先看到的是一個(gè)未知得棋盤(pán),不知道哪里埋放著雷,如果我們觸碰到雷結(jié)束游戲后,我們需要給玩家呈現(xiàn)這局游戲所有點(diǎn)位的情況,這樣以便于玩家清楚所有雷都在那里,為什么死,因此我們需要兩個(gè)棋盤(pán)才能完成這項(xiàng)任務(wù)。
在這里我們創(chuàng)建了11X11大小的棋盤(pán),但是只顯示9X9大小的棋盤(pán)也就是81個(gè)格子,打算埋放10顆雷,玩家可以在頭文件自行更改雷的個(gè)數(shù)。
問(wèn):我們顯示9X9大小的棋盤(pán),為什么創(chuàng)建11X11大小的棋盤(pán)?
答:這是因?yàn)閽呃子螒蛞?guī)則中,我們?cè)谂爬椎倪^(guò)程中,會(huì)顯示周?chē)?個(gè)格子的雷的個(gè)數(shù),如果創(chuàng)建一個(gè)9X9的格子,那當(dāng)我們?cè)谶吔堑臅r(shí)候,我們周?chē)母褡硬粔?個(gè),但是我們還要訪問(wèn)周?chē)?個(gè)格子,這時(shí)候我們必然會(huì)造成數(shù)組越界問(wèn)題,具體情況如下圖所示,這時(shí)候我們?nèi)绻麆?chuàng)建11X11的棋盤(pán),對(duì)11X11的棋盤(pán)都初始化為字符" 0 ", 我們只顯示內(nèi)部的9X9的格子,我們依然不會(huì)影響游戲,并且也解決了數(shù)組越界的問(wèn)題。
如圖所示,我們假設(shè)要查找坐標(biāo)為(9,9)格子周?chē)?個(gè)格子的雷的個(gè)數(shù),如果我們還只是9X9的格子,我們圖中的紅色陰影區(qū)域就處于數(shù)組的范圍之外,因?yàn)槲覀冃枰獎(jiǎng)?chuàng)建11X11的棋盤(pán),就可以輕松化解這個(gè)問(wèn)題。
// 初始化mine數(shù)組為全"0" InitBoard(mine,ROWS,COLS,"0");//初始化--->棋盤(pán)函數(shù) // 初始化show數(shù)組為全"*" InitBoard(show,ROWS,COLS,"*");//初始化--->棋盤(pán)函數(shù)
和三子棋一樣,我們依然自定義函數(shù)InitBoard(),具體代碼如下:
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set){ int i = 0, j = 0; for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) { board[i][j] = set; } }}
在這里我們對(duì)第一塊mine棋盤(pán)全部初始化為字符 " 0 "?(注意這里是字符0,不是數(shù)字0),我們對(duì)第二塊show棋盤(pán)全部初始化為字符" * " ,最終玩家首先會(huì)看到一幅全是字符" * "的棋盤(pán),這樣也符合游戲規(guī)則。
自定義函數(shù)DisplayBoard(),具體代碼如下:
void DisplayBoard(char board[ROWS][COLS], int row, int col){ int i = 0, j = 0; //列號(hào)的打印 for (i = 0; i <= col; i++) { printf("%d ", i); } printf("/n"); for (i = 1; i <= row; i++) { printf("%d ", i);//打印行號(hào) for (j = 1; j <= col; j++) { printf("%c ", board[i][j]); } printf("/n"); }}
這樣通過(guò)調(diào)用DisplayBoard()函數(shù)我們可以檢查一下,我們剛才所創(chuàng)建和初始化的棋盤(pán)是否符合我們的要求,我們打印棋盤(pán)演示如下:
?我們發(fā)現(xiàn),打印出來(lái)的棋盤(pán)也完全符合我們的要求,我們也只需要最終將show棋盤(pán)顯示給玩家即可。
在這里我們自定義函數(shù)SetMine()函數(shù),具體代碼如下:
// 布置雷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--; } }}
我們對(duì)此代碼進(jìn)行分析:
A:如何實(shí)現(xiàn)隨機(jī)布雷?
答:我們創(chuàng)建rand函數(shù),利用時(shí)間戳生成隨機(jī)數(shù),因?yàn)槲覀兯鶆?chuàng)建的棋盤(pán)大小是9X9大小,我們我們只需要給生成的隨機(jī)數(shù)模上row(col)即可得到0~row-1 ,因此我們?cè)?+1?即可得到一個(gè)在0~row(col)的隨機(jī)數(shù),從而實(shí)現(xiàn)隨機(jī)布雷。
我們?cè)O(shè)定count個(gè)雷,如果我們埋下一顆雷,我們就count-1,同時(shí)我們將初始化的字符" 0 " 變成字符" 1 " , 只有我們識(shí)別到目標(biāo)格子是字符 " 0 " 時(shí)才會(huì)埋雷,這也解決了在同一位置重復(fù)埋雷的問(wèn)題。?
假設(shè)我們隨機(jī)埋下10顆雷,演示一下棋盤(pán):
?我們發(fā)現(xiàn),我們隨機(jī)埋下了10顆雷,并且也改成了字符" 1 "
自定義函數(shù)FindMine(),具體代碼如下所示:
// 排查雷void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col){ int x = 0, y = 0; int win = 0; while (win"); 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 { //計(jì)算x,y坐標(biāo)周?chē)袔讉€(gè)雷 int n = get_mine_count(mine,x,y); show[x][y] = n+"0"; // 數(shù)字+"0"可以轉(zhuǎn)換成對(duì)應(yīng)的ASCII DisplayBoard(show, row, col); win++; } } else { printf("輸入坐標(biāo)非法,無(wú)法排雷,請(qǐng)重新輸入/n"); } } if (win == row * col - EASY_COUNT) { printf("恭喜你,排雷成功/n"); DisplayBoard(mine, row,col); }}
其中調(diào)用了get_mine_count函數(shù),其代碼如下:
static int get_mine_count(char mine[ROWS][COLS],int x,int y){ return mine[x - 1][y] + mine[x - 1][y - 1] + mine[x][y - 1] + mine[x + 1][y - 1] + mine[x + 1][y] + mine[x + 1][y + 1] + mine[x][y + 1] + mine[x - 1][y + 1] - 8 * "0";}
接下來(lái)對(duì)這兩段代碼進(jìn)行分析:
當(dāng)我們輸入需要排查的坐標(biāo)的時(shí)候,我們所輸入的坐標(biāo)也必須合法,必須在1~row(col)之間的數(shù)字,如果在此之外,我們將會(huì)提醒玩家“輸入坐標(biāo)非法,無(wú)法排雷,請(qǐng)重新輸入”字樣。
當(dāng)我們輸入正確的坐標(biāo)時(shí)候,我們需要對(duì)這個(gè)坐標(biāo)下所對(duì)應(yīng)的字符進(jìn)行判斷,如果是字符" 1 " ,說(shuō)明踩中雷,說(shuō)明游戲結(jié)束,這時(shí)候我們將完整棋盤(pán)打印出來(lái),玩家也可以了解本局游戲的情況。
如果是字符 " 0 " ,說(shuō)明玩家沒(méi)有踩中雷,根據(jù)游戲規(guī),我們需要顯示這個(gè)格子周?chē)?個(gè)格子中存在雷的個(gè)數(shù),這時(shí)候我們調(diào)用了get_mine_count函數(shù),我們先看一下統(tǒng)計(jì)周?chē)椎膫€(gè)數(shù)的代碼:
return mine[x - 1][y] + mine[x - 1][y - 1] + mine[x][y - 1] + mine[x + 1][y - 1] + mine[x + 1][y] + mine[x + 1][y + 1] + mine[x][y + 1] + mine[x - 1][y + 1] - 8 * "0";
我們發(fā)現(xiàn),此代碼將周?chē)?個(gè)格子的字符全部加了起來(lái),我們知道如果是字符 " 0 " 和字符 " 1 "所對(duì)應(yīng)的ASCII碼值相差1,我們可以通過(guò)ASCII碼值來(lái)進(jìn)行判斷,我們將周?chē)?個(gè)字符相加,然后再減去8個(gè)字符" 0 " 的和,這樣,我們就可以得到周?chē)?個(gè)格子中有多少個(gè)字符 " 1 " 的格子,也就是雷的個(gè)數(shù)。
為了方便大家理解,我們假定有10個(gè)雷,我們將Mine棋盤(pán)和show棋盤(pán)都顯示,我們根據(jù)棋盤(pán)制定輸入,看是否可以得到我們想要的結(jié)果:
如果我們排除萬(wàn)難,最終將81個(gè)格子排完,我們將會(huì)獲得勝利,具體判斷代碼如下:
if (win == row * col - EASY_COUNT) { printf("恭喜你,排雷成功/n"); DisplayBoard(mine, row,col); }
我們這里假定有80個(gè)雷,我們顯示一下:
?至此,我們掃雷小游戲也寫(xiě)完了,完整代碼我也放在我的Gitee倉(cāng)庫(kù),鏈接如下:
C語(yǔ)言: C語(yǔ)言代碼學(xué)習(xí)-練習(xí) - Gitee.com
其中這3個(gè)對(duì)應(yīng)資源管理器3個(gè)文件
本節(jié)內(nèi)容主要用C語(yǔ)言實(shí)現(xiàn)了小游戲---> 掃雷,大家可以拷貝到編譯器里面玩一玩,如果大家覺(jué)得還不錯(cuò)有收獲的話,點(diǎn)贊收藏走一波唄~?
由于我的個(gè)人技術(shù)水平有限,各位大佬發(fā)現(xiàn)錯(cuò)誤及時(shí)指出哦~
這里是 用C語(yǔ)言實(shí)現(xiàn)《三子棋?》 小游戲的鏈接,大家有興趣也可以看看哦:
[ C語(yǔ)言 ] 用C語(yǔ)言實(shí)現(xiàn)小游戲 ---- 三子棋 代碼 + 解析_小白又菜的博客-CSDN博客
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/123367.html
摘要:頭文件部分進(jìn)行符號(hào)常量的聲明,宏定義等源文件和用時(shí)需要引用。包括布置雷區(qū),埋雷,掃雷,判斷輸贏等。游戲規(guī)則掃雷就是要把所有非地雷的格子揭開(kāi)即勝利踩到地雷格子就算失敗。一次就可以完成兩次函數(shù)調(diào)用的實(shí)現(xiàn)。這是因?yàn)榉乐乖趻呃椎臅r(shí)候數(shù)組越界。 ...
摘要:上一期咱們用語(yǔ)言實(shí)現(xiàn)了三子棋的小游戲語(yǔ)言實(shí)現(xiàn)三子棋今天我們?cè)賮?lái)寫(xiě)個(gè)掃雷的游戲,說(shuō)起掃雷,相信大家都不陌生,可能許多朋友還是玩掃雷的高手。 ? ? ?上一期咱們用C語(yǔ)言實(shí)現(xiàn)了三子棋的小游戲? C語(yǔ)言實(shí)現(xiàn)三子棋? ? ? ?今天我們?cè)賮?lái)寫(xiě)個(gè)掃雷的游戲,說(shuō)起掃雷,相信大家都不陌生,可能許多朋友還是...
摘要:目錄前言前言前期的準(zhǔn)備前期的準(zhǔn)備游戲代碼的具體實(shí)現(xiàn)游戲代碼的具體實(shí)現(xiàn)完整版的掃雷小游戲代碼完整版的掃雷小游戲代碼總結(jié)總結(jié)前言掃雷是一款大眾類(lèi)的益智小游戲,于年發(fā)行。 目錄 前言 前期的準(zhǔn)備 游戲代碼的具體實(shí)現(xiàn) 1、text.c 2、game.h 3、game.c 完整版的掃雷小游戲代碼: 1...
摘要:展示雷盤(pán)和初始化雷盤(pán)不一樣,展示雷盤(pán)只需要用即可,并不需要將都展示出來(lái),只是為了我們更好的計(jì)算掃雷的位置周?chē)睦椎臄?shù)量。 目錄 1、需求分析 2、程序架構(gòu) 3、代碼實(shí)現(xiàn)(分函數(shù)呈現(xiàn)) (1)主函數(shù)代碼實(shí)現(xiàn) 分析: 異常處理: (2)游戲主函數(shù)實(shí)現(xiàn) 分析: (3)初始化函數(shù)的實(shí)現(xiàn) 分析: (4...
摘要:新人小白的第一篇博客,有什么不好之處望多提意見(jiàn)。這個(gè)掃雷小游戲主要是基于二維數(shù)組,循環(huán)與基本的函數(shù)知識(shí)等。請(qǐng)輸入坐標(biāo)提示玩家輸入坐標(biāo)。換行是為了看著好看,要不然打印出來(lái)的數(shù)組會(huì)變形的。用來(lái)接收判斷輸贏的函數(shù)的返回值。 ???????新人小白的第一篇博客,有什么不好之處望多提意見(jiàn)。 ? ? ?...
閱讀 3606·2021-11-15 11:38
閱讀 2801·2021-11-11 16:55
閱讀 2550·2021-11-08 13:22
閱讀 2627·2021-11-02 14:45
閱讀 1303·2021-09-28 09:35
閱讀 2567·2021-09-10 10:50
閱讀 463·2019-08-30 15:44
閱讀 2775·2019-08-29 17:06