日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

C语言项目:扫雷大战精简版

發布時間:2023/12/2 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C语言项目:扫雷大战精简版 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? ? ????一直說寫個幾百行的小項目,于是我寫了一個控制臺的掃雷,沒有想到精簡完了代碼才200行左右,不過考慮到這是我精簡過后的,濃縮才是精華嘛,我就發出來大家一起學習啦,看到程序跑起來能玩,感覺還是蠻有成就感的~~~

????????掃雷應該屬于一款大眾游戲,從我初中使用計算機開始,它就被集成到了windows系統中,雖然他是這么經典,我還是要介紹一下他的玩法,然后再考慮在控制臺中怎么實現它。

編輯


請點擊輸入圖片描述


1、游戲的主界面,是一個一個小方格,在小方格上單擊左鍵,可以翻開小方格看看后面有什么。

2、在這些小方格的背后隱藏著雷,如果不幸點中了雷,那么就GameOver了。

3、如果點中的不是一個雷,那么就是一塊空地,這個時候會出現兩種情況:

(1)用鼠標點中的空地周圍八個點內有雷,那么就顯示雷的個數

(2)用鼠標點中的空地周圍沒有雷,這個時候就將周圍的空地全部顯示出來,遇到該顯示數字的空地,就將數字顯示出來。(仔細觀察你會發現,數字會將空地圍起來,這是一句廢話,但是也值得想一想這是為什么)

4、在小方格上,點擊鼠標的右鍵,可以將一個空地標記為雷,當然這個功能只是為了方便你記憶你之前確定是雷的地方。(還有左右鍵都點,和點擊右鍵出現?標記,這里就不談啦)

5、當空地上剩余的格子數和雷的個數一樣多,那么這個時候就應該算是勝利啦。


????????OK~游戲流程說完了,這個時候該談談如何實現了。

1、首先需要一張地圖,一般情況下我們都可以用一個二維數組表示一個地圖,每一個元素代表著掃雷中的一個小方格。相應元素存儲0,那么地圖上的這個位置就是空地,相應元素存儲1,那么就代表這個位置就一顆雷。

2、在控制臺上依照二維數組長度和寬度,打印相應的小方塊。

3、然后就用鼠標點擊那些小方塊,對于控制臺來講,在黑框框的區域中是有坐標的,可以使用一些函數捕獲到你點擊了屏幕的哪一個坐標。

4、對于控制臺來說,打印一個字符,有的字符橫向占一個位置比如普通的字母數字,有的字符橫向占兩個位置比如一些圖形字符: ①②③■◆等等,這點在控制臺編程的時候要注意。

5、當點擊屏幕的時候,獲取到點擊的坐標后,去二維數組中查看相應的位置是雷還是空地,從而做相應的處理。

(1)假如點擊到了雷,那么就控制游戲結束

(2)假如點擊到了空地有兩種情況

(1)點擊的空地周圍有雷,那么就將雷的個數顯示出來

(2)假如點擊的空地周圍沒有雷,那么就使用遞歸的方法去探測周圍的點,探測出與其相連的所有周圍有雷的點。


下面就是代碼啦:

// saolei.cpp : 定義控制臺應用程序的入口點。

#include "stdafx.h"

#include <windows.h>

#include <stdlib.h>

#include <time.h>

#define Boom 10

int a[10][10] = {0};

COORD TempPos[100] ={0};

int nSign = 0;

/************************************

函數名 : WriteWchar

函數作用: 在控制臺相應的坐標上顯示一串字符

返回值 : void

參數 : int x 橫坐標

參數 : int y 縱坐標

參數 : char szString[] 要顯示的字符串

說明 :

************************************/

void WriteWchar(int x,int y,char szString[])

{

HANDLE hOut= GetStdHandle(STD_OUTPUT_HANDLE);

COORD pos = {x*2,y};

SetConsoleCursorPosition(hOut,pos);

printf("%s",szString);

}

/************************************

函數名 : DrawNumber

函數作用: 在相應的坐標上,根據傳入的數字,打印相應的數字字符

返回值 : void

參數 : COORD pos 要打印的位置

參數 : int nNumber 要打印的數字

說明 :

************************************/

void DrawNumber(COORD pos,int nNumber)

{

switch (nNumber)

{

case 1:

WriteWchar(pos.X,pos.Y,"①");

break;

case 2:

WriteWchar(pos.X,pos.Y,"②");

break;

case 3:

WriteWchar(pos.X,pos.Y,"③");

break;

case 4:

WriteWchar(pos.X,pos.Y,"④");

break;

case 5:

WriteWchar(pos.X,pos.Y,"⑤");

break;

case 6:

WriteWchar(pos.X,pos.Y,"⑥");

break;

case 7:

WriteWchar(pos.X,pos.Y,"⑦");

break;

case 8:

WriteWchar(pos.X,pos.Y,"⑧");

break;

default:

break;

}

}

/************************************

函數名 : GetNumber

函數作用: 獲取一個點的四周有幾顆雷

返回值 : int

參數 : COORD pos 要探測的點的坐標

說明 :

************************************/

