關于C語言編程學習敬特,第一個小項目,打造掃雷游戲

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

掃雷應該屬于一款大眾游戲合搅,從我初中使用計算機開始,它就被集成到了windows系統(tǒng)中怕篷,雖然他是這么經(jīng)典历筝,我還是要介紹一下他的玩法,然后再考慮在控制臺中怎么實現(xiàn)它廊谓。

C/C++學習群:315732400

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

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

2 如果點中的不是一個雷,那么就是一塊空地榛鼎,這個時候會出現(xiàn)兩種情況:

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

2)用鼠標點中的空地周圍沒有雷鳖孤,這個時候就將周圍的空地全部顯示出來,遇到該顯示數(shù)字的空地抡笼,就將數(shù)字顯示出來苏揣。(仔細觀察你會發(fā)現(xiàn),數(shù)字會將空地圍起來推姻,這是一句廢話平匈,但是也值得想一想這是為什么)

3 在小方格上,點擊鼠標的右鍵藏古,可以將一個空地標記為雷增炭,當然這個功能只是為了方便你記憶你之前確定是雷的地方。(還有左右鍵都點拧晕,和點擊右鍵出現(xiàn)隙姿?標記,這里就不談啦)

4 當空地上剩余的格子數(shù)和雷的個數(shù)一樣多防症,那么這個時候就應該算是勝利啦孟辑。

OK~游戲流程說完了,這個時候該談談如何實現(xiàn)了蔫敲。

1 首先需要一張地圖饲嗽,一般情況下我們都可以用一個二維數(shù)組表示一個地圖,每一個元素代表著掃雷中的一個小方格奈嘿。相應元素存儲0貌虾,那么地圖上的這個位置就是空地,相應元素存儲1裙犹,那么就代表這個位置就一顆雷尽狠。

2 在控制臺上依照二維數(shù)組長度和寬度,打印相應的小方塊叶圃。

3 然后就用鼠標點擊那些小方塊袄膏,對于控制臺來講,在黑框框的區(qū)域中是有坐標的掺冠,可以使用一些函數(shù)捕獲到你點擊了屏幕的哪一個坐標沉馆。

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

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

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

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

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

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

這個是我實現(xiàn)的效果:

下面就是代碼啦:

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

//

#include "stdafx.h"

#include

#include

#include

#define Boom 10

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

COORD TempPos[100] ={0};

int nSign = 0;

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

函數(shù)名 : WriteWchar

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

返回值 : void

參數(shù) : int x 橫坐標

參數(shù) : int y 縱坐標

參數(shù) : 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);

}

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

函數(shù)名 : DrawNumber

函數(shù)作用: 在相應的坐標上茴恰,根據(jù)傳入的數(shù)字销钝,打印相應的數(shù)字字符

返回值 : void

參數(shù) : COORD pos 要打印的位置

參數(shù) : int nNumber 要打印的數(shù)字

說明 :

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

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;

}

}

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

函數(shù)名 : GetNumber

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

返回值 : int

參數(shù) : 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;

}

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

函數(shù)名 : Drawmap

函數(shù)作用: 打印一下地圖

返回值 : void

說明 :

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

void Drawmap()

{

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

{

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

{

WriteWchar(j,i,"■");

}

}

}

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

函數(shù)名 : Init

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

返回值 : void

說明 :

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

void Init()

{

srand(time(NULL));

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

{

int Temp_x = rand()%10;

int Temp_y = rand()%10;

//判斷這個地方是不是已經(jīng)生成一個雷了琐簇,如果沒有,賦值為雷

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

{

a[Temp_x][Temp_y] = Boom;

}

//如果是雷座享,就相當于本次生成沒有發(fā)生過婉商。。渣叛。丈秩。。

else

{

i--;

}

}

Drawmap();

}

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

函數(shù)名 : IsClose

函數(shù)作用: 判斷是不是已經(jīng)探測過的點淳衙,由于使用的8方向遞歸的探測蘑秽,這樣避免重復

返回值 : bool

參數(shù) : COORD posTemp

說明 :

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

bool IsClose(COORD posTemp)

{

for (int i =0;i

{

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

return true;

}

return false;

}

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

函數(shù)名 : IsKongdi

函數(shù)作用: 判斷一個點是空地,還是雷箫攀,如果是空地肠牲,需要做其他處理

返回值 : void

參數(shù) : COORD pos

說明 :

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

bool IsKongdi(COORD pos)

{

int nNumber = 0;

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

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

{

return false;

}

//2 如果不是雷靴跛,那么就做后續(xù)處理

else

{

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

nNumber = GetNumber(pos);

if (nNumber!=0){

//有幾顆雷缀雳,就打印這個數(shù)字

DrawNumber(pos,nNumber);

return true;

}

else

{

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

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

}

}

//2.2點到了空地肥印,但是周圍沒有雷的情況的處理,繼續(xù)去探測周圍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;

//這個點是不是已經(jīng)探測過了

if (IsClose(posTemp))

continue;

//這個點沒有探測過绝葡,就將其加入到數(shù)組中深碱,然后使其在以后的探測中,存入

TempPos[nSign++] =posTemp;

IsKongdi(posTemp);

}

return true;

}

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

函數(shù)名 : GetMousePosition

函數(shù)作用: 獲取鼠標點擊的位置藏畅,假如沒有獲取到敷硅,就返回(-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)

{

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

if (IsClose(pos))

{

continue;

}

TempPos[nSign++] =pos;

bool bIskongdi = IsKongdi(pos);

//點到雷了墓赴,就直接退出游戲了竞膳。

if (false ==bIskongdi)

{

system("cls");

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

getchar();

break;

}

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

if (nSign ==90)

{

system("cls");

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

}

}

}

return 0; ?

} ?

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末诫硕,一起剝皮案震驚了整個濱河市坦辟,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌章办,老刑警劉巖锉走,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件滨彻,死亡現(xiàn)場離奇詭異,居然都是意外死亡挪蹭,警方通過查閱死者的電腦和手機亭饵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來梁厉,“玉大人辜羊,你說我怎么就攤上這事〈使耍” “怎么了八秃?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長肉盹。 經(jīng)常有香客問我昔驱,道長,這世上最難降的妖魔是什么上忍? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任骤肛,我火速辦了婚禮,結果婚禮上窍蓝,老公的妹妹穿的比我還像新娘腋颠。我一直安慰自己,他們只是感情好它抱,可當我...
    茶點故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布秕豫。 她就那樣靜靜地躺著,像睡著了一般观蓄。 火紅的嫁衣襯著肌膚如雪混移。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天侮穿,我揣著相機與錄音歌径,去河邊找鬼。 笑死亲茅,一個胖子當著我的面吹牛回铛,可吹牛的內容都是我干的。 我是一名探鬼主播克锣,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼茵肃,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了袭祟?” 一聲冷哼從身側響起验残,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎巾乳,沒想到半個月后您没,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鸟召,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年氨鹏,在試婚紗的時候發(fā)現(xiàn)自己被綠了欧募。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,163評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡仆抵,死狀恐怖跟继,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情镣丑,我是刑警寧澤还栓,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站传轰,受9級特大地震影響,放射性物質發(fā)生泄漏谷婆。R本人自食惡果不足惜慨蛙,卻給世界環(huán)境...
    茶點故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望纪挎。 院中可真熱鬧期贫,春花似錦、人聲如沸异袄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽烤蜕。三九已至封孙,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間讽营,已是汗流浹背虎忌。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留橱鹏,地道東北人膜蠢。 一個月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像莉兰,于是被迫代替她去往敵國和親挑围。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,925評論 2 344

推薦閱讀更多精彩內容