两个吃奶一个添下面视频_人妻第一页香蕉网_欧美xxxx少妇_妺妺窝人体色www婷婷

一、源碼簡介

這是一個可以進行掃雷游戲的小程序,采用C語言進行編寫。

上下左右控制光標位置,按j鍵進行標記,按k進行點擊探雷,并且當光標 放在數(shù)字上,且周圍的雷都已經(jīng)被正確標記時,按k可以點開周圍所有的空白,不過出錯會結(jié)束游戲。

雷區(qū)長寬為25格,初始有10雷,每過一關(guān)增加20雷。

 編譯環(huán)境:VC6.0(采取純C語言寫法)

第三方庫:無

 

二、運行截圖

掃雷1


掃雷2


三、源碼解析

我們先來看游戲的主體邏輯。

雖然下面的代碼很長,但邏輯還是較為清晰的。

以下循環(huán)

若游戲未開始,初始化。

若游戲開始,則檢測鍵盤輸入

  按下ASDW則移動光標

  第一次按下K,則初始化雷區(qū)

  按下K則點開空白,或者清雷,并檢測是否勝利

  按下j則進行標記

游戲結(jié)束跳出循環(huán)

void Gamerun()//游戲主體
{
       int first;
       while(1)
       {
              if(gamestate==0)//初始化
              {
                     first=0;
                     m_time=time(NULL);//時間初始化
                     Init_display();//初始化顯示區(qū)域
                     CONSOLE_CURSOR_INFO cursor_info = { 1,0 };    
                     SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);//設(shè)置指定控制臺屏幕緩沖區(qū)的光標的大小和可見性
                     gamestate=1;
              }
              else if(gamestate==1)//游戲中
              {
                     RemainderMine();//計算剩余的雷
                     Draw_display();
                     MoveCursor();
                     PressJ();
                     if(GetAsyncKeyState('K')&1)//如果按下K
                     {
                            if(first==0)
                            {
                                Init_mine(pos.y,pos.x);
                                OpenDisplay(pos.y,pos.x);
                                first++;
                                if(Victory())//判定是否獲勝
                                {
                                       Showmine();
                                       Draw_display();
                                       UINT uint=MessageBox(NULL,TEXT("恭喜過關(guān)!是否繼續(xù)。"),TEXT("提示"),1);
                                       if(uint==IDOK)
                                       {
                                              count+=20;
                                              level++;
                                              gamestate=0;
                                       }
                                       else if(uint==IDCANCEL)
                                       {
                                              gamestate=2;
                                       }
                                       else;
                                }
                                   else;
                         }
                            else
                            {
                                   if(TreadMine(pos.y,pos.x))//判斷是否踩到雷
                                   {
                                          Showmine();
                                          Draw_display();
                                          UINT uint=MessageBox(NULL,TEXT("掃雷失??!是否重新開始?"),TEXT("提示"),MB_OKCANCEL|MB_ICONERROR);
                                          if(uint==IDOK)
                                       {
                                              gamestate=0;
                                       }
                                       else if(uint==IDCANCEL)
                                      {
                                             gamestate=2;
                                       }
                                       else;
                                   }
                                   else
                                   {
                                          OpenDisplay(pos.y,pos.x);
                                   }
                                   if(OpenNumDisplay1(pos.y,pos.x))//按K也可以清雷,返回值為1表示踩雷
                                {
                                       Showmine();
                                       Draw_display();
                                          UINT uint=MessageBox(NULL,TEXT("掃雷失敗!是否重新開始?"),TEXT("提示"),MB_OKCANCEL|MB_ICONERROR);
                                          if(uint==IDOK)
                                       {
                                              gamestate=0;
                                       }
                                       else if(uint==IDCANCEL)
                                      {
                                             gamestate=2;
                                       }
                                       else;
                                }
                                else;
                                   if(Victory())//判定是否獲勝
                                {
                                       Showmine();
                                       Draw_display();
                                       UINT uint=MessageBox(NULL,TEXT("恭喜過關(guān)!是否繼續(xù)。"),TEXT("提示"),1);
                                       if(uint==IDOK)
                                       {
                                              count+=20;
                                              level++;
                                              gamestate=0;
                                       }
                                       else if(uint==IDCANCEL)
                                       {
                                              gamestate=2;
                                       }
                                       else;
                                }
                                   else;
                            }
                     }
                     else;
              }
              else if(gamestate==2)//游戲結(jié)束
              {
                     printf("GAME END!");
                     break;
              }
              else;
       }
}

 

