最近剛學(xué)完STL,心血來潮突然想做個(gè)掃雷玩玩,寫了大半天,如有錯(cuò)誤,請(qǐng)多指正。
創(chuàng)新互聯(lián)專注于雞西梨樹企業(yè)網(wǎng)站建設(shè),成都響應(yīng)式網(wǎng)站建設(shè)公司,商城系統(tǒng)網(wǎng)站開發(fā)。雞西梨樹網(wǎng)站建設(shè)公司,為雞西梨樹等地區(qū)提供建站服務(wù)。全流程按需求定制設(shè)計(jì),專業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,創(chuàng)新互聯(lián)專業(yè)和態(tài)度為您提供的服務(wù)做完這個(gè)之后,我在csdn上搜到的掃雷實(shí)現(xiàn)方法里,基本上都是在實(shí)際數(shù)組的基礎(chǔ)上向四周擴(kuò)展一圈然后使用遞歸,來保證不會(huì)出界,我的方法不大一樣,再加上是第一個(gè)正經(jīng)的cpp項(xiàng)目,故以此留念。
完整代碼在文章結(jié)尾
掃雷的實(shí)現(xiàn)思路
第一步:創(chuàng)建出一個(gè)9*9的數(shù)組來存放方塊,然后隨機(jī)生成地雷,在地雷周圍的方塊正確生成數(shù)字。
第二步:用另外的9*9數(shù)組來存放方塊是否可見,接收輸入的坐標(biāo),根據(jù)兩個(gè)數(shù)組容器來顯示地圖
第三步:判斷成功或失敗
具體的實(shí)現(xiàn)方法
vectorvbase;
vector>v; //存放地雷和數(shù)字的數(shù)組
vector>showv; //存放方塊是否可見的數(shù)組
int main()
{
Flag:
vbase.assign(9,0);
v.assign(9,vbase); //利用vector容器嵌套,創(chuàng)建類似二維數(shù)組,初始化全為0
showv.assign(9,vbase);
MineRespawn(); //隨機(jī)生成地雷方塊
numberRespawn(); //給地雷周圍方塊賦值
while(judge()) //判斷是否踩雷
{
system("cls"); //清屏
vprint(); //畫出地圖
inputV(); //輸入坐標(biāo)并判斷
}
system("pause");
goto Flag; //重新開始游戲
return 0;
}
理論上來說用二維數(shù)組來表示方塊就可以了,但是為了復(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
掃雷中難的部分來了,如果是地圖中間的方塊的話,只需要簡單地對(duì)周圍8個(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)楹竺嬉曇罢归_的時(shí)候也要用到類似的方法)
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;} //如果是方塊本身就直接跳過
//通過遍歷所有可能并且加上坐標(biāo)條件的限制可以鎖定周圍的所有方塊并保證不會(huì)出界
//再強(qiáng)調(diào)一遍,用其他函數(shù)作為本函數(shù)參數(shù)是因?yàn)椋笠曇皵U(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的話直接打印整張地圖
{
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<
平平無奇的打印,未優(yōu)化
void equalfunc(int x,int y){showv[x][y] = 1;} //showv為0是不可見,為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 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的話開辟周圍視野
{
expand(i,j,8,8,equalfunc);
}
}
}
}while(num<=10); //這里我沒有什么好的想法判斷視野是否全部擴(kuò)展,于是偷懶了
}
inputV函數(shù)集合了輸入和視野開辟(掃雷中的特性,如果點(diǎn)到的方塊為0,則與0相連部分的視野也會(huì)拓展)
視野開辟與上文中的地雷周圍數(shù)字的生成有點(diǎn)類似,但又不相同,故封裝函數(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的話開辟周圍視野
{
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ù)器適合批量采購,新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧
本文名稱:C++掃雷小游戲(非遞歸實(shí)現(xiàn)版)-創(chuàng)新互聯(lián)
本文URL:http://www.chinadenli.net/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)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容