掃雷小程序設(shè)計(jì)_第1頁
掃雷小程序設(shè)計(jì)_第2頁
掃雷小程序設(shè)計(jì)_第3頁
掃雷小程序設(shè)計(jì)_第4頁
掃雷小程序設(shè)計(jì)_第5頁
已閱讀5頁,還剩41頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

掃雷小程序設(shè)計(jì)掃雷小程序設(shè)計(jì)/NUM問題描述與分析問題描述掃地雷是一個廣泛游戲,掃地雷的游戲規(guī)則:掃雷就是要把所有非地雷的格子揭開即勝利;踩到地雷格子就算失敗。當(dāng)鼠標(biāo)點(diǎn)擊到棋盤范圍外時,視為無效,無響應(yīng)。游戲主區(qū)域由很多個方格組成?;疽鬄椋河贸绦蛟O(shè)計(jì)分析思想對選題進(jìn)行分析設(shè)計(jì)用C語言對選題進(jìn)行代碼實(shí)現(xiàn)測試要求為:進(jìn)行系統(tǒng)功能性測試,驗(yàn)證基本功能實(shí)現(xiàn)情況。進(jìn)行邊界測試及特殊數(shù)據(jù)用例測試,驗(yàn)證功能模塊的邏輯分支流程。問題分析仔細(xì)分析課題的要求并粗略分析可以得到大致得到:選擇棋盤的大小(6*6,9*9,11*11)選擇游戲的難度(簡單10%的雷,一般20%的雷,困難30%的雷)繪制一個掃雷的面板。根據(jù)鼠標(biāo)點(diǎn)擊位置確定所點(diǎn)格子位置。判斷格子是否是地雷,若為地雷則游戲結(jié)束。若非地雷顯示周圍8個格子所含地雷總數(shù)。若所有非地雷的格子揭開,則勝利,否則一直循環(huán)進(jìn)行2、3步。

