




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、編程實(shí)現(xiàn)一個(gè)掃雷機(jī)器人一、課題內(nèi)容和要求在一個(gè)20*20的地圖上,分布著81顆地雷,掃雷機(jī)器人走到其中一個(gè)方格上,如果是地雷,它將被炸死,如果不是,它可以探測(cè)到它周圍的八個(gè)方格中有幾個(gè)地雷?,F(xiàn)在你擁有10個(gè)掃雷機(jī)器人(10次錯(cuò)誤機(jī)會(huì)),請(qǐng)你將這片雷區(qū)中的所有地雷標(biāo)出來(lái)。二、需求分析(1)規(guī)則描述 游戲開(kāi)始時(shí),系統(tǒng)會(huì)在雷區(qū)的某些小方塊中隨機(jī)布下81顆雷,部署完畢后,系統(tǒng)會(huì)在其他非雷方塊中填充一些數(shù)字,某一個(gè)具體數(shù)字表示預(yù)期緊鄰的8個(gè)方塊中有多少雷方塊,玩家可以可以根據(jù)這些信息去判斷是否可以打開(kāi)某些方塊,并把認(rèn)為是地雷的方塊打上標(biāo)記,當(dāng)玩家將所有地雷找出后,其余的非雷方塊區(qū)域都已打開(kāi),此時(shí)游戲勝利
2、結(jié)束,在游戲過(guò)程中,一旦錯(cuò)誤地打開(kāi)了雷方塊10次以上,游戲結(jié)束。(2)功能需求分析此掃雷機(jī)器人游戲是一個(gè)交互式的游戲,它的開(kāi)發(fā)需滿足的要求包括以下幾個(gè)部分:一部分是此游戲界面需要在20*20的界面上實(shí)現(xiàn),并規(guī)定雷數(shù)為81顆,第二部分是實(shí)現(xiàn)掃雷要求,即掃雷機(jī)器人走到其中一個(gè)方格上,如果是地雷,它將被炸死,如果不是,它可以探測(cè)到它周圍的八個(gè)方格中有幾個(gè)地雷,該部分包括進(jìn)行某種操作判斷某區(qū)域是否是雷,如果是雷該如何操作,如果不是雷該如何操作,判斷某區(qū)域是雷則如何加以標(biāo)記,以及點(diǎn)擊某區(qū)域時(shí),判斷與該區(qū)域相鄰的其它8個(gè)區(qū)域是否是雷并做一個(gè)標(biāo)記。第三部分是此掃雷機(jī)器人有10次錯(cuò)誤機(jī)會(huì)。(3)功能模塊需求分
3、析程序設(shè)計(jì)過(guò)程中涉及到的功能模塊函數(shù):1函數(shù):static int TextOut(const char* pstr ); 功能要求:在當(dāng)前位置輸出字符串,本程序根據(jù)各種操作,定義的字符串分別為"ArrowKey:MoveCursor Key1:Open Key2:Mark Key3:OpenNeighbors"代表程序標(biāo)題、Congratulations! You Win! Thank you for playing!代表游戲獲勝、Game Over, thank you for playing!代表游戲失敗、Presented by 1803 . Press ESC t
4、o exit代表退出。2函數(shù): static int GotoXY(int x , int y );功能要求:光標(biāo)移至(x,y)處并得到此光標(biāo)位置。3函數(shù):static int CharOut(int x, int y, const int pstr);功能要求:在(x,y)處輸出一字符。4函數(shù):static int TextOut(int x, int y, const char* pstr);功能要求:由任意位置移到(x,y)并在當(dāng)前位置輸出字符串5函數(shù):static int GetKey(); 功能要求:等待鍵1、2、3的輸入并返回此值。6函數(shù):int InitPool(in
5、t Width, int Height, int nBoom);功能要求:初始化游戲環(huán)境。 7函數(shù):int DrawPool(int bDrawBoom = 0);功能要求:根據(jù)各區(qū)域內(nèi)容輸出字符串 、 *、 #、 .。8. 函數(shù):int WaitMessage( );功能要求:根據(jù)各種輸入KEY_UP、 KEY_DOWN、 KEY_LEFT、 KEY_RIGHT、 KEY_1、 KEY_2 、KEY_3、 KEY_ESC執(zhí)行操作,通過(guò)返回的nRT來(lái)判斷失敗、勝利或未結(jié)束。9. 函數(shù):int GetShowNum(int x, int y);功能要求:確定認(rèn)一點(diǎn)(x,y)和它周圍8個(gè)方向的總雷
6、數(shù),并把雷的數(shù)目顯示出來(lái)。10. 函數(shù):int TryOpen(int x, int y); 功能要求:打開(kāi)點(diǎn)(x,y)并顯示雷數(shù)號(hào)碼,必須實(shí)現(xiàn)10次機(jī)會(huì)錯(cuò)誤這一功能要求,若超出10次而未找出全部雷數(shù),則將游戲界面上的所有雷顯示出來(lái)(即返回EOF)。11. 函數(shù):int DFSShowNum(int x, int y);功能要求:在游戲界面范圍內(nèi),先通過(guò)調(diào)用函數(shù)int GetShowNum(int x, int y)獲得任意一點(diǎn)周圍的總雷數(shù),若為0,則通過(guò)遞歸調(diào)用直至將獲得的雷數(shù)顯示出來(lái)。 四、概要設(shè)計(jì)整體游戲流程圖:游戲開(kāi)始執(zhí)行操作雷區(qū)GAME OVER判斷非雷區(qū)程序使用了面向?qū)ο?/p>
7、的方法,首先創(chuàng)建工程項(xiàng)目,本程序基于Win32 Console Application.程序定義了窗口類class CConsoleWnd和類模塊class CSLGame , 類中成員變量和成員函數(shù)原型聲明分別如下:(1).class CConsoleWnd public: static int TextOut(const char*); static int GotoXY(int, int); static int CharOut(int, int, const int); static int TextOut(int, int, const char*); static int GetK
8、ey(); ;(2).class CSLGame:public CConsoleWnd private: int curX,curY; int poolWidth,poolHeight; int bm_gamepoolGAME_MAX_HEIGHT+2GAME_MAX_WIDTH+2; public: CSLGame():curX(0),curY(0)poolWidth=poolHeight=0; int InitPool(int, int, int); int MoveCursor()return CConsoleWnd:GotoXY(curX, curY); int DrawPool(in
9、t); int WaitMessage(); int GetShowNum(int, int); int TryOpen(int, int); private: int DFSShowNum(int, int); private: const static int GMARK_BOOM; const static int GMARK_EMPTY; const static int GMARK_MARK;const int CSLGame:GMARK_BOOM = 0x10;const int CSLGame:GMARK_EMPTY= 0x100;const int CSLGame:GMARK_
10、MARK = 0x200;#define KEY_UP 0xE048#define KEY_DOWN 0xE050#define KEY_LEFT 0xE04B#define KEY_RIGHT 0xE04D#define KEY_ESC 0x001B#define KEY_1 '1'#define KEY_2 '2'#define KEY_3 '3'#define GAME_MAX_WIDTH 100#define GAME_MAX_HEIGHT 100算法設(shè)計(jì)包括:1 隨機(jī)布雷可以隨即獲取一個(gè)狀態(tài)為非雷的點(diǎn),將它的屬性標(biāo)志為雷,重復(fù)這樣的工作
11、直到將81顆雷布完。流程圖如下:是開(kāi)始生成隨機(jī)的雷方塊的坐標(biāo)(x,y)判斷(x,y)區(qū)域是否已經(jīng)布下雷在(x,y)區(qū)域布雷,修改狀態(tài)數(shù)據(jù)判斷是否布下所有雷結(jié)束否否是設(shè)數(shù)組bm_gamepoolyx為地雷標(biāo)志數(shù)組,若此數(shù)組恒為0,則標(biāo)志為雷,Windows的API有這樣的一種機(jī)制,可以生成隨機(jī)函數(shù)。先用strand()函數(shù)產(chǎn)生并返回隨機(jī)種子,可以利用系統(tǒng)的時(shí)間作為隨機(jī)數(shù)產(chǎn)生的種子,而產(chǎn)生的隨機(jī)數(shù)實(shí)際上是偽隨機(jī)數(shù),它的產(chǎn)生是根據(jù)遞推公式計(jì)算的一組數(shù)組,即int x = rand()%Width + 1, y = rand()%Height + 1,當(dāng)序列長(zhǎng)度滿足81時(shí),這組數(shù)值近似滿足均勻分布。2
12、. 做雷陣,即雷數(shù)目的計(jì)算和顯示在沒(méi)有雷的地方點(diǎn)擊后就會(huì)顯示一個(gè)數(shù)字表示它周圍有幾個(gè)雷,這是怎么實(shí)現(xiàn)的呢?我們可以把整個(gè)雷區(qū)看成一個(gè)二維數(shù)組bm_gamepoolyx,假如雷區(qū): 11 12 13 14 15 16 17 18 21 22 23 24 25 26 27 28 31 32 33 34 35 36 37
13、 38 41 42 43 44 45 46 47 48 51 52 53 54 55 56 57 58我要知道a34周圍有幾個(gè)雷,就只有去檢測(cè) a23,a24,a25 a33, a35 a43,a44,a45這8個(gè)雷區(qū)是否放上了雷,仔細(xì)觀察它們成在數(shù)學(xué)關(guān)系,抽象出來(lái)就是:ai,j的雷的個(gè)數(shù)就是由
14、160;ai-1,j-1,ai-1,j,ai-1,j+1 a i ,j-1, a i ,j+1 ai+1,j-1,ai+1,j,ai+1,j+1 這樣的8個(gè)雷區(qū)決定的。對(duì)于任意一點(diǎn)(x,y)執(zhí)行循環(huán)語(yǔ)句:for(int Y=-1;Y<=1;+Y) for(int X=-1;X<=1;+X) if(bm_gamepooly+Yx+X & GMARK_BOOM)+nCount; 觀察并計(jì)算它周圍8個(gè)方向雷區(qū)的總雷數(shù)。3.
15、 雷方塊拓展接著上面的例子,假如a3,4周圍雷數(shù)為1,a2,3已被標(biāo)示為地雷,那么a24,a25,a33,a35,a43,a44,a45將被展開(kāi),一直波及到不可確定的雷區(qū)。這也是實(shí)現(xiàn)的關(guān)鍵。我們可以把數(shù)組的元素設(shè)定為一個(gè)類對(duì)象,它們所屬的類設(shè)定這樣的一個(gè)事件:在被展開(kāi)時(shí),檢查周圍的雷數(shù)是否與周圍標(biāo)示出來(lái)的雷數(shù)相等,如果相等則展開(kāi)周圍未標(biāo)示的雷區(qū)。這樣新的雷區(qū)展開(kāi)又觸發(fā)這個(gè)事件,就這樣遞歸下去,一直蔓延到不可展開(kāi)的雷區(qū)。4. KEY_1事件在雷區(qū)鍵1的時(shí)候,光標(biāo)所在的方塊將顯示提示信息,即它周圍8個(gè)方向的雷區(qū)總雷數(shù)。(1) 判斷鼠標(biāo)點(diǎn)擊的雷區(qū)位置,計(jì)算出當(dāng)前打開(kāi)的小方塊坐標(biāo)。(2) 檢測(cè)小方塊的
16、狀態(tài),判斷能否打開(kāi),是則跳到無(wú)雷狀態(tài)處理。(3) 檢測(cè)小方塊的狀態(tài),判斷是否為雷,是則跳到雷狀態(tài)處理。(4) 繼續(xù)狀態(tài)處理,打開(kāi)小方塊,并拓展最大可能顯示范圍。KEY_1事件流程圖如下:KEY_1事件游戲結(jié)束雷方塊定位繼續(xù)處理打開(kāi)區(qū)域拓展最大的可能顯示范圍勝利失敗處理勝利處理顯示結(jié)束否是否是5. KEY_2事件對(duì)雷區(qū)域中某個(gè)小方塊的屬性做出判斷后,可以鍵2做出相應(yīng)的屬性標(biāo)記,當(dāng)鍵2時(shí),可以根據(jù)以前該雷方塊標(biāo)識(shí)的狀態(tài)去計(jì)算出應(yīng)該顯示的下一狀態(tài),并標(biāo)識(shí)對(duì)該雷方塊的推測(cè)屬性,人啊背后予以顯示,其實(shí)現(xiàn)步驟如下:(1)光標(biāo)所在的雷區(qū)位置。(2)歷史標(biāo)志狀態(tài)。(3)使?fàn)顟B(tài)修改為即將顯示的狀態(tài)。(4)顯示。
17、 KEY_2的流程分析如下圖:KEY_2事件雷方塊定位判斷歷史屬性以及相關(guān)狀態(tài)修改相關(guān)狀態(tài)顯示結(jié)束6. KEY_3事件對(duì)雷區(qū)域中某個(gè)小方塊的屬性做出判斷后,可以鍵3做出相應(yīng)的雷區(qū)拓展,首先顯示該區(qū)域的方塊狀態(tài),然后判斷該方塊周圍8個(gè)方向的方塊中是否有雷,如果沒(méi)有,則在此方塊鍵3,將會(huì)打開(kāi)這8個(gè)方塊中無(wú)雷的區(qū)域。實(shí)現(xiàn)步驟如下:(1) 光標(biāo)所在雷區(qū)顯示的數(shù)字。(2) 相鄰8個(gè)方向的區(qū)域狀態(tài)。(3) 進(jìn)行判斷,并做相應(yīng)操作。(4) 結(jié)果顯示。 KEY_3流程分析如下圖:KEY_3事件雷方塊定位判斷其屬性以及周圍方塊狀態(tài)打開(kāi)其周圍非雷區(qū)顯示結(jié)束 五、詳細(xì)設(shè)計(jì)1.二維數(shù)組初始化我開(kāi)的是一個(gè)22
18、*22的數(shù)組,而實(shí)際使用的雷區(qū)是20*20的數(shù)組,周圍一圈是空的,這樣對(duì)雷區(qū)的邊界,我也可以簡(jiǎn)單的將它周圍8個(gè)點(diǎn)的雷數(shù)相加,而不會(huì)發(fā)生數(shù)組越界的情況,但在編程的時(shí)候,仍應(yīng)該認(rèn)為雷區(qū)是一個(gè)簡(jiǎn)單的20*20的數(shù)組,可以利用的應(yīng)該是0,19. #define GAME_MAX_WIDTH 100#define GAME_MAX_HEIGHT 100int bm_gamepoolGAME_MAX_HEIGHT+2GAME_MAX_WIDTH+2;while(nBoom) int x = rand()%Width + 1, y = rand()%Height + 1; if(bm_gamep
19、oolyx=0) bm_gamepoolyx = GMARK_BOOM; -nBoom; 2.判斷一個(gè)區(qū)域是否是雷方塊int CSLGame:DrawPool(int bDrawBoom = 0)if(bm_gamepoolyx & GMARK_BOOM) if(bDrawBoom) putchar('*'); else putchar('.'); 3.相鄰區(qū)域的雷數(shù)獲取/ return ShowNum at (x, y) int CSLGame:GetShowNum(int x, int y) int nCount = 0; for(int Y=-1;
20、Y<=1;+Y) for(int X=-1;X<=1;+X) if(bm_gamepooly+Yx+X & GMARK_BOOM)+nCount; return nCount; 4.根據(jù)玩家的操作和雷區(qū)的分布,在游戲界面上顯示 各字符串 用來(lái)表示空、 *用來(lái)表示為雷、 #表示此區(qū)域標(biāo)志為雷、 .表示未確定區(qū)域或雷數(shù),即任意一點(diǎn)周圍8個(gè)方向的總雷數(shù)。/ Draw game pool to Console windowint CSLGame:DrawPool(int bDrawBoom = 0) for(int y=1;y<=poolHeight;+y) CConsole
21、Wnd:GotoXY(1, y); for(int x=1;x<=poolWidth;+x) if(bm_gamepoolyx=0) putchar('.'); else if(bm_gamepoolyx=GMARK_EMPTY) putchar(' '); else if(bm_gamepoolyx>0 && bm_gamepoolyx<=8) putchar('0'+bm_gamepoolyx); Else if(bDrawBoom=0&&(bm_gamepoolyx GMARK_MARK)
22、putchar('#'); else if(bm_gamepoolyx & GMARK_BOOM) if(bDrawBoom) putchar('*'); else putchar('.'); return 0;5掃雷機(jī)器人有10次錯(cuò)誤機(jī)會(huì),執(zhí)行以下循環(huán)函數(shù)if(bm_gamepoolyx & GMARK_BOOM) i+; if(i=10)nRT = EOF; 6.雷方塊的拓展int CSLGame:DFSShowNum(int x, int y) if(0<x && x<=poolWidth) &a
23、mp;&(0<y && y<=poolHeight) && (bm_gamepoolyx=0) int nCount = GetShowNum(x, y); if(nCount=0) bm_gamepoolyx = GMARK_EMPTY; for(int Y=-1;Y<=1;+Y) for(int X=-1;X<=1;+X) DFSShowNum(x+X,y+Y); else bm_gamepoolyx = nCount; return 0; 7. 勝利的判斷與相應(yīng)處理,根據(jù)各種輸入KEY_UP、 KEY_DOWN、 KEY_L
24、EFT、 KEY_RIGHT、 KEY_1、 KEY_2 、KEY_3、 KEY_ESC執(zhí)行操作,通過(guò)返回的nRT來(lái)判斷失敗、勝利或未結(jié)束。/ Game loop, wait and process an input message/ return: 0: not end; 1: Win; otherwise: Lose int CSLGame:WaitMessage() int nKey = CConsoleWnd:GetKey(); int nRT = 0, nArrow = 0; switch (nKey) case KEY_UP: if(curY>1)-curY; nArrow=
25、1; break; case KEY_DOWN: if(curY<poolHeight) +curY; nArrow=1; break; case KEY_LEFT: if(curX>1)-curX; nArrow=1; break; case KEY_RIGHT: if(curX<poolWidth)+curX; nArrow=1; break; case KEY_1: nRT = TryOpen(curX, curY); break; case KEY_2: if(bm_gamepoolcurYcurX & (GMARK_MARK|GMARK_BOOM)=0) b
26、m_gamepoolcurYcurX = GMARK_MARK; break; case KEY_3: if(bm_gamepoolcurYcurX & 0xF) int nb = bm_gamepoolcurYcurX & 0xF; for(int y=-1;y<=1;+y) for(int x=-1;x<=1;+x) if(bm_gamepoolcurY+ycurX+x&GMARK_MARK) -nb; if(nb=0) for(int y=-1;y<=1;+y) for(int x=-1;x<=1;+x) if(bm_gamepoolcur
27、Y+ycurX+x & (0xF|GMARK_MARK) = 0) nRT |= TryOpen(curX+x, curY+y); break; case KEY_ESC: nRT = EOF; break; if(nKey = KEY_1 | nKey = KEY_3) int y=1; for(;y<=poolHeight;+y) int x=1; for(;x<=poolWidth; +x) if(bm_gamepoolyx=0)break; if(x<=poolWidth) break; if(! (y<=poolHeight) nRT = 1; if(
28、nArrow=0) DrawPool(); MoveCursor(); return nRT; 六、測(cè)試數(shù)據(jù)及其結(jié)果分析游戲開(kāi)始頁(yè)面如下:在10次錯(cuò)誤機(jī)會(huì)內(nèi)未獲得游戲勝利,運(yùn)行結(jié)果如下:分析:(1)鍵1,打開(kāi)光標(biāo)所在區(qū)域并顯示其相鄰8個(gè)方向的總雷數(shù)。 (2)判斷某方塊的狀態(tài),若確定其為雷,鍵2,則在此方塊上標(biāo)記,表示此為雷。 (3)判斷已打開(kāi)方塊相鄰8個(gè)方向的方塊狀態(tài),若已顯示的雷數(shù)與此方塊顯示的數(shù)字相等,則在此方塊鍵3,將其相鄰方向未打開(kāi)區(qū)域打開(kāi)。(4)有10次錯(cuò)誤機(jī)會(huì),在10內(nèi)錯(cuò)誤將不顯示游戲失敗信息,只有超過(guò)10次才會(huì)出現(xiàn)游戲失敗的提示信息。七、調(diào)試過(guò)程中的問(wèn)題1.問(wèn)題:在布雷時(shí),如何實(shí)現(xiàn)隨機(jī)分布。解決為題:通過(guò)
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度廣告牌安裝與廣告制作服務(wù)合同模板
- 二零二五年度grc構(gòu)件生產(chǎn)、安裝、售后服務(wù)全面合同
- 資源配置效率評(píng)估-第2篇-洞察及研究
- 衡水高考二模數(shù)學(xué)試卷
- 華東師大版八上數(shù)學(xué)試卷
- 湖南省各地中考模擬數(shù)學(xué)試卷
- 2025-2030中國(guó)海藻提取物行業(yè)發(fā)展分析及投資前景預(yù)測(cè)研究報(bào)告
- 2025-2030中國(guó)水泥熟料和水泥行業(yè)市場(chǎng)發(fā)展趨勢(shì)與前景展望戰(zhàn)略研究報(bào)告
- 2025-2030中國(guó)氣體膨脹溫控器行業(yè)市場(chǎng)發(fā)展趨勢(shì)與前景展望戰(zhàn)略研究報(bào)告
- 2025-2030中國(guó)揚(yáng)琴錘行業(yè)市場(chǎng)發(fā)展趨勢(shì)與前景展望戰(zhàn)略研究報(bào)告
- 園林綠化移樹(shù)合同
- 醫(yī)療機(jī)構(gòu)保潔人員培訓(xùn)
- 企業(yè)員工健康促進(jìn)計(jì)劃的設(shè)計(jì)與實(shí)施
- 助理工程師答辯演示
- 成人失禁相關(guān)性皮炎的預(yù)防與護(hù)理-護(hù)理團(tuán)標(biāo)
- 裝載機(jī)的基礎(chǔ)知識(shí)-裝載機(jī)的結(jié)構(gòu)及儀表
- 現(xiàn)代低壓電器技術(shù) 課件 2. 常見(jiàn)低壓電器
- 浙江天垣新型墻體材料有限公司年產(chǎn)40萬(wàn)立方米ALC板材項(xiàng)目環(huán)境影響報(bào)告
- 《義務(wù)教育物理課程標(biāo)準(zhǔn)》測(cè)試題及答案【共兩套】完整詳細(xì)2022版
- 放射事件應(yīng)急處理預(yù)案牙科
- GSV2.0反恐安全管理手冊(cè)
評(píng)論
0/150
提交評(píng)論