最近剛學(xué)完STL,心血來(lái)潮突然想做個(gè)掃雷玩玩,寫(xiě)了大半天,如有錯(cuò)誤,請(qǐng)多指正。
創(chuàng)新互聯(lián)專(zhuān)注于雞西梨樹(shù)企業(yè)網(wǎng)站建設(shè),成都響應(yīng)式網(wǎng)站建設(shè)公司,商城系統(tǒng)網(wǎng)站開(kāi)發(fā)。雞西梨樹(shù)網(wǎng)站建設(shè)公司,為雞西梨樹(shù)等地區(qū)提供建站服務(wù)。全流程按需求定制設(shè)計(jì),專(zhuān)業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,創(chuàng)新互聯(lián)專(zhuān)業(yè)和態(tài)度為您提供的服務(wù)做完這個(gè)之后,我在csdn上搜到的掃雷實(shí)現(xiàn)方法里,基本上都是在實(shí)際數(shù)組的基礎(chǔ)上向四周擴(kuò)展一圈然后使用遞歸,來(lái)保證不會(huì)出界,我的方法不大一樣,再加上是第一個(gè)正經(jīng)的cpp項(xiàng)目,故以此留念。
完整代碼在文章結(jié)尾
掃雷的實(shí)現(xiàn)思路
第一步:創(chuàng)建出一個(gè)9*9的數(shù)組來(lái)存放方塊,然后隨機(jī)生成地雷,在地雷周?chē)姆綁K正確生成數(shù)字。
第二步:用另外的9*9數(shù)組來(lái)存放方塊是否可見(jiàn),接收輸入的坐標(biāo),根據(jù)兩個(gè)數(shù)組容器來(lái)顯示地圖
第三步:判斷成功或失敗
具體的實(shí)現(xiàn)方法
vectorvbase;
vector>v; //存放地雷和數(shù)字的數(shù)組
vector>showv; //存放方塊是否可見(jiàn)的數(shù)組
int main()
{
Flag:
vbase.assign(9,0);
v.assign(9,vbase); //利用vector容器嵌套,創(chuàng)建類(lèi)似二維數(shù)組,初始化全為0
showv.assign(9,vbase);
MineRespawn(); //隨機(jī)生成地雷方塊
numberRespawn(); //給地雷周?chē)綁K賦值
while(judge()) //判斷是否踩雷
{
system("cls"); //清屏
vprint(); //畫(huà)出地圖
inputV(); //輸入坐標(biāo)并判斷
}
system("pause");
goto Flag; //重新開(kāi)始游戲
return 0;
}
理論上來(lái)說(shuō)用二維數(shù)組來(lái)表示方塊就可以了,但是為了復(fù)習(xí)STL知識(shí),“多此一舉”地使用了vector容器
void MineRespawn()
{
srand((unsigned int)time(NULL));
for(int i = 0;i< 10;i++)
{
int randomNumLenth = rand()%9; //隨機(jī)生成一個(gè)0~8的數(shù)字
int randomNumHeigh = rand()%9;
if(v[randomNumLenth][randomNumHeigh]!=9)//將地雷方塊的數(shù)字賦值為9,后面有用的
{
v[randomNumLenth][randomNumHeigh]=9;
}
else
{
i--; //如果出現(xiàn)重復(fù)的,則讓i后退一位,防止地雷數(shù)量減少
}
}
}
void numberRespawn()
{
for(int i = 0;i< 9;i++) //對(duì)所有方塊進(jìn)行遍歷
{
for(int j = 0;j< 9;j++)
{
if(v[i][j] >= 9) //地雷方塊為9,條件為>=9是因?yàn)闀?huì)出現(xiàn)地雷挨著地雷的情況
{
expand(i,j,8,8,addfunc); //下文中會(huì)講這個(gè)
}
}
}
}
首先上一部分中給地雷方塊賦值為9,是因?yàn)橐粋€(gè)普通方塊大為8(被8個(gè)地雷包圍),并且如果地雷挨著地雷,一個(gè)地雷會(huì)給另一個(gè)地雷方塊數(shù)字加1(變成10),因此判定條件為>=9
掃雷中難的部分來(lái)了,如果是地圖中間的方塊的話(huà),只需要簡(jiǎn)單地對(duì)周?chē)?個(gè)方塊加1就行了,但是還會(huì)出現(xiàn)地雷在角上,在邊上的情況。
第一種不動(dòng)腦子的解決辦法是
void numberRespawn1()
{
for(int i = 0;i< 9;i++)
{
for(int j = 0;j< 9;j++)
{
if(v[i][j] >= 9)
{
if(i == 0&&j == 0)
{
v[i+1][j] += 1;
v[i][j+1] += 1;
v[i+1][j+1] += 1;
}
else if(i == 8&&j == 8)
{
v[i-1][j] += 1;
v[i][j-1] += 1;
v[i-1][j-1] += 1;
}
else if(i == 0&&j == 8)
{
v[i+1][j] += 1;
v[i][j-1] += 1;
v[i+1][j-1] += 1;
}
else if(i == 8&&j == 0)
{
v[i-1][j] += 1;
v[i][j+1] += 1;
v[i-1][j+1] += 1;
}
else if(i == 0)
{
v[i+1][j] += 1;
v[i][j+1] += 1;
v[i][j-1] += 1;
v[i+1][j+1] += 1;
v[i+1][j-1] += 1;
}
else if(i == 8)
{
v[i-1][j] += 1;
v[i][j+1] += 1;
v[i][j-1] += 1;
v[i-1][j-1] += 1;
v[i-1][j+1] += 1;
}
else if(j == 0)
{
v[i+1][j] += 1;
v[i-1][j] += 1;
v[i][j+1] += 1;
v[i+1][j+1] += 1;
v[i-1][j+1] += 1;
}
else if(j == 8)
{
v[i+1][j] += 1;
v[i-1][j] += 1;
v[i][j-1] += 1;
v[i-1][j-1] += 1;
v[i+1][j-1] += 1;
}
else if(0< i< 8&&0< j< 8)
{
v[i+1][j] += 1;
v[i-1][j] += 1;
v[i][j+1] += 1;
v[i][j-1] += 1;
v[i+1][j+1] += 1;
v[i-1][j-1] += 1;
v[i-1][j+1] += 1;
v[i+1][j-1] += 1;
}
}
}
}
}
第二種方法:封裝成函數(shù)套函數(shù)(其實(shí)是因?yàn)楹竺嬉曇罢归_(kāi)的時(shí)候也要用到類(lèi)似的方法)
void addfunc(int x,int y){v[x][y] += 1;}
void expand(int i,int j,int lenth,int width,void (*func)(int,int))
{
for(int a = -1;a<= 1;a++)
{
for(int b = -1;b<= 1;b++)
{
if(a == 0&&b == 0){continue;} //如果是方塊本身就直接跳過(guò)
//通過(guò)遍歷所有可能并且加上坐標(biāo)條件的限制可以鎖定周?chē)乃蟹綁K并保證不會(huì)出界
//再?gòu)?qiáng)調(diào)一遍,用其他函數(shù)作為本函數(shù)參數(shù)是因?yàn)?,之后視野擴(kuò)張的時(shí)候還會(huì)再使用一次
if((0<= i + a && i + a<= lenth)&&(0<= j + b && j + b<= width)){(*func)(i+a,j+b);}
}
}
}
void numberRespawn()
{
for(int i = 0;i< 9;i++) //對(duì)所有方塊進(jìn)行遍歷
{
for(int j = 0;j< 9;j++)
{
if(v[i][j] >= 9) //地雷方塊為9,條件為>=9是因?yàn)闀?huì)出現(xiàn)地雷挨著地雷的情況
{
expand(i,j,8,8,addfunc); //函數(shù)作為其他函數(shù)的參數(shù)
}
}
}
}
expand(i,j,8,8,addfunc); 這里傳入的是addfunc函數(shù)的地址
void vprint(int authority = 0) //這里給了一個(gè)權(quán)限,如果權(quán)限是1的話(huà)直接打印整張地圖
{
cout<<" y 0 1 2 3 4 5 6 7 8 "<= 9) //數(shù)字大于9即為雷
{
cout<<"# ";
}
else if(v[i][j] == 0) //如果數(shù)字為0,打印空格
{
cout<<" ";
}
else //除此之外,方塊數(shù)字是啥打印啥
{
cout<
平平無(wú)奇的打印,未優(yōu)化
void equalfunc(int x,int y){showv[x][y] = 1;} //showv為0是不可見(jiàn),為1是可見(jiàn)
void expand(int i,int j,int lenth,int width,void (*func)(int,int))
{
for(int a = -1;a<= 1;a++)
{
for(int b = -1;b<= 1;b++)
{
if(a == 0&&b == 0){continue;}
if((0<= i + a && i + a<= lenth)&&(0<= j + b && j + b<= width)){(*func)(i+a,j+b);}
}
}
}
void inputV()
{
int num = 0;
int inputNum = 0;
cout<<"請(qǐng)輸入兩位數(shù)字,第一位為x軸,第二位為y軸"<>inputNum;
if(inputNum >88||inputNum< 0){return;}
int x = (int)(inputNum/10); //取十位數(shù)
int y = (int)(inputNum%10); //取個(gè)位數(shù)
showv[x][y] = 1;
if(v[x][y] != 0){return;}
do
{
num++;
for(int i = 0;i< 9;i++)
{
for(int j = 0;j< 9;j++)
{
if(showv[i][j] == 1&&v[i][j] == 0) //如果已經(jīng)被顯示且其值為0的話(huà)開(kāi)辟周?chē)曇? {
expand(i,j,8,8,equalfunc);
}
}
}
}while(num<=10); //這里我沒(méi)有什么好的想法判斷視野是否全部擴(kuò)展,于是偷懶了
}
inputV函數(shù)集合了輸入和視野開(kāi)辟(掃雷中的特性,如果點(diǎn)到的方塊為0,則與0相連部分的視野也會(huì)拓展)
視野開(kāi)辟與上文中的地雷周?chē)鷶?shù)字的生成有點(diǎn)類(lèi)似,但又不相同,故封裝函數(shù)。
int judge()
{
int num = 0;
for(int i = 0;i< 9;i++)
{
for(int j = 0;j< 9;j++)
{
if(showv[i][j] == 1)
{
num++;
if(v[i][j] >= 9)
{
system("cls");
vprint(1);
cout<<"失敗"<
效果如下
完整代碼如下
#includeusing namespace std;
#include
#include#include#includevectorvbase;
vector>v;
vector>showv;
void MineRespawn()
{
srand((unsigned int)time(NULL));
for(int i = 0;i< 10;i++)
{
int randomNumLenth = rand()%9;
int randomNumHeigh = rand()%9;
if(v[randomNumLenth][randomNumHeigh]!=9)
{
v[randomNumLenth][randomNumHeigh]=9;
}
else
{
i--;
}
}
}
void addfunc(int x,int y){v[x][y] += 1;}
void equalfunc(int x,int y){showv[x][y] = 1;}
void expand(int i,int j,int lenth,int width,void (*func)(int,int))
{
for(int a = -1;a<= 1;a++)
{
for(int b = -1;b<= 1;b++)
{
if(a == 0&&b == 0){continue;}
if((0<= i + a && i + a<= lenth)&&(0<= j + b && j + b<= width)){(*func)(i+a,j+b);}
}
}
}
void numberRespawn()
{
for(int i = 0;i< 9;i++)
{
for(int j = 0;j< 9;j++)
{
if(v[i][j] >= 9)
{
expand(i,j,8,8,addfunc);
}
}
}
}
void vprint(int authority = 0)
{
cout<<" y 0 1 2 3 4 5 6 7 8 "<= 9)
{
cout<<"# ";
}
else if(v[i][j] == 0)
{
cout<<" ";
}
else
{
cout<>inputNum;
if(inputNum >88||inputNum< 0){return;}
int x = (int)(inputNum/10);
int y = (int)(inputNum%10);
showv[x][y] = 1;
if(v[x][y] != 0){return;}
do
{
num++;
for(int i = 0;i< 9;i++)
{
for(int j = 0;j< 9;j++)
{
if(showv[i][j] == 1&&v[i][j] == 0) //如果已經(jīng)被顯示且其值為0的話(huà)開(kāi)辟周?chē)曇? {
expand(i,j,8,8,equalfunc);
}
}
}
}while(num<=10);
}
int judge()
{
int num = 0;
for(int i = 0;i< 9;i++)
{
for(int j = 0;j< 9;j++)
{
if(showv[i][j] == 1)
{
num++;
if(v[i][j] >= 9)
{
system("cls");
vprint(1);
cout<<"失敗"<
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧
本文名稱(chēng):C++掃雷小游戲(非遞歸實(shí)現(xiàn)版)-創(chuàng)新互聯(lián)
本文URL:http://muchs.cn/article22/dhehcc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設(shè)計(jì)、App設(shè)計(jì)、虛擬主機(jī)、手機(jī)網(wǎng)站建設(shè)、響應(yīng)式網(wǎng)站、定制網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容