算法設(shè)計(jì)與流程圖算法設(shè)計(jì)掃雷游戲的設(shè)計(jì)可以從三方面進(jìn)行考慮:面板的選擇(BoardChoice)難度的選擇(LevelChoice)游戲主界面(Game)這三方面即為游戲進(jìn)行的過程,大致可以畫出如圖2-1的模塊圖:圖2-1掃雷游戲設(shè)計(jì)的模塊圖面板的選擇在該模塊中,需要決定面板的大小,即每行每列有多少個格子。在設(shè)計(jì)時,個人決定使用6*6,9*9和11*11的格子面板。設(shè)計(jì)中,個人決定設(shè)置3個按鈕分別作為3種面板的選擇。在具體實(shí)現(xiàn)時,需要從兩方面進(jìn)行考慮,即:位置確定和數(shù)據(jù)傳入。位置確定即為確定點(diǎn)擊位置是否有效,確定點(diǎn)擊位置與按鈕的關(guān)系。數(shù)據(jù)傳入即為確定按鈕后,將相應(yīng)的6或9或11載入行列統(tǒng)計(jì)變量ROWANDCOLUMN中。難度的選擇在該模塊中,需要決定面板種雷的個數(shù),面板中應(yīng)包含多少的地雷。在設(shè)計(jì)時,個人決定使用10%,20%和30%的總格子數(shù)作為雷的總個數(shù)。設(shè)計(jì)中,個人決定設(shè)置3個按鈕分別作為3種面板的選擇。在具體實(shí)現(xiàn)時,需要從兩方面進(jìn)行考慮,即:位置確定和數(shù)據(jù)傳入。位置確定即為確定點(diǎn)擊位置是否有效,確定點(diǎn)擊位置與按鈕的關(guān)系。數(shù)據(jù)傳入即為確定按鈕后,將相應(yīng)的雷數(shù)載入變量MINENUM中。游戲主界面游戲主界面的設(shè)計(jì)可以包含圖形的繪制模塊,鼠標(biāo)區(qū)域的獲取模塊,數(shù)據(jù)的生成模塊。各部分包含的內(nèi)容如下:圖形的繪制基礎(chǔ)線條的繪制單個地雷的繪制非雷區(qū)域的數(shù)字輸出游戲結(jié)束后所有雷和數(shù)字的結(jié)果輸出鼠標(biāo)區(qū)域的獲取有效性判斷獲取鼠標(biāo)區(qū)域?qū)⒆鴺?biāo)轉(zhuǎn)換為可以使用的相應(yīng)的數(shù)組數(shù)據(jù)數(shù)據(jù)的生成初始化數(shù)據(jù)隨機(jī)位置設(shè)置雷非雷區(qū)域計(jì)算相應(yīng)數(shù)值流程圖總體流程圖函數(shù)的主流程圖如圖2-2。在該流程圖中,介紹了游戲的三個界面的切換情況,三者為依次展示的狀態(tài),完成前一步驟后方可進(jìn)入下一界面。圖2-2程序的總流程圖面板的選擇的流程圖面板的選擇流程圖如圖2-3。在該流程圖中,介紹了面板大小選擇的流程,主要的部分為界面的繪制過程,鼠標(biāo)點(diǎn)擊區(qū)域的判斷,以及相應(yīng)數(shù)值的賦值。該過程是掃雷游戲的第一個界面。該流程的目的是為了傳入相應(yīng)的參數(shù),使得在游戲主界面時,能夠初始化相應(yīng)數(shù)組以及繪制對應(yīng)的界面。圖2-3面板選擇的流程圖難度的選擇的流程圖難度的選擇流程圖如圖2-4。在該流程圖中,介紹了游戲難度的選擇流程,主要的部分為界面的繪制過程,鼠標(biāo)點(diǎn)擊區(qū)域的判斷,以及相應(yīng)數(shù)值的賦值。該過程是掃雷游戲的第二個界面。過程類似于面板選擇的流程。該流程的目的是為了傳入相應(yīng)的參數(shù),使得在游戲主界面時,能夠初始化相應(yīng)數(shù)組以及繪制對應(yīng)的界面。圖2-4難度選擇的流程圖游戲主界面的流程圖游戲主界面的流程圖如圖2-5。在該流程圖中,主要的操作為繪制相應(yīng)的主界面面板,即多個格子。獲取鼠標(biāo)點(diǎn)擊的位置,而后進(jìn)行儲存數(shù)據(jù)的判斷,雷區(qū)與非雷區(qū)的判斷,游戲是否結(jié)束的判斷等等操作,相應(yīng)的過程如下所示。圖2-5游戲主界面的流程圖

