本期介紹🍖
主要介紹:如何一步一步的把整個掃雷游戲的所有功能實(shí)現(xiàn),詳細(xì)的講解其中每一個功能從無到有的思考過程以及代碼上的實(shí)現(xiàn)👀。
??掃雷是一款大眾類的益智小游戲,于1992年發(fā)行。游戲目標(biāo)是在最短的時(shí)間內(nèi)根據(jù)點(diǎn)擊格子出現(xiàn)的數(shù)字找出所有非雷格子,同時(shí)避免踩雷,踩到一個雷即全盤皆輸。這款游戲的玩法是在一個9 * 9(初級),16 * 16(中級),16 * 30(高級),或自定義大小的方塊矩陣中隨機(jī)布置一定量的地雷(初級為10個,中級為40個,高級為99個)。由玩家逐個翻開方塊,以找出所有地雷為最終游戲目標(biāo)。如果玩家翻開的方塊有地雷,則游戲結(jié)束。值得注意的是:若翻開的格子下沒有地雷,則會標(biāo)記其周圍一圈格子中包含雷的個數(shù),所以若想順利通關(guān)就必須利用好這些顯示出來的數(shù)字。如下圖所示。(而我們今天要實(shí)現(xiàn)的是9×9方格的掃雷游戲,棋盤上一共放置了10個地雷)
??首先,我們要思考一下怎樣才能實(shí)現(xiàn)的和計(jì)算機(jī)里的掃雷游戲一樣呢?進(jìn)入計(jì)算機(jī)里的掃雷游戲,首先映入眼簾的是9×9的棋盤上所有的格子都被掩蓋了。然后隨機(jī)去翻開一些格子,你肯定能發(fā)現(xiàn)會出現(xiàn)幾種情況:
1.當(dāng)翻開的是“地雷”時(shí),你會被炸死游戲結(jié)束。
2.當(dāng)翻開的格子周圍一圈當(dāng)中存在“地雷”時(shí),翻開的格子下面會顯示周圍一圈格子內(nèi)存在“地雷”的個數(shù)。
3.當(dāng)翻開的格子周圍沒有“地雷”時(shí),會一下子展開一大片區(qū)域。
??然后不斷地翻開格子,直到把所有的非“地雷”的格子全部翻開后,游戲提示:掃雷成功!那我們該怎么實(shí)現(xiàn)這里雙層結(jié)構(gòu)的棋盤呢?你會發(fā)現(xiàn)雙層結(jié)構(gòu)的第一層是用來覆蓋住第二層上顯示的內(nèi)容,一個想法就油然而生了:我們是不是只要創(chuàng)建兩個二維數(shù)組,其中一個隱藏在暗處用來存放這些地雷啊、數(shù)字的信息,用戶是看不見的;另一個則是專門向用戶展示的,是擺在明面上的棋盤。(這期會實(shí)現(xiàn):可以自己標(biāo)注地雷位置的操作,還有炸金花式展開的功能)
??游戲菜單:選擇是否開始玩兒游戲,1:開始游戲,0:退出游戲。
??游戲流程:創(chuàng)建兩個格子棋盤(其中一個是隱與幕后存放地雷信息用的,另一個是向用戶展示的)→ 初始化兩個棋盤 → 隨機(jī)放置地雷 → 實(shí)現(xiàn)打印棋盤 → 開始掃雷(用戶輸入要查找的位置的坐標(biāo) → 判斷是否有雷 → 有則游戲結(jié)束,若沒有則顯示其周圍一圈中地雷的個數(shù)或者炸金花式展開一片)→ 直至掃完所有非雷區(qū) → 游戲結(jié)束。
??代碼如下:
#include"game.h"
void menu()
{printf("*****************************************\n");
printf("********* 1.play 0.exit *********\n");
printf("*****************************************\n");
}
void game()
{//存放地雷的棋盤
char mine[ROWS][COLS] = {0 };
//展示給用戶看的棋盤
char show[ROWS][COLS] = {0 };
//初始化棋盤
init_board(mine, ROWS, COLS, '0');
init_board(show, ROWS, COLS, '*');
//放置地雷
set_mine(mine, ROW, COL);
system("cls");//清空屏幕
//打印棋盤
//display_board(mine, ROW, COL);
display_board(show, ROW, COL);
//開始掃雷
find_mind(mine, show, ROW, COL);
}
int main()
{//設(shè)置隨機(jī)數(shù)的起點(diǎn)
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");
break;
}
} while (input);
return 0;
}
??注意:仔細(xì)看上面的代碼,你會我并沒有引
??相信看到這肯定有同學(xué)問:“不是說實(shí)現(xiàn)的是9×9的掃雷嗎,為什么這里是用11×11的二維數(shù)組來存放噠???”這就得夸夸那些牛逼的大佬想出來的方法了。現(xiàn)在假設(shè)我用9×9的二維數(shù)組來存放信息,當(dāng)排查某個非雷的坐標(biāo)時(shí),我們知道這時(shí)是需要將該坐標(biāo)周圍一圈坐標(biāo)逐個排查一遍的。但當(dāng)你去排查最邊界的那一圈坐標(biāo)時(shí),你會發(fā)現(xiàn)你必須得以特殊的排查法來處理這些坐標(biāo),不然你就會越界訪問。就如下圖所示:
??所以要在排查的時(shí)候不越界訪問你就必須給這最邊緣一圈的坐標(biāo)設(shè)計(jì)出專門的排查規(guī)則,這是一種解決的方法,但該方法的實(shí)現(xiàn)太過于麻煩了。所以一些大佬就思考:能不能從另一個角度以更加簡便的方法來解決這個問題呢?其中有些人就發(fā)現(xiàn),似乎只要把9×9的棋盤擴(kuò)張成11×11的棋盤,然后只拿該棋盤中間的9×9的格子用作和以前一樣的操作,問題不就迎刃而解了。這是為什么呢?因?yàn)槲也僮鲿r(shí)只會去排查中間那9行9列的格子,且就算我去排查最邊上的一圈坐標(biāo)也不會出現(xiàn)越界訪問的情況,如下圖所示。你看僅僅只需要把數(shù)組的大小改一改就能解決困擾你很久的問題,完全沒有必要在那限制這限制那的。所以有些時(shí)候不能硬想啊,一定要學(xué)會換一個角度來思考問題的解決之法?。?!
?? 該函數(shù)做到了可以任意對棋盤進(jìn)行初始化,想初始化什么就傳參傳進(jìn)來就行了。
//初始化棋盤
void init_board(char board[ROWS][COLS], int rows, int cols, char set)
{int i = 0;
for (i = 0; i< rows; i++)
{int j = 0;
for (j = 0; j< cols; j++)
{ board[i][j] = set;//set為外部傳進(jìn)來要初始化的字符
}
}
}
??該函數(shù)是通過rand()隨機(jī)數(shù)函數(shù)來設(shè)置地雷的,如果我之前有一期是專門講解了如何去創(chuàng)建隨機(jī)數(shù),如果這里感覺不是很明確,建議先了解一下隨機(jī)數(shù)再來看下去。鏈接:如何創(chuàng)建隨機(jī)數(shù)。
//設(shè)置地雷
void set_mine(char mine[ROWS][COLS], int row, int col)
{int count = COUNT;//COUNT定義在頭文件中為常量10
while (count)
{int x = rand() % 9 + 1;
int y = rand() % 9 + 1;
if (mine[x][y] == '0')
{ mine[x][y] = '1';
count--;
}
}
}
??該函數(shù)可以實(shí)時(shí)的打印出你想要的幾行幾列的棋盤,只需更改頭文件中的常量ROW和COL就行。
//打印棋盤
void display_board(char board[ROWS][COLS], int row, int col)
{printf("---------------掃雷游戲----------------\n");
int i = 0;
for (i = 0; i<= row; i++)//打印列號
{printf(" %d ", i);
}
printf("\n");
printf("\n");
for (i = 1; i<= row; i++)
{int j = 0;
printf(" %d ", j);//打印行號
//打印棋子行
for (j = 1; j<= col; j++)
{ printf(" %c ", board[i][j]);
if (j<= col - 1)
{ printf("|");
}
}
printf("\n");
//打印分隔行
if (i<= row - 1)
{ printf(" ");
for (j = 1; j<= col; j++)
{ printf("---");
if (j<= col - 1)
{printf("|");
}
}
printf("\n");
}
}
printf("---------------掃雷游戲----------------\n");
}
??演示一下效果,就如下圖所示。mine棋盤其中字符1代表設(shè)置的地雷,字符0表示該地沒有地雷,而show棋盤中字符 ‘ * ’ 表示方格還沒有被翻開,是未知的意思。
??該函數(shù)是由很多子函數(shù)嵌套調(diào)用而成,總體實(shí)現(xiàn)的功能是:先創(chuàng)建一個循環(huán),然后要求用戶輸入要排查的下標(biāo),接著判斷用戶輸入下標(biāo)是否有效,再判斷是否排查到雷。若排到地雷則直接退出循環(huán)游戲結(jié)束,否則直接進(jìn)入炸金花式展開的遞歸調(diào)用,直到排查完所有的非雷方格則游戲勝利(炸金花式展開是啥,下面會仔細(xì)說明,不要著急)。
//開始掃雷
void find_mind(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{int x = 0;
int y = 0;
int win = 0;//記錄排查出不是地雷位置的個數(shù)
char ch = 0;
while (win< row * col - COUNT)
{printf("請輸入要排查的位置下標(biāo):");
scanf("%d%d", &x, &y);
if (x >= 1 && x<= row && y >= 1 && y<= col)//判斷輸入下標(biāo)是否有效
{ if (mine[x][y] == '1')//排查到了地雷
{ break;
}
//此時(shí)沒有排查到地雷
else
{ //炸金花式展開
explode_spread(mine, show, row, col, x, y);
system("cls");
//打印棋盤
display_board(show, row, col);
printf("需要標(biāo)注地雷就輸入:Y,不需要標(biāo)注地雷則輸入:N\n");
//清空一下緩沖區(qū)
while ((ch = getchar()) != '\n');
scanf("%c", &ch);
switch (ch)
{ case 'Y':
//標(biāo)記雷的位置
sign_mine(show, row, col);
break;
default:
break;
}
}
}
else
{ printf("輸入下標(biāo)非法,請重新輸入:\n");
}
}
//把所有mine中地雷全部顯示到show上
show_all_mine(mine, show, row, col);
system("cls");
//打印棋盤
display_board(show, row, col);
//判斷是否排查成功
if (win >= row * col - COUNT)
{printf("恭喜你排查出所有的地雷?。?!\n");
}
else
{printf("掃雷失敗,你被炸死了?。?!\n");
}
}
??該函數(shù)是實(shí)現(xiàn):當(dāng)我們在排查某個位置的時(shí)候,會計(jì)算該位置周圍一圈存在地雷的個數(shù),并返回給這個值。如下圖中的數(shù)字那樣:
//計(jì)算周圍一圈范圍內(nèi)存在地雷的個數(shù)
int get_mine_count(char mine[ROWS][COLS], int x, int y)
{//把3×3方格內(nèi)所有的字符(‘1’或‘0’)加起來,
//然后再統(tǒng)一減去9個字符‘0’得到的結(jié)果就是地雷的個數(shù)
int i = 0;
int sum = 0;
for (i = x - 1; i<= x + 1; i++)
{int j = 0;
for (j = y - 1; j<= y + 1; j++)
{ sum += mine[i][j];
}
}
return (sum - 9 * '0');
}
??該函數(shù)若放到調(diào)用它的掃雷函數(shù)中去執(zhí)行,會實(shí)現(xiàn)下面這種情況:若我不小心掃到了地雷或掃雷成功時(shí)將會顯示曝光所有的地雷在用戶界面上向你展示。如下圖所示:
//把所有mine中地雷全部顯示到show上
void show_all_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{int i = 0;
for (i = 1; i<= row; i++)
{int j = 0;
for (j = 1; j<= col; j++)
{ if (mine[i][j] == '1')
{ show[i][j] = '@';//地雷用字符‘@’在用戶界面表示
}
}
}
}
??這是一個遞歸函數(shù)(對于新手來水非常難,我估計(jì)光看我寫的代碼是很難理解透徹這個函數(shù)的,所以我會逐步的來分析這個代碼),該函數(shù)實(shí)現(xiàn)的功能是:若排查的位置周圍沒有雷則向四周爆炸式展開,直至遇到周圍有地雷的坐標(biāo)時(shí)停下來。如下圖所示:
??那該怎么實(shí)現(xiàn)該遞歸函數(shù)呢?當(dāng)排查的位置沒有雷且該位置周圍沒有雷時(shí),就展開其周圍一圈的8個坐標(biāo),然后看這8個坐標(biāo)是否可以再逐個向其自身周圍接著展開,這樣一次就遞歸調(diào)用函數(shù)自身8次的展開速度就像爆炸了一樣,所以稱其為:炸金花式展開。
??如果按照這個思路去編寫代碼一定會出現(xiàn)一種情況“ 程序陷入死遞歸 ”。這個問題當(dāng)時(shí)也時(shí)困擾了我很久,代碼調(diào)試一直走不下去,直到我動手畫了張圖慢慢分析后才發(fā)現(xiàn)了問題的所在??聪聢D所示:
??基于上面的所思所想:我們認(rèn)為當(dāng)排查某個周圍沒有雷的坐標(biāo)時(shí),該坐標(biāo)會向周圍一圈展開,然后展開的這些坐標(biāo)會繼續(xù)再向外圍展開,繼而把所有周圍沒有地雷的坐標(biāo)統(tǒng)統(tǒng)排查出來??墒聦?shí)真是如此嗎?你會發(fā)現(xiàn)不管你先展開哪一個位置你都將陷入死遞歸當(dāng)中。就拿上圖所示的這個坐標(biāo)為例,當(dāng)要展開(x,y)坐標(biāo)周圍的一圈坐標(biāo)時(shí),假如其首先會從(x-1,y+1)位置開始,然后又由該坐標(biāo)向其自身周圍的一圈展開時(shí),你會發(fā)現(xiàn)坐標(biāo)(x,y)也在需要展開的范圍內(nèi)。這樣一來不就會重復(fù)要求再次展開坐標(biāo)(x,y),然后在由(x,y)要求展開(x-1,y+1),兩個坐標(biāo)在那相互瘋狂調(diào)用,你不死遞歸誰死遞歸???
??解題思路:那該怎么解決呢,說難不難當(dāng)也不簡單,要看你自己在思考的過程中能不能靈光一現(xiàn)。你看,現(xiàn)在我們完全是站在存放地雷這個棋盤(mine_board)的角度在思考解決問題的辦法。這樣必然局限了我們的思維,不妨跳出來看看,換一個角度去尋求解題之法。不知道大家有沒有發(fā)現(xiàn)我們似乎略了用戶棋盤(show_board)了呀,可不能只認(rèn)為用戶棋盤只是用來展示的,如若這兩個棋盤配合的夠好,你會發(fā)現(xiàn)此法可以完美的解決上面的難題。
??如何實(shí)現(xiàn):若每次判斷一個坐標(biāo)上沒有雷且該坐標(biāo)周圍一圈同樣沒有雷時(shí),則將向我們展示的棋盤(show_board)上表示未知的字符 ‘ * ’ 改成空格。然后在之后的遞歸調(diào)用前給一個判斷:如果這個將要被遞歸調(diào)用的坐標(biāo)在(show_board)棋盤上存放的是字符 ‘ * ’ 時(shí)才能進(jìn)行下一步,否則將直接跳過此次遞歸。如此就可以限制住坐標(biāo)在那相互瘋狂調(diào)用,因?yàn)槌绦蜻@樣設(shè)計(jì)后每個坐標(biāo)向外展開的次數(shù)就只有一次了。
??解決了上面的難題后你還會遇到一種情況,程序調(diào)試時(shí)出現(xiàn)錯誤,編譯器給的理由是:非法訪問內(nèi)存空間。其實(shí)在很多情況下會導(dǎo)致這里出現(xiàn)“ 非法訪問內(nèi)存空間” ,但該處出現(xiàn)的原因是:數(shù)組越界訪問了??隙ㄓ型瑢W(xué)會問:怎么又會越界訪問呢?上面不是已經(jīng)解決這個問題了嗎?那就只能說明你思考問題的時(shí)候太片面。上面的確解決了這個問題,但你要知道這里可是出現(xiàn)了向外擴(kuò)張的遞歸啊,你那拓展出來最外圍的一圈坐標(biāo)完全無法起到限制的作用,無法阻止炸金花式的向外展開。所以當(dāng)然會出現(xiàn)越界訪問啦?。?!
??那該怎么解決呢?其實(shí)很簡單只要能想到上面那層,就很容易得出:每次進(jìn)入遞歸函數(shù)后加一條限制不就行了。具體怎么做看下面的代碼自己領(lǐng)悟吧。
//炸金花式展開函數(shù)
void explode_spread(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int x, int y)
{//限制非法坐標(biāo)的展開
if (x >= 1 && x<= row && y >= 1 && y<= col)
{//計(jì)算該位置附近四周地雷的個數(shù)
int count = get_mine_count(mine, x, y);
//若四周沒有一個地雷,則需要向該位置的四周展開,直到展開到某個位置附近存在地雷為止
if (count == 0)
{ //把附近沒有地雷的位置變成字符 “空格”
show[x][y] = ' ';
int i = 0;
//向四周共8個位置遞歸調(diào)用
for (i = x - 1; i<= x + 1; i++)
{ int j = 0;
for (j = y - 1; j<= y + 1; j++)
{//限制對點(diǎn)位置的重復(fù)展開調(diào)用,使得每一個位置只能向四周展開一次
if (show[i][j] == '*')
{explode_spread(mine, show, row, col, i, j);
}
}
}
}
//若四周存在地雷則應(yīng)該在這個位置上標(biāo)注上地雷的個數(shù)
else
{ show[x][y] = count + '0';
}
}
}
??該功能實(shí)現(xiàn)的是在每次排查后都有一次選擇的機(jī)會,是否要標(biāo)記地雷的位置。若要則輸入**‘ Y ’** ,之后需要輸入想要標(biāo)注的坐標(biāo)位置,只有當(dāng)方格還是未知符號 ‘ * ’ 時(shí)才能用字符 ‘ !’ 作為警告標(biāo)記的;若不要則輸入 ‘ N ’ ,程序接著執(zhí)行下一步。
//標(biāo)記地雷位置(方便排查游戲中的地雷)
void sign_mine(char show[ROWS][COLS], int row, int col)
{int x = 0;
int y = 0;
while (1)
{printf("請輸入要標(biāo)記的坐標(biāo):");
scanf("%d%d", &x, &y);
if (x >= 1 && x<= row && y >= 1 && y<= col)
{ if (show[x][y] == '*')
{ show[x][y] = '!';
break;
}
else
{ printf("該位置不能被標(biāo)記,請重新輸入:\n");
}
}
else
{ printf("輸入坐標(biāo)非法,請重新輸入:\n");
}
}
system("cls");
display_board(show, row, col);
}
}
頭文件
#include#include#include#define ROW 9
#define COL 9
#define ROWS ROW + 2
#define COLS COL + 2
#define COUNT 10
void init_board(char board[ROWS][COLS], int rows, int cols, char set);
void set_mine(char mine[ROWS][COLS], int row, int col);
void display_board(char board[ROWS][COLS], int row, int col);
void find_mind(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
源文件
#include"game.h"
void menu()
{printf("*****************************************\n");
printf("********* 1.play 0.exit *********\n");
printf("*****************************************\n");
}
void game()
{//存放地雷的棋盤
char mine[ROWS][COLS] = {0 };
//展示給用戶看的棋盤
char show[ROWS][COLS] = {0 };
//初始化棋盤
init_board(mine, ROWS, COLS, '0');
init_board(show, ROWS, COLS, '*');
//放置地雷
set_mine(mine, ROW, COL);
system("cls");//清空屏幕
//打印棋盤
//display_board(mine, ROW, COL);
display_board(show, ROW, COL);
//開始掃雷
find_mind(mine, show, ROW, COL);
}
int main()
{//設(shè)置隨機(jī)數(shù)的起點(diǎn)
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");
break;
}
} while (input);
return 0;
}
源文件
#include"game.h"
//初始化棋盤
void init_board(char board[ROWS][COLS], int rows, int cols, char set)
{int i = 0;
for (i = 0; i< rows; i++)
{int j = 0;
for (j = 0; j< cols; j++)
{ board[i][j] = set;
}
}
}
//設(shè)置地雷
void set_mine(char mine[ROWS][COLS], int row, int col)
{int count = COUNT;
while (count)
{int x = rand() % 9 + 1;
int y = rand() % 9 + 1;
if (mine[x][y] == '0')
{ mine[x][y] = '1';
count--;
}
}
}
//打印棋盤
void display_board(char board[ROWS][COLS], int row, int col)
{int i = 0;
printf("---------------掃雷游戲----------------\n");
//打印列號
for (i = 0; i<= row; i++)
{printf(" %d ", i);
}
printf("\n");
printf("\n");
for (i = 1; i<= row; i++)
{int j = 0;
//打印行號
printf(" %d ", i);
//打印棋子行
for (j = 1; j<= col; j++)
{ printf(" %c ", board[i][j]);
if (j<= col - 1)
{ printf("|");
}
}
printf("\n");
//打印分隔行
if (i<= row - 1)
{ printf(" ");
for (j = 1; j<= col; j++)
{ printf("---");
if (j<= col - 1)
{printf("|");
}
}
printf("\n");
}
}
printf("---------------掃雷游戲----------------\n");
}
//計(jì)算周圍一圈范圍內(nèi)存在地雷的個數(shù)
int get_mine_count(char mine[ROWS][COLS], int x, int y)
{//把3×3方格內(nèi)所有的字符(‘1’或‘0’)加起來,然后再統(tǒng)一減去9個字符‘0’,得到的結(jié)果就是地雷的個數(shù)
int i = 0;
int sum = 0;
for (i = x - 1; i<= x + 1; i++)
{int j = 0;
for (j = y - 1; j<= y + 1; j++)
{ sum += mine[i][j];
}
}
return (sum - 9 * '0');
}
//把所有mine中地雷全部顯示到show上
void show_all_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{int i = 0;
for (i = 1; i<= row; i++)
{int j = 0;
for (j = 1; j<= col; j++)
{ if (mine[i][j] == '1')
{ show[i][j] = '@';//地雷用字符‘@’在用戶界面表示
}
}
}
}
//炸金花式展開函數(shù)
void explode_spread(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int x, int y)
{//限制非法坐標(biāo)的展開
if (x >= 1 && x<= row && y >= 1 && y<= col)
{//計(jì)算該位置附近四周地雷的個數(shù)
int count = get_mine_count(mine, x, y);
//若四周沒有一個地雷,則需要向該位置的四周展開,直到展開到某個位置附近存在地雷為止
if (count == 0)
{ //把附近沒有地雷的位置變成字符 “空格”
show[x][y] = ' ';
int i = 0;
//向四周共8個位置遞歸調(diào)用
for (i = x - 1; i<= x + 1; i++)
{ int j = 0;
for (j = y - 1; j<= y + 1; j++)
{//限制對點(diǎn)位置的重復(fù)展開調(diào)用,使得每一個位置只能向四周展開一次
if (show[i][j] == '*')
{explode_spread(mine, show, row, col, i, j);
}
}
}
}
//若四周存在地雷則應(yīng)該在這個位置上標(biāo)注上地雷的個數(shù)
else
{ show[x][y] = count + '0';
}
}
}
//標(biāo)記地雷位置(方便排查游戲中的地雷)
void sign_mine(char show[ROWS][COLS], int row, int col)
{int x = 0;
int y = 0;
while (1)
{printf("請輸入要標(biāo)記的坐標(biāo):");
scanf("%d%d", &x, &y);
if (x >= 1 && x<= row && y >= 1 && y<= col)
{ if (show[x][y] == '*')
{ show[x][y] = '!';
break;
}
else
{ printf("該位置不能被標(biāo)記,請重新輸入:\n");
}
}
else
{ printf("輸入坐標(biāo)非法,請重新輸入:\n");
}
}
system("cls");
display_board(show, row, col);
}
//開始掃雷
void find_mind(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{int x = 0;
int y = 0;
int win = 0;//記錄排查出不是地雷位置的個數(shù)
char ch = 0;
while (win< row * col - COUNT)
{printf("請輸入要排查的位置下標(biāo):");
scanf("%d%d", &x, &y);
if (x >= 1 && x<= row && y >= 1 && y<= col)//判斷輸入下標(biāo)是否有效
{ if (mine[x][y] == '1')//排查到了地雷
{ break;
}
//此時(shí)沒有排查到地雷
else
{ //炸金花式展開
explode_spread(mine, show, row, col, x, y);
system("cls");
//打印棋盤
display_board(show, row, col);
printf("需要標(biāo)注地雷就輸入:Y,不需要標(biāo)注地雷則輸入:N\n");
//清空一下緩沖區(qū)
while ((ch = getchar()) != '\n');
scanf("%c", &ch);
switch (ch)
{ case 'Y':
//標(biāo)記雷的位置
sign_mine(show, row, col);
break;
default:
break;
}
}
}
else
{ printf("輸入下標(biāo)非法,請重新輸入:\n");
}
}
//把所有mine中地雷全部顯示到show上
show_all_mine(mine, show, row, col);
system("cls");
//打印棋盤
display_board(show, row, col);
//判斷是否排查成功
if (win >= row * col - COUNT)
{printf("恭喜你排查出所有的地雷!?。n");
}
else
{printf("掃雷失敗,你被炸死了!?。n");
}
}
??這就是我今天這一期所帶來的掃雷游戲的實(shí)現(xiàn),希望多多關(guān)注我的其他博客,我想你會收獲很多你完全不了解的新知識?。?!再次感謝你的捧場。
這份博客👍如果對你有幫助,給博主一個免費(fèi)的點(diǎn)贊以示鼓勵歡迎各位🔎點(diǎn)贊👍評論收藏??,謝謝?。?!
如果有什么疑問或不同的見解,歡迎評論區(qū)留言歐👀。
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