下面看一些重要部分的實現(xiàn)。

改變光標位置以及定義為輸出模式

void Pos(int x,int y)//定義一個設(shè)置光標位置到(x,y)的函數(shù)
{
    COORD pos;
    HANDLE hOutput;
    pos.X=x;
    pos.Y=y;
    hOutput=GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorPosition(hOutput,pos);
}

 

初始化雷區(qū)實現(xiàn)原理:

void Init_mine(int m, int n)//初始化雷區(qū)
{
       int num=count;
       int x,y;
       srand((unsigned)time(NULL));//利用時間獲取隨機種子
       while(num>0)
       {
              x=rand()%height+1;//1-25
              y=rand()%width+1;//1-25
              if(mine[x][y]==0&&(m!=x||n!=y))//避免重復(fù)
              {
                     mine[x][y]=1;
                     num--;
              }
              else;
       }
}

這個函數(shù)在第一次按下k的時候調(diào)用,輸入值為光標的位置。在生成雷的時候,如果與之前的雷或者光標重合,那么會重新生成一個雷,這樣做可以避免直接失敗。

 

檢測某一點周圍的雷數(shù)目,以及標記數(shù)目

這兩者的原理都是一樣的。直接對光標周圍八個點進行判定,若是則++。

繪制游戲畫面

void Draw_display()//繪制游戲畫面
{
       Pos(7, 7);//光標定位
       int i,j;
       for(i=1;i<=height;i++)//逐行逐列輸出游戲畫面
       {
              for(j=1;j<=width;j++)
              {
                     if(j==pos.x&&i==pos.y)
                            SetConsoleTextAttribute(ColorHandle,0X5|0XC);//對不同類型的圖像設(shè)置不同顏色
                     else if(map[i][j]==10)
                            SetConsoleTextAttribute(ColorHandle,0X94);
                     else
                            SetConsoleTextAttribute(ColorHandle,0X97);
                     switch(map[i][j])
                     {
                            case 0:printf("  ");break;
                            case 1:printf("1 ");break;
                            case 2:printf("2 ");break;
                            case 3:printf("3 ");break;
                            case 4:printf("4 ");break;
                            case 5:printf("5 ");break;
                            case 6:printf("6 ");break;
                            case 7:printf("7 ");break;
                            case 8:printf("8 ");break;
                            case 9:printf("■");break;//未知區(qū)域
                            case 10:printf("▲");break;//標記
                            case 11:printf("雷");break;//雷
                     }
                     if(j==pos.x&&i==pos.y)
                            SetConsoleTextAttribute(ColorHandle,0X7);//關(guān)閉顏色
                     else if(map[i][j]==10)
                            SetConsoleTextAttribute(ColorHandle,0X7);
                     else
                            SetConsoleTextAttribute(ColorHandle,0X7);
              }
              Pos(7,7+i);//光標移到下一行
       }
       Pos(7,3);
       printf("未排除的雷:%d   ",RemMine);//打印各種文字信息
       Pos(7,5);
       printf("時間:%ld 秒   ",long(time(NULL)-m_time));
       Pos(27,3);
       printf("關(guān)卡:%d  ",level);
}

采用雙層循環(huán)結(jié)構(gòu),對區(qū)域的每個點進行一次判定,將對應(yīng)的標識及顏色輸出就可以了。注意不要混淆圖像數(shù)組和雷的信息數(shù)組。

 

展開無雷區(qū)域

在掃雷游戲中,當我們第一次點擊時,很有可能點開一大片區(qū)域。其實現(xiàn)如下面的代碼所示。

void OpenDisplay(int x,int y)//單擊后展開顯示無雷區(qū)域
{
       int i,j;
       int offsetX[] = { 0,1,1,1,0,-1,-1,-1 };
       int offsetY[] = { -1,-1,0,1,1,1,0,-1 };
       if(map[x][y]==9&&x>0&&x<=width&&y>0&&y<=height)//中心點顯示有幾顆雷
       {
              map[x][y]=Judge_mine(x,y);
              if(map[x][y]>0)//某點周圍有雷就不展開
              {
                     return;
              }
              else;
       }
       else if(map[x][y]==10||(map[x][y]>=1&&map[x][y]<=8))//某點為標記或數(shù)字 不展開
       {
              return;
       }
       else;
       for(i=0;i<8;i++)//周圍8點
       {
              if(x>0&&x<=width&&y>0&&y<=height)
              {
                     if(map[x+offsetX[i]][y+offsetY[i]]==10&&mine[x+offsetX[i]][y+offsetY[i]]!=1)//展開的時候,如果周圍某點為標記且不是雷
                     {
                            map[x+offsetX[i]][y+offsetY[i]]=9;//改為未知區(qū)域
                     }
                     if(mine[x+offsetX[i]][y+offsetY[i]]==0&&map[x+offsetX[i]][y+offsetY[i]]==9)//無雷且未知,則展開
                     {
                            map[x+offsetX[i]][y+offsetY[i]]=Judge_mine(x+offsetX[i],y+offsetY[i]);//得到某點周圍的雷的個數(shù)
                            if(map[x+offsetX[i]][y+offsetY[i]]==0)//該點無雷且無數(shù)字
                            {
                                   OpenDisplay(x+offsetX[i],y+offsetY[i]);//遞歸
                            }
                     }
              }
       }
       return;
}