編碼與測試程序編碼程序的編碼部分可以分為四各模塊,即:主函數(shù)的程序部分,面板大小選擇部分,難度選擇部分,游戲主界面部分,每個部分內(nèi)均可以分類編寫,互不干擾,以下為代碼的主要部分,詳細(xì)代碼由于篇幅的限制,可以在附錄中查閱。主函數(shù)程序代碼#include<graphics.h>#include"BoardChoice.h"#include"LevelChoice.h"#include"Game.h"intROWANDCOLUMN;//行列數(shù)intMINENUM;//雷數(shù)intCHESSSIZE;//格子大小intmain(){ BoardChoiceb1;//面板一 b1.main(); LevelChoiceb2;//面板二 b2.main(); Gameb3;//面板三 b3.main(); return0;}面板選擇的類聲明及主要代碼BoardChoice類的聲明classBoardChoice{public: voidmain();//面板控制private: voidDrawBoard();//主界面繪制 voidChoiceClick();//鼠標(biāo)輸入};主要代碼//主界面繪制voidBoardChoice::DrawBoard(){ setcaption("掃雷游戲"); setbkcolor(WHITE); setcolor(BLACK); setfont(25,0,"宋體",0); outtextxy(150,30,"面板選擇"); rectangle(100,80,300,130); rectangle(100,180,300,230); rectangle(100,280,300,330); outtextxy(169,93,"6*6"); outtextxy(169,193,"9*9"); outtextxy(156,293,"11*11");}//鼠標(biāo)輸入voidBoardChoice::ChoiceClick(){ while(true) { mouse_msgm; m=getmouse(); if(m.is_down()&&m.x>100&&m.x<300) { //判斷鼠標(biāo)所處坐標(biāo) if(m.y>80&&m.y<130)//6*6 { ROWANDCOLUMN=6; CHESSSIZE=60; break; } if(m.y>180&&m.y<230)//9*9 { ROWANDCOLUMN=9; CHESSSIZE=50; break; } if(m.y>280&&m.y<330)//9*9 { ROWANDCOLUMN=11; CHESSSIZE=45; break; } } }}難度選擇的類聲明及主要代碼LevelChoice類的聲明classLevelChoice{public: voidmain();//面板控制private: voidDrawBoard();//主界面繪制 voidChoiceClick();//鼠標(biāo)輸入};主要代碼//面板控制voidLevelChoice::main(){ initgraph(400,400); DrawBoard(); ChoiceClick(); closegraph();}voidLevelChoice::ChoiceClick(){ while(true) { mouse_msgm; m=getmouse(); if(m.is_down()&&m.x>100&&m.x<300) { //判斷鼠標(biāo)所處坐標(biāo) if(m.y>80&&m.y<130)//10%的雷 { MINENUM=ROWANDCOLUMN*ROWANDCOLUMN*0.1; break; } if(m.y>180&&m.y<230)//20%的雷 { MINENUM=ROWANDCOLUMN*ROWANDCOLUMN*0.15; break; } if(m.y>280&&m.y<330)//30%的雷 { MINENUM=ROWANDCOLUMN*ROWANDCOLUMN*0.2; break; } } }}游戲主界面的類聲明及主要代碼Game類的聲明classGame{public: voidmain();//面板控制private: voidDrawBoard();//主界面繪制 boolChoiceClick();//鼠標(biāo)輸入 voidDataInital();//數(shù)據(jù)初始化private: voidDrawMine(intx,inty);// 畫一個雷 voidDrawNum(intx,inty,intnum);// 畫一個數(shù)字 voidPrintWhole();//游戲結(jié)束打印所有位置 boolDrawClickArea(intx,inty);//繪制所處位置返回true繼續(xù)//數(shù)組計(jì)算private: voidRandMine();//數(shù)組隨機(jī)布雷 intCalculateMineNum(intx,inty);//計(jì)算指定位置周邊雷個數(shù) voidSetMineNum();//數(shù)組賦值周邊雷個數(shù)//數(shù)據(jù)private: intstatus[11][11];//每個狀態(tài) boolopenStatus[11][11];//是否點(diǎn)擊 intcount;//計(jì)數(shù)器:未按且不是雷};主要代碼//隨機(jī)布雷voidGame::RandMine(){ intn=MINENUM; while(n!=0) { inti=random(ROWANDCOLUMN); intj=random(ROWANDCOLUMN); if(status[i][j]==0)//若無雷則變雷 { status[i][j]=-1; n--; } }}//計(jì)算周邊雷個數(shù)intGame::CalculateMineNum(intx,inty){ intnum=0; if(x-1>=0&&y-1>=0&&status[x-1][y-1]==-1)num++; if(x-1>=0&&status[x-1][y]==-1)num++; if(x-1>=0&&y+1<ROWANDCOLUMN&&status[x-1][y+1]==-1)num++; if(y-1>=0&&status[x][y-1]==-1)num++; if(y+1<ROWANDCOLUMN&&status[x][y+1]==-1)num++; if(x+1<ROWANDCOLUMN&&y-1>=0&&status[x+1][y-1]==-1)num++; if(x+1<ROWANDCOLUMN&&status[x+1][y]==-1)num++; if(x+1<ROWANDCOLUMN&&y+1<ROWANDCOLUMN&&status[x+1][y+1]==-1)num++; returnnum;}//設(shè)置非雷區(qū)的周邊雷統(tǒng)計(jì)值voidGame::SetMineNum(){ for(inti=0;i<ROWANDCOLUMN;i++) { for(intj=0;j<ROWANDCOLUMN;j++) { if(status[i][j]!=-1) { status[i][j]=CalculateMineNum(i,j); } } }}測試結(jié)果本次課程設(shè)計(jì)中要求需要進(jìn)行系統(tǒng)功能性測試,并且驗(yàn)證基本功能實(shí)現(xiàn)情況。同時需要進(jìn)行邊界測試及特殊數(shù)據(jù)用例測試,驗(yàn)證功能模塊的邏輯分支流程。針對這些要求,我做了以下的測試。界面一:面板選擇的相關(guān)測試針對面板一需要進(jìn)行的測試為鼠標(biāo)的相關(guān)測試。面板一可以劃分為以下四個區(qū)域:空白的無效區(qū)域,按鈕一6*6區(qū)域,按鈕二9*9區(qū)域,按鈕三11*11區(qū)域。首先測試的是空白的無效區(qū)域,運(yùn)行程序后,經(jīng)過多次的鼠標(biāo)點(diǎn)擊空白的無效區(qū)域,可以從實(shí)際使用中發(fā)現(xiàn),并沒有任何效果。而后測試三個按鈕區(qū)域。在調(diào)試過程中,可以發(fā)現(xiàn)三個區(qū)域判斷無誤,并且從變量區(qū)中,可以看到?jīng)Q定面板大小的變量ROWANDCOLUMN傳值正確,說明界面一的功能無誤。圖3.1即為面板選擇界面的圖示。圖3-1面板選擇界面的運(yùn)行圖界面二:難度選擇的相關(guān)測試針對面板二同樣需要測試鼠標(biāo)的相關(guān)點(diǎn)擊。具體區(qū)域可以劃分以下四個:空白的無效區(qū)域,按鈕一6*6區(qū)域,按鈕二9*9區(qū)域,按鈕三11*11區(qū)域。首先測試的是空白的無效區(qū)域,運(yùn)行程序后,經(jīng)過多次的鼠標(biāo)點(diǎn)擊空白的無效區(qū)域,在調(diào)試過程中可以發(fā)現(xiàn),鼠標(biāo)位置的傳入正確,數(shù)值參數(shù)無誤。而后測試三個按鈕區(qū)域。在調(diào)試過程中,同樣可以發(fā)現(xiàn)三個區(qū)域判斷無誤,并且從變量區(qū)中,可以看到?jīng)Q定雷數(shù)的百分比根據(jù)10%,20%,30%的比例設(shè)置正確,決定雷數(shù)的變量MINENUM計(jì)算值正確,說明界面二的功能和數(shù)值無誤。圖3-2即為難度選擇界面的圖示。圖3-2難度選擇界面的運(yùn)行圖界面三:主界面的相關(guān)測試在界面三中具體需要測試的內(nèi)容有:面板的繪制是否與預(yù)期相符。雷的布置是否正確以及非雷區(qū)域的周邊雷數(shù)計(jì)算是否正確。鼠標(biāo)點(diǎn)擊的相關(guān)測試。游戲是否結(jié)束的判斷及游戲結(jié)束后的真實(shí)界面公示。首先需要測試面板的繪制是否與預(yù)期相符,這需要查看數(shù)值的傳入對于面板的大小的影響,因而通過多次使用界面一和界面二來初步觀察界面的格子數(shù)字是否與預(yù)期相符。圖3-3至圖3-5為不同選擇下面板的格子數(shù)與格子大小的變化。圖3-3界面為6*6的運(yùn)行初始主界面圖圖3-4界面為9*9的運(yùn)行初始主界面圖圖3-5界面為11*11的運(yùn)行初始主界面圖其次雷的布置以及非雷區(qū)域的周邊雷數(shù)計(jì)算是否正確。以下為6*6以及適中難度下的測試。在調(diào)試過程中,圖3-6為觀察變量區(qū)域status的初始狀態(tài),初始狀態(tài)時各變量均為0,與預(yù)期相符。圖3-7為設(shè)置雷以及非雷區(qū)域的計(jì)算結(jié)果,各變量經(jīng)過檢驗(yàn),均與預(yù)期吻合,測試結(jié)果正確。圖3-6面板6*6適中難度的初始雷區(qū)數(shù)組圖圖3-7面板6*6適中難度的布雷后數(shù)組變量變化圖鼠標(biāo)點(diǎn)擊的相關(guān)測試中需要確認(rèn)的有:未點(diǎn)擊的位置進(jìn)行點(diǎn)擊是否會正確顯示雷或數(shù)字;無效區(qū)域點(diǎn)擊是否會產(chǎn)生未知效果。在實(shí)際檢測中,在點(diǎn)擊空白空格后能夠正常顯示數(shù)字,若點(diǎn)擊范圍為雷區(qū),則正確顯示雷。在點(diǎn)擊無效區(qū)域時,棋盤沒有任何其他效果。在調(diào)試中,數(shù)值的傳入傳出與預(yù)期均相符。鼠標(biāo)點(diǎn)擊的結(jié)果,如圖3-8所示。圖3-8界面為6*6簡單模式的游戲過程圖游戲是否結(jié)束的判斷及面板公示測試過程中,需要從兩方面考慮即:鼠標(biāo)點(diǎn)擊至雷區(qū),游戲失敗結(jié)束,并且打印失敗的信息;所有非雷區(qū)都被點(diǎn)開,游戲勝利,打印獲勝信息。因此從這兩方面單獨(dú)對編寫的程序進(jìn)行測試。圖3-9為6*6面板大小簡單難度下的游戲失敗時的測試結(jié)果,該結(jié)果是用于測試點(diǎn)擊至雷區(qū)后是否游戲真正結(jié)束。在失敗后,正確打印了失敗的提示字符,并且此時鼠標(biāo)點(diǎn)擊任意位置均無效。圖3-10為游戲失敗后的棋盤公示畫面。圖3.11和圖3-12為6*6面板大小簡單難度下的游戲勝利的測試結(jié)果。圖3-11是在游戲過程中顯示各數(shù)字區(qū)域的畫面,圖3.12為游戲勝利之后提示的游戲勝利的畫面。圖3-13為游戲勝利后的棋盤公示畫面。以上測試說明游戲結(jié)束的判斷及面板公示正確。圖3-9界面為6*6簡單模式的游戲失敗圖圖3-10界面為6*6簡單模式的游戲結(jié)果公示圖圖3-11界面為6*6簡單模式的游戲過程圖圖3-12界面為6*6簡單模式的游戲勝利圖圖3-13界面為6*6簡單模式的游戲結(jié)果公示圖

