C++實(shí)現(xiàn)掃雷游戲示例講解
C/C++實(shí)現(xiàn)掃雷小游戲
源代碼:
github:https://github.com/KamSss/C-Practice/tree/master/Minesweeper掃雷小游戲/Minesweeper掃雷
總體構(gòu)造:
a.簡易的游戲菜單邏輯
b.初始化棋盤
c.布置雷的位置
d.排雷、棋盤打印、判斷輸贏(難點(diǎn))
a.簡易的游戲菜單邏輯
簡單的通過一個(gè)輸入0和1實(shí)現(xiàn)判斷是玩游戲還是退出游戲的邏輯
輸入1則進(jìn)入游戲
輸入0則break退出游戲,且退出do…while循環(huán),程序結(jié)束。
void test(){
int input = 0;
do{
menu();
cout << "請輸入:>--";
cin >> input;
switch (input)
{
case 1:
game();
break;
case 0:
cout << "退出游戲" << endl;
break;
default:
cout << " 選擇錯(cuò)誤!請重新輸入" << endl;
break;
}
} while (input);
}
b.初始化棋盤
一、越界情況的考慮
為了減少邊界情況可能出現(xiàn)越界訪問的情況,把棋盤擴(kuò)大一圈,但是在顯示的時(shí)候只顯示沒擴(kuò)大之前的棋盤。

二、棋盤打印的考慮
如果只使用一個(gè)二維數(shù)組,同時(shí)要記錄雷的位置和每一個(gè)位置附近的雷數(shù)以及點(diǎn)擊和未點(diǎn)擊的位置顯示顯然不合適。
所以: 初始化兩個(gè)棋盤,一個(gè)專門用來存放雷的位置,一個(gè)專門用于打印當(dāng)前棋盤給玩家看。
//初始化格子
InitBoard(mine, ROWS, COLS, '0');
InitBoard(show, ROWS, COLS, '*');
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
memset(&board[0][0], set, rows*cols*sizeof(board[0][0]));
}
初始化完,得到一個(gè)全0的雷盤,和一個(gè)全*的顯示盤。
c.布置雷的位置
這里用隨機(jī)數(shù)布置雷的位置,會(huì)不會(huì)對同一個(gè)點(diǎn)多次放雷呢?這里的解決辦法是,如果當(dāng)前隨機(jī)到的位置已經(jīng)有雷就再隨機(jī)一個(gè)位置防雷。
void SetMine(char board[ROWS][COLS], int row, int col)
{
srand((unsigned int)time(NULL));
int count = EASY_COUNT;
while (count)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
if (board[x][y] == '0')
{
board[x][y] = '1';
count--;
}
}
}
d.排雷、棋盤打印、判斷輸贏(難點(diǎn))d
排雷的邏輯判斷:

如果沒有雷如何打印棋盤呢?
掃雷應(yīng)該做到,“點(diǎn)擊”棋盤之后,一路“打開”到最近的出現(xiàn)雷的邊界上。
void Spread(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
int offset_x = 0;
int offset_y = 0;
int count = 0;
//坐標(biāo)合法
if (x >= 1 && x <= 9 && y >= 1 && y <= 9)
{
//遍歷周圍坐標(biāo)
for (offset_x = -1; offset_x <= 1; offset_x++)
{
for (offset_y = -1; offset_y <= 1; offset_y++)
{
//如果這個(gè)坐標(biāo)不是雷
if (mine[x + offset_x][y + offset_y] == '0')
{
//統(tǒng)計(jì)周圍雷的個(gè)數(shù)
count = GetMineCount(mine, x + offset_x, y + offset_y);
if (count == 0)
{
if (show[x + offset_x][y + offset_y] == '*')
{
show[x + offset_x][y + offset_y] = ' ';
Spread(mine, show, x + offset_x, y + offset_y);
}
}
else
{
show[x + offset_x][y + offset_y] = count + '0';
}
}
}
}
}
}
如何判斷輸贏:
很簡單,踩到雷 board[i][j] == 1
所有的雷都出現(xiàn)了 * == MineCount 就贏了
//判斷是否排雷成功
int IsWin(char show[ROWS][COLS], int row, int col)
{
int i = 0;
int j = 0;
int count = 0;
for (i = 1; i <= row; i++)
{
for (j = 1; j <= col; j++)
{
if (show[i][j] == '*')
{
count++;
}
}
}
return count == EASY_COUNT;
}
到此這篇關(guān)于C++實(shí)現(xiàn)掃雷游戲示例講解的文章就介紹到這了,更多相關(guān)C++實(shí)現(xiàn)掃雷游戲內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于SpringBoot實(shí)現(xiàn)動(dòng)態(tài)配置數(shù)據(jù)庫的加載
這篇文章主要介紹了Spring?Boot?如何動(dòng)態(tài)配置數(shù)據(jù)庫的加載,現(xiàn)項(xiàng)目有一個(gè)需求,期望通過在application.yml配置文件中設(shè)置一個(gè)開關(guān),來決定是否加載數(shù)據(jù)庫,文中通過代碼示例講解的非常詳細(xì),需要的朋友可以參考下2024-10-10
Java實(shí)現(xiàn)超市會(huì)員管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)超市會(huì)員管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
springboot+vue實(shí)現(xiàn)Token自動(dòng)續(xù)期(雙Token方案)
雙Token方案通過訪問令牌和刷新令牌提高用戶登錄安全性和體驗(yàn),訪問令牌有效期短,包含用戶信息,用于請求校驗(yàn),本文就來介紹一下springboot+vue實(shí)現(xiàn)Token自動(dòng)續(xù)期(雙Token方案),感興趣的可以了解一下2024-10-10
SWT(JFace) 圖片瀏覽器 實(shí)現(xiàn)代碼
SWT(JFace)小制作:圖片瀏覽器2009-06-06
新建springboot項(xiàng)目時(shí),entityManagerFactory報(bào)錯(cuò)的解決
這篇文章主要介紹了新建springboot項(xiàng)目時(shí),entityManagerFactory報(bào)錯(cuò)的解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01