具體來說,就是采取遞歸的算法。先判定該點是否產(chǎn)生變化,如果產(chǎn)生,則對周圍8個點同樣做出一次判定。如果這些點周圍的雷數(shù)為0,則遞歸調(diào)用該函數(shù)。

 

清雷動作

當一個數(shù)字周圍的雷全部被點開之后,在其上按k會點開周圍無雷的區(qū)域

int OpenNumDisplay1(int x,int y)//將數(shù)字周圍區(qū)域顯示出來。返回值表明是否因為該動作踩雷,1為是
{
       int i,j;
       int offsetX[]={ 0,1,1,1,0,-1,-1,-1 };
       int offsetY[]={ -1,-1,0,1,1,1,0,-1 };
       if(map[x][y]<9&&map[x][y]>0)//1-8
       {
              if(Judge_mine(x,y)==Judge_cur(x,y))//若周圍標記數(shù)量等于周圍雷的數(shù)量,展開
              {
                     for(i=0;i<8;i++)
                     {
                            if(x>0&&x<=width&&y>0&&y<=height)//越界判斷
                            {
                                   if(map[x+offsetX[i]][y+offsetY[i]]==9||map[x+offsetX[i]][y+offsetY[i]]==10)//為標記和未知區(qū)域時,進行判定
                                   {
                                          if(map[x+offsetX[i]][y+offsetY[i]]==10&&mine[x+offsetX[i]][y+offsetY[i]]==1)//標記正確
                                          {
                                                 continue;
                                          }
                                          else if(map[x+offsetX[i]][y+offsetY[i]]==10&&mine[x+offsetX[i]][y+offsetY[i]]!=1) //標記錯誤
                                          {
                                                 return 1;//踩雷
                                          }
                                          else;
                                   }
                                   else;
                            }
                            else;
                     }
                     for(i=0;i<8;i++)
                     {
                            if(x>0&&x<=width&&y>0&&y<=height)//越界判斷
                            {
                                   if(map[x+offsetX[i]][y+offsetY[i]]==9)//為未知區(qū)域則正常展開
                                   {
                                          OpenDisplay(x+offsetX[i],y+offsetY[i]);//展開
                                   }
                            }
                     }
              }
       }
       return 0;
}

輸入為按下k時的光標位置。判定周圍標記數(shù)是否與雷數(shù)相同,是則檢查每一個標記處是否為雷,若全部對應(yīng),則清雷,若有不對應(yīng)的,則游戲結(jié)束。

其余定義的函數(shù)還有檢測是否踩雷,計算剩余的雷,判定是否勝利,顯示雷,移動光標,做標記。這些函數(shù)一般都是用雙重循環(huán),或者直接改變變量的方法進行的。這里暫時不給出源碼,但完整源碼也會有對應(yīng)的內(nèi)容。


四、完整源碼

C語言掃雷完整源碼

點贊(0)

C語言網(wǎng)提供由在職研發(fā)工程師或ACM藍橋杯競賽優(yōu)秀選手錄制的視頻教程,并配有習(xí)題和答疑,點擊了解:

一點編程也不會寫的:零基礎(chǔ)C語言學(xué)練課程

解決困擾你多年的C語言疑難雜癥特性的C語言進階課程

從零到寫出一個爬蟲的Python編程課程

只會語法寫不出代碼?手把手帶你寫100個編程真題的編程百練課程

信息學(xué)奧賽或C++選手的 必學(xué)C++課程

藍橋杯ACM、信息學(xué)奧賽的必學(xué)課程:算法競賽課入門課程

手把手講解近五年真題的藍橋杯輔導(dǎo)課程

Dotcpp在線編譯      (登錄可減少運行等待時間)