總結(jié)與分析在本次實(shí)驗(yàn)過程中,遇到的最大的問題是掃雷界面的制作以及對雷區(qū)和非雷區(qū)的布置和計(jì)算,即圖形的繪制以及實(shí)際數(shù)據(jù)的生成及匹配。在處理圖形問題的時候我選擇了使用EasyGraphicsEngine的圖形庫,利用里面的函數(shù)來繪制圖形,具體操作時使用rectangle函數(shù)畫矩形,利用line函數(shù)繪制相關(guān)格子的線條,并使用鼠標(biāo)的相關(guān)函數(shù),來獲取鼠標(biāo)點(diǎn)擊的坐標(biāo)點(diǎn),從而且確定范圍的有效性。在處理數(shù)據(jù)以及相關(guān)問題時,我的解決方案是,利用兩組二維數(shù)組來表示所有的格子。第一組二維數(shù)組status用于存放與雷相關(guān)的數(shù)據(jù),若為雷區(qū),則對應(yīng)數(shù)組的位置為-1,其余位置利用自定義的相關(guān)函數(shù)計(jì)算并存放周圍8個區(qū)域所存放的雷的個數(shù)。第二個二維數(shù)組openStatus用于存放鼠標(biāo)是否點(diǎn)擊的信息,若點(diǎn)擊則置1,未點(diǎn)擊則為0。該數(shù)組的作用是,若點(diǎn)擊前位置已被點(diǎn)擊一次,則不展示數(shù)組數(shù)據(jù),且點(diǎn)擊無效;若點(diǎn)擊前未曾點(diǎn)擊,則展示數(shù)組數(shù)據(jù),并將openStatus的相應(yīng)位置置1表示為已點(diǎn)擊。通過上述的幾個構(gòu)思之后,我解決了掃雷小程序設(shè)計(jì)的大部分問題,在后續(xù)的實(shí)現(xiàn)中也更好的解決了相關(guān)的問題,完成了項(xiàng)目設(shè)計(jì)的目標(biāo)。此次實(shí)驗(yàn)中,我收獲了很多。從程序設(shè)計(jì)方面來說,首先需要需求分析,再進(jìn)行總體的規(guī)劃,而后是局部的設(shè)計(jì),最終再到代碼實(shí)現(xiàn),逐層遞進(jìn)的方式,能夠?qū)栴}解決的較為簡便。同時我也學(xué)到了模塊化的思想,在具體完成設(shè)計(jì)的過程中,首先將各個界面相互獨(dú)立,使用對應(yīng)的類進(jìn)行封裝,并分開編寫圖形界面與數(shù)據(jù)的實(shí)現(xiàn)。模塊化的思想能將功能局部分解,簡單實(shí)現(xiàn)。最后還懂得了獨(dú)立測試程序的方式,在測試程序時,需要考慮全面,不僅需要進(jìn)行正確的測試,更要考慮到各種極端的情況,減少一些不易察覺的錯誤。

