C++掃雷小游戲(非遞歸實(shí)現(xiàn)版)-創(chuàng)新互聯(lián)

最近剛學(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)方法

  • 主函數(shù)以及全局變量
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容器

  • MineRespawn函數(shù) - 隨機(jī)生成地雷方塊
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ù)量減少
        }
    }
}
  • numberRespawn函數(shù) - 給地雷周?chē)綁K賦值
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ù)的地址

  • vprint函數(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)化

  • inputV函數(shù)
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ù)。

  • judge函數(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)