int GetNumber(COORD pos)

{

int nCount = 0;

for(int i = pos.X-1;i<=pos.X+1;i++)

for (int j = pos.Y-1;j<=pos.Y+1;j++)

{

if (a[j][i] == Boom)

{

nCount++;

}

}

return nCount;

}

/************************************

函數名 : Drawmap

函數作用: 打印一下地圖

返回值 : void

說明 :

************************************/

void Drawmap()

{

for (int i =0;i<10;i++)

{

for (int j =0;j<10;j++)

{

WriteWchar(j,i,"■");

}

}

}

/************************************

函數名 : Init

函數作用: 隨機生成10個地雷,然后存到數組中

返回值 : void

說明 :

************************************/

void Init()

{

srand(time(NULL));

for (int i =0;i<10;i++)

{

int Temp_x = rand()%10;

int Temp_y = rand()%10;

//判斷這個地方是不是已經生成一個雷了,如果沒有,賦值為雷

if (a[Temp_x][Temp_y]!=Boom)

{

a[Temp_x][Temp_y] = Boom;

}

//如果是雷,就相當于本次生成沒有發生過。。。。。

else

{

i--;

}

}

Drawmap();

}

/************************************

函數名 : IsClose

函數作用: 判斷是不是已經探測過的點,由于使用的8方向遞歸的探測,這樣避免重復

返回值 : bool

參數 : COORD posTemp

說明 :

************************************/

bool IsClose(COORD posTemp)

{

for (int i =0;i<nSign;i++)

{

if(TempPos[i].X == posTemp.X&&TempPos[i].Y == posTemp.Y)

return true;

}

return false;

}

/************************************

函數名 : IsKongdi

函數作用: 判斷一個點是空地,還是雷,如果是空地,需要做其他處理

返回值 : void

參數 : COORD pos

說明 :

************************************/

bool IsKongdi(COORD pos)

{

int nNumber = 0;

//1 如果是雷,就直接返回一個false說明要掛了

if (a[pos.Y][pos.X] == Boom)

{

return false;

}

//2 如果不是雷,那么就做后續處理

else

{

//2.1先判斷一下周圍有幾顆雷

nNumber = GetNumber(pos);

if (nNumber!=0){

//有幾顆雷,就打印這個數字

DrawNumber(pos,nNumber);

return true;

}

else

{

//如果沒有雷,那就先畫空地出來,然后向周圍擴散去探測其他點

WriteWchar(pos.X,pos.Y," ");

}

}

//2.2點到了空地,但是周圍沒有雷的情況的處理,繼續去探測周圍8個點

for(int i = -1;i<=1;i++)

for (int j = -1;j<=1;j++)

{

COORD posTemp = {pos.X+i,pos.Y+j};

//是不是越界了

if (i==0&&j==0||posTemp.X==-1||posTemp.Y==-1||posTemp.X==10||posTemp.Y==10)

continue;

//這個點是不是已經探測過了

if (IsClose(posTemp))

continue;

//這個點沒有探測過,就將其加入到數組中,然后使其在以后的探測中,存入

TempPos[nSign++] =posTemp;

IsKongdi(posTemp);

}

return true;

}

/************************************

函數名 : GetMousePosition

函數作用: 獲取鼠標點擊的位置,假如沒有獲取到,就返回(-1,-1)

返回值 : COORD 鼠標點擊的坐標

說明 :

************************************/

COORD GetMousePosition()

{

HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE);

INPUT_RECORD stcInput = {0};

DWORD buffer;

COORD pos = {-1,-1};

ReadConsoleInput(hIn,&stcInput,1,&buffer);

if (stcInput.EventType == MOUSE_EVENT)

{

MOUSE_EVENT_RECORD stcMouseEnent = stcInput.Event.MouseEvent;

if (stcMouseEnent.dwButtonState ==FROM_LEFT_1ST_BUTTON_PRESSED )

{

pos = stcMouseEnent.dwMousePosition;

pos.X/=2;

}

}

return pos;

}

int _tmain(int argc, _TCHAR* argv[])

{

Init();

COORD pos;

//開始游戲

while(1)

{

//獲取鼠標點擊位置

pos = GetMousePosition();

if (pos.X!=-1)

{

//如果鼠標點擊的位置被探測過了,就開始下一次循環

if (IsClose(pos))

{

continue;

}

TempPos[nSign++] =pos;

bool bIskongdi = IsKongdi(pos);

//點到雷了,就直接退出游戲了。

if (false ==bIskongdi)

{

system("cls");

WriteWchar(20,10,"you lose");

getchar();

break;

}

//檢測是不是贏了,贏的條件就是沒有被探測的點的個數和雷的個數相等

if (nSign ==90)

{

system("cls");

WriteWchar(20,10,"you win");

}

}

}

return 0;

}

項目不是很長,但是注釋我寫的還算明白,估計大家都可以看得懂,希望對于新手們有一定的幫助,最后,謝謝大家的支持!!!

關注點贊

總結

以上是生活随笔為你收集整理的C语言项目:扫雷大战精简版的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。