參考文獻(xiàn)EGE圖形庫主站EasyGraphicsEngine.h,2018.EGE文檔與源代碼./ege-open-source,2018.EGE(EasyGraphicsEngine)15.04./manual,2018.EasyGraphicsEngine基礎(chǔ)教程./category/lesson,2018.譚浩強(qiáng).C++程序設(shè)計(jì)(第3版).北京:清華大學(xué)出版社,2015.嚴(yán)蔚敏,李冬梅,吳偉民.數(shù)據(jù)結(jié)構(gòu)(C語言版第2版).北京:人民郵電出版社,2015.王紅梅,胡明,王濤.數(shù)據(jù)結(jié)構(gòu)(C++版).北京:清華大學(xué)出版社,2011.嚴(yán)蔚敏,陳文博.數(shù)據(jù)結(jié)構(gòu)及應(yīng)用算法教程(修訂版),北京:清華大學(xué)出版社,2011.嚴(yán)蔚敏,陳文博.數(shù)據(jù)結(jié)構(gòu)及應(yīng)用算法教程(修訂版),北京:清華大學(xué)出版社,2011.Decoder.C/C++程序設(shè)計(jì).北京:中國鐵道出版社,2002.譚浩強(qiáng).C++面向?qū)ο蟪绦蛟O(shè)計(jì)(第2版).北京:清華大學(xué)出版社,2014.

附錄必選題題目使用折半插入排序的方法對10個數(shù)進(jìn)行排序,按照要求畫流程圖,給出代碼及結(jié)果截圖。流程圖圖附-1排序算法流程圖程序代碼#include<iostream>usingnamespacestd;voidBInsertSort(int*arr,intlength){ for(inti=1;i<length;i++) { inttemp=arr[i];//需要插入的值存放入temp intlow=0; inthigh=i-1; while(

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論