第一篇:五子棋游戲項目報告
-《軟件技術(shù)基礎(chǔ)》項目報告
《軟件技術(shù)基礎(chǔ)》課程項目報告
項目名稱:用VC++實現(xiàn)的五子棋游戲 專業(yè)班級: G11009
項目成員:崔光浩 程德武 付強 付鈺
李洪潤 尚振興 沈婷玉 佟承雨 周彤姣
指導(dǎo)老師: 殷黎
完成時間: 2011/10/31
-《軟件技術(shù)基礎(chǔ)》項目報告
目錄
摘要
一、需求分析.............................................................................................................1.1 開發(fā)背景................................................................................................................1.2 項目目標(biāo)................................................................................................................1.3 運行環(huán)境................................................................................................................1.4 游戲說明................................................................................................................1.5 項目任務(wù)書............................................................................................................二、技術(shù)路線.......................................................................................................................2.1 總體方案................................................................................................................2.2 詳細(xì)設(shè)計................................................................................................................三、工程進(jìn)度.......................................................................................................................3.1 前期準(zhǔn)備部分(1-3)天.......................................................................................3.2中期實現(xiàn)功能部分(4-7)天................................................................................3.3后期總結(jié)完善部分(8-10)天..............................................................................四、測試報告.....................................................................................................................4.1 第5天:測試棋譜..............................................................................................4.2 第6天:基本功能測試......................................................................................4.3 第7天:悔棋功能..............................................................................................4.4第8天:測試其他的附加功能...........................................................................4.5第9、10天:總體測試.......................................................................................五、個人小結(jié).....................................................................................................................六、主要算法.....................................................................................................................1判斷勝負(fù)..................................................................................................................-《軟件技術(shù)基礎(chǔ)》項目報告
2鼠標(biāo)模擬..................................................................................................................摘要
五子棋是起源于中國古代的傳統(tǒng)黑白棋種之一。現(xiàn)代五子棋日文稱之為“連珠”,英譯為“Renju”,英文稱之為“Gobang”或“FIR”(Five in a Row的縮寫),亦有“連五子”、“五子連”、“串珠”、“五目”、“五目碰”、“五格”等多種稱謂。
五子棋不僅能增強思維能力,提高智力,而且富含哲理,有助于修身養(yǎng)性。五子棋既有現(xiàn)代休閑的明顯特征“短、平、快”,又有古典哲學(xué)的高深學(xué)問“陰陽易理”;它既有簡單易學(xué)的特性,為人民群眾所喜聞樂見,又有深奧的技巧和高水平的國際性比賽;它的棋文化源淵流長,具有東方的神秘和西方的直觀;既有“場”的概念,亦有“點”的連接。它是中西文化的交流點,是古今哲理的結(jié)晶。
-《軟件技術(shù)基礎(chǔ)》項目報告
一、需求分析
1.1 開發(fā)背景
五子棋是一種兩人對弈的純策略型棋類游戲,是起源于中國古代的傳統(tǒng)黑白棋種之一。發(fā)展于日本,流行于歐美。五子棋容易上手,老少皆宜,而且趣味橫生,引人入勝;不僅能增強思維能力,提高智力,而且富含哲理,有助于修身養(yǎng)性。傳統(tǒng)五子棋的棋子分為黑白兩色,采用圍棋棋盤,棋子放置于棋盤線交叉點上。兩人對局,各執(zhí)一色,輪流下一子,先將橫、豎或斜線的5個同色棋子連成不間斷的一排者為勝。
棋類游戲規(guī)則簡單,對外部要求不高,人們可以隨時隨地進(jìn)行對弈。但是,真正能夠精通棋類游戲的人卻不是很多,主要是棋類游戲具有變化莫測的特點,人們經(jīng)常得在棋局上深思熟慮才能找到克敵制勝的辦法。因此,各種棋類游戲都具有開發(fā)智力的效能。在休閑中使自己得到真正的長進(jìn),這或許就是其倍受人們青睞的原因所在!
1.2 項目目標(biāo)
我們將主要通過VC++語言,運用面向?qū)ο蟮某绦蛟O(shè)計方法,開發(fā)此款五子棋游戲。力爭使程序短小精悍,簡潔明了;游戲界面優(yōu)美,容易操作;功能豐富,趣味性強。現(xiàn)在將我們對項目期望實現(xiàn)的目標(biāo)一一介紹: a.能供兩人對弈。
b.可以實現(xiàn)經(jīng)典棋局的回放。c.可以悔棋。
D.能實現(xiàn)棋局步數(shù)的排名。e.操作方便,容易上手。
1.3 運行環(huán)境
本游戲短小精悍,而且對電腦配置的要求均不高,目前幾乎所有的PC機均可運行該游戲。但是為了能讓大家更好地體驗該款游戲,我們給出如下的最低配置:
-《軟件技術(shù)基礎(chǔ)》項目報告
最低配置:CPU1GHz 內(nèi)存 32M 硬盤 4G Windows 95 Microsoft Visual C++ 6.0 同時結(jié)合我們開發(fā)該游戲的環(huán)境,我們強烈推薦用戶使用如下的配置:
最佳配置:CPU2GHz及以上 內(nèi)存256M及以上 硬盤80G及以上 Windows XP及以上 Microsoft Visual C++ 6.0
1.4 游戲說明
(1)游戲流程:
啟動游戲后,顯示主菜單。里面包括開始游戲、讀取游戲、排行榜、關(guān)于游戲、游戲幫助、退出。讀取游戲中包含經(jīng)典棋局的回放和未下完的棋局。排行榜中顯示的是棋局步數(shù)的排名。(2)游戲規(guī)則:
落子:對陣雙方交替落子,任何一方不能多下一步,也不能在已有棋子的地方繼續(xù)落子,否則會有錯誤提示。
贏棋:任何一方先出現(xiàn)在棋盤的橫、縱或斜線上形成連續(xù)的五子,則該方獲勝。排行榜:可以判斷贏者是否可以進(jìn)入排行榜。
(3)特別提示:
? 雙人對弈模式下,悔棋的過程為:首先由玩家向?qū)Ψ桨l(fā)送悔棋請求(悔棋消息),然后由對方?jīng)Q定是否允許玩家悔棋,在玩家得到對方的響應(yīng)消息(允許或者拒絕)之后,才進(jìn)行悔棋與否的操作。
1.5 項目任務(wù)書
(1)班級:G11009(2)組長:崔光浩
(3)成員:尚振興、李洪潤、沈婷玉、程德武、付強、周彤嬌、佟承雨、付鈺(4)項目名稱: 五子棋
-《軟件技術(shù)基礎(chǔ)》項目報告
(5)項目背景:五子棋是起源于中國古代的傳統(tǒng)黑白棋種之一。五子棋不僅能增強思維能力,提高智力,而且富含哲理,有助于修身養(yǎng)性。五子棋既有現(xiàn)代休閑的明顯特征“短、平、快”,又有古典哲學(xué)的高深學(xué)問“陰陽易理”。
(6)項目分工:程德武:顯示棋盤、顯示幫助、游戲版權(quán)、顯示在線幫助文檔。
李洪潤:排行榜全部。
付 強:下棋、經(jīng)典棋局的回放。
沈婷玉:構(gòu)造函數(shù)、初始化所有數(shù)據(jù)、析構(gòu)函數(shù)。
尚振興:負(fù)責(zé)文檔規(guī)劃。
周彤姣:文件的保存和讀取。
付 鈺:技術(shù)支持。
(7)項目進(jìn)度:1-3天:前期準(zhǔn)備,各類資料收集,流程圖,算法等同時完成。4-7天:實現(xiàn)基本功能和附加功能。8-10天:最后測試,最后優(yōu)化。
(各類文檔的設(shè)計與編寫穿插于始終)
-《軟件技術(shù)基礎(chǔ)》項目報告
二、技術(shù)路線
2.1 總體方案
游戲的簡單流程如下圖:
開始開始游戲 讀取游戲排行榜幫助否關(guān)于退出 設(shè)定用戶信息 下棋判斷是否贏是悔棋鼠標(biāo)模擬進(jìn)排行榜否 是否保存保存是認(rèn)輸
2.2 詳細(xì)設(shè)計
a.實現(xiàn)玩家的類Player。其中實現(xiàn)各個成員變量的set和get方法,以及構(gòu)造和析構(gòu)函數(shù)。
b.實現(xiàn)五子棋的類Gobang。其中實現(xiàn)各個功能的函數(shù)如下: 1.開始游戲 :開始、下棋、悔棋、認(rèn)輸、保存 void startGame();2.顯示幫助文檔 void showHelp();3.顯示版權(quán) void showEdition();4.顯示棋盤 void showChessBoard();5.顯示在線在幫助文檔 void showOnlineHelp();
-《軟件技術(shù)基礎(chǔ)》項目報告
6.顯示菜單 void showMenu();7.播放歷史棋局 void movieGoBang();8.讀取排行榜 void setWinnerHome();9.顯示排行榜 void showWinnerHome();10.修改排行榜 void editWinnerHome(Player &player);11.保存歷史記錄、保存經(jīng)典、繼續(xù) int saveHD(char *arr);12.讀取歷史記錄、讀取經(jīng)典、繼續(xù) int loadHD(char *arr);13.鼠標(biāo)模擬 1.void monitor();2.bool agree(int a);14.悔棋 void repent();15.判斷五子連線 bool fun();16.顯示已保存文檔、有經(jīng)典文檔和繼續(xù)文檔 int showSave(int choice);
-《軟件技術(shù)基礎(chǔ)》項目報告
三、工程進(jìn)度
本次作業(yè)歷時十天時間,總的說起來可以分為三個部分:
3.1 前期準(zhǔn)備部分(第1-3天)
主要完成方案的討論、資料的收集、流程圖、算法等前期工作,編寫報告中需求分析的一部分和總體方案的一部分及項目任務(wù)書。
第1天:選定題名,進(jìn)行方案的討論。收集資料,寫出需求分析中的開發(fā)背景部分。第2-3天:商定算法,將軟件總體分塊,寫出項目任務(wù)書。
3.2中期實現(xiàn)功能部分(第4-7天)
主要完成預(yù)先設(shè)想的基本功能和附加功能,完成項目文檔中的技術(shù)路線和需求分析的剩余部分,完成調(diào)試報告中的單功能調(diào)適。
第4天:開始軟件編寫,完成棋盤的設(shè)計部分。完成下棋部分程序的編寫,測試棋盤設(shè)計部分。完成悔棋部分程序的編寫,測試下棋部分程序。
第5-6天:完成兩人對弈部分程序的編寫,測試基本功能,測試悔棋部分。
第7天:完成附加功能,測試對弈部分情況。完善各項功能,測試附加功能。
3.3后期總結(jié)完善部分(第8-10天)
總體功能的調(diào)試改進(jìn),完成項目文檔。
第8天:功能調(diào)試,優(yōu)化軟件。第9-10天:其它報告剩余部分。
0-《軟件技術(shù)基礎(chǔ)》項目報告
四、測試報告
4.1 第4天:測試棋譜
測試人:程德武
測試內(nèi)容:通過VC++語言,我們編寫了基于對話框的游戲界面。我們將測試它的最基本面貌,希望其是符合我們要求的界面模式!
測試過程:運行程序以后,彈出了棋局的對話框,整體棋局呈現(xiàn)白色,棋局右邊和上邊都有一些空出的區(qū)域,這是我們?yōu)閷韺崿F(xiàn)其他附加功能預(yù)留的地方。但是測試過程中我們始終發(fā)現(xiàn)一個問題,棋格的位圖沒有按照我們的設(shè)想正確放置,出現(xiàn)了躍出棋盤的怪現(xiàn)象!
問題解決:通過反復(fù)推敲程序相關(guān)部分,我們覺得可能是算法有疏漏,于是修改了一下算法。我們將每個棋格的位圖封裝了起來,將其位置作為成員數(shù)據(jù)。再運行程序,問題就不再出現(xiàn)了。反復(fù)運行程序再也沒有出現(xiàn)異常情況!
4.2 第5天:基本功能測試
測試人:佟承雨
測試內(nèi)容:程序的基本框架已經(jīng)編好了,希望能按我們的預(yù)期目標(biāo)能實現(xiàn)供兩人對弈功能!
測試過程:將程序編譯、鏈接、運行后,彈出棋局的對話框,然后開始下棋,我們一步一步觀察了每步落子后棋局的變化過程,均與我們預(yù)期的變化過程一樣,我們非常欣喜,這說明我們設(shè)計下棋程序時的算法準(zhǔn)確無誤!
1-《軟件技術(shù)基礎(chǔ)》項目報告
4.3 第6天:悔棋功能
測試人:沈婷玉
測試內(nèi)容: 測試悔棋功能能否正常實現(xiàn)。
測試過程:我們測試了悔棋功能,反復(fù)的測試,此功能運行良好,能夠一步一步悔棋,直到無子可悔,而且通過記錄觀察,每步的悔棋過程均準(zhǔn)確無誤!
4.4第7天:測試其他的附加功能
測試人:李洪潤
測試內(nèi)容:我們對排行榜,經(jīng)典棋局回放功能進(jìn)行了測試
測試過程:我們開始游戲后,正常下棋取得勝利后,程序默認(rèn)將勝方步數(shù)與排行榜中已存在的玩兒家步數(shù)進(jìn)行比較,滿足條件則進(jìn)入排行榜,否則不進(jìn)入。如果是前五次玩的話默認(rèn)都進(jìn)入排行榜。關(guān)于經(jīng)典棋局,進(jìn)入游戲后,載入經(jīng)典棋局,每按一次回車,回放一步,經(jīng)測試無異常。
4.5第8-10天:總體測試
測試人:崔廣浩
測試內(nèi)容:我們將在總體上對程序的運行效果和運行環(huán)境進(jìn)行測試,以完善所有功能,達(dá)到軟件的最優(yōu)化!
測試過程:
首先我們測試了軟件對運行環(huán)境的要求,我們先在Windows xp操作系統(tǒng)中運行了一遍,結(jié)果并無異常情況出現(xiàn);隨后我們在CPU只有1GHz頻率的硬件系統(tǒng)中運行,也并未發(fā)現(xiàn)任何問題!我們基本上可以得出結(jié)論,我們的軟件在一般的軟、硬件環(huán)境下都能正常穩(wěn)定地運行,對機子的配置基本沒有什么要求,適合于廣大的電腦擁有者使用!
2-《軟件技術(shù)基礎(chǔ)》項目報告
五、個人小結(jié)
通過本次五子棋程序的設(shè)計,我想我學(xué)到了很多東西。我主要是負(fù)責(zé)大報告的設(shè)計和編寫,同時也編寫一部分程序。編程的確是非常辛苦,主要是第一次利用VC++編寫程序。我的VC++學(xué)的不是很好,編程時遇到了很多的困難,好在我們班的崔光浩同學(xué)不辭辛苦的幫助我調(diào)試程序,我們參考了很多的資料,像我們《軟件基礎(chǔ)》大作業(yè)中的優(yōu)秀作品,網(wǎng)上的有關(guān)VC++的一些實用的編程技巧,還有一些經(jīng)典的算法。善于利用已有的資源,是我在本次大作業(yè)中學(xué)到得很寶貴的經(jīng)驗,對于網(wǎng)絡(luò),我們懂得了不只要用它來實現(xiàn)低級的聊天、看電影、打游戲等功能,我們還要實現(xiàn)獲取有用的信息、學(xué)習(xí)別人先進(jìn)的方法、查閱相關(guān)的電子資料等功能,充分發(fā)揮它的作用。
我們這次的作品,雖然只是一個比較簡單游戲的實現(xiàn),但是通過這次合作,我也有很大的收獲。雖然是一個小組,但每個人有不同的看問題的方法,我們在做這個軟件的時候,大家也曾有過意見的分歧,我們也曾因為預(yù)期的功能沒有實現(xiàn)而互相指責(zé),也曾為有一點小小的進(jìn)步而欣喜若狂。一路風(fēng)風(fēng)雨雨,我們畢竟是基本完成了預(yù)期的功能,努力沒有白費,心里特別的充實,這就是創(chuàng)造的快樂,也是合作的快樂。我還編寫了大作業(yè)的文檔,由于自身能力的有限,我雖然竭盡全力,但總的感覺還是不能讓我滿意,不過,我也從中學(xué)到了一些東西:
總的說來,這次作業(yè)中我鍛煉了自己的能力,也培養(yǎng)了團(tuán)隊合作的精神,感謝我的隊友!感謝老師!感謝生活!
——尚振興
在本軟件的開發(fā)中,還是有不少地方是不太滿意的,首先我通過單純的VC++語言來實現(xiàn)功能。雖然VC++的強大功能足以應(yīng)付這種軟件的開發(fā)要求了,但是由于控件的缺乏,語法的繁瑣,在實現(xiàn)很多功能的實現(xiàn)中花費了不少力氣。但是由于知識水平的缺乏,無法使用Delphi,flash等更簡便的手段來實現(xiàn)功能,希望以后可以彌補這一點。其次,缺乏完成大工程的經(jīng)驗,沒有建立一個有效可行的工作計劃。在工作中時而通宵奮戰(zhàn),時而停頓不前,既浪費了寶貴的時間,也耗費了大量精力,實在得不償失。
但值得注意的是,在軟件的開發(fā)中,我也學(xué)到了很多書本上學(xué)不到的經(jīng)驗。首先,我使用了別人開發(fā)的思想,雖然開始很不習(xí)慣,但是上手之后就深深的體會到模塊化開發(fā)和面向?qū)ο笳Z言的方便與高效。其次,這次開發(fā)中我使用了很多以前沒接觸過的函數(shù)。除了上網(wǎng)學(xué)習(xí)資料外。熟練的使用老師提供的參考資料,相信對我以后的工作會有很大的益處。
3-《軟件技術(shù)基礎(chǔ)》項目報告
我覺得通過這個小項目很好地考察了每個學(xué)生的知識水平,每個人都發(fā)揮了個人最佳的狀態(tài)。雖然這種形式比普通的卷面考試要難,但是卻能夠充分調(diào)動每個人的積極性去學(xué)習(xí)自己尚未接觸的知識和運用自己已經(jīng)學(xué)過的知識。實驗中,我們小組成員之間配合默契,共同商討問題,使我們在碰到一個一個的問題后,能快速找到相關(guān)的答案。難能可貴的是,在軟件制作最緊張的時候,大家都義無反顧地放棄了一點休息時間,和團(tuán)隊一起堅持奮斗!所以通過這次實驗的合作,我們小組成員之間更加增進(jìn)了了解,增進(jìn)了團(tuán)結(jié)!
——崔光浩
六、主要算法
以下時詳細(xì)算法中提到的主要函數(shù),其他函數(shù)在程序中。
1判斷勝負(fù)
五子棋的勝負(fù),在于判斷棋盤上是否有一個點,從這個點開始的右、下、右下、左下四個方向是否有連續(xù)的五個同色棋子出現(xiàn),判斷勝負(fù)方向如下圖
bool Gobang::fun(int a, int b)//判斷是否五子連棋 {
int arr[8][2]={{-1,-1},{1,1},{-1,0},{1,0},{-1,1},{1,-1},{0,1},{0,-1}};int i;int sum=0;for(i=0;i<8;i+=2)
4-《軟件技術(shù)基礎(chǔ)》項目報告
{
sum=1;int A = a+arr[i][0];int B = b+arr[i][1];while(A>=0 && A<=N && B>=0 && B<=N && chessBoard[A][B]==chessBoard[a][b])
{
} A = a+arr[i+1][0];B = b+arr[i+1][1];while(A>=0 && A<=N && B>=0 && B<=N && A += arr[i][0];B += arr[i][1];sum++;chessBoard[A][B]==chessBoard[a][b])
}
} return false;{
} if(sum>=5)return true;A += arr[i+1][0];B += arr[i+1][1];sum++;
5-《軟件技術(shù)基礎(chǔ)》項目報告
2鼠標(biāo)模擬
void Gobang::monitor(){
char ch = getch();switch(ch){
case 'w': case 'W': getMonitor = 0;break;case 'a': case 'A': getMonitor = 1;break;case 's': case 'S': getMonitor = 2;break;case 'd': case 'D': getMonitor = 3;break;case 'j': case 'J': getMonitor = 4;
6-《軟件技術(shù)基礎(chǔ)》項目報告
}
} break;case 'r': case 'R': getMonitor = 5;break;case 'p': case 'P': getMonitor = 6;break;case 'Q': case 'q': getMonitor = 7;break;default: break;void Gobang::startGame(){
int chose = 1;while(chose){ showChessBoard();monitor();
7-《軟件技術(shù)基礎(chǔ)》項目報告
if(getMonitor==0 && chessBoardMark[0]-1>=0)chessBoardMark[0]--;if(getMonitor==1 && chessBoardMark[1]-1>=0)chessBoardMark[1]--;if(getMonitor==2 && chessBoardMark[0]+1 case 4: //下棋 if(playGoBang(chessBoardMark[0], chessBoardMark[1])==1) if(fun()==true){ system(“cls”); printf(“nnnnn You Win!!nnnnnnnnnn”); remind(); if(historyStep%2==0)else editWinnerHome(player2);editWinnerHome(player1); showWinnerHome();remind(); 8-《軟件技術(shù)基礎(chǔ)》項目報告 } } } } break;case 5: //悔棋 repent();break;case 6: //保存 showSave(1);break;case 7: //退出 chose = 0;break;default: break; 10:10-10:40 區(qū)域游戲 一、活動目標(biāo): 1、新增區(qū)域中幼兒能迅速接受理解新游戲。 2、大膽選擇自己喜歡的游戲材料和游戲內(nèi)容,自主愉快地游戲。 3、能與同伴合作游戲,積極交流自己的想法。 二、活動準(zhǔn)備: 1、經(jīng)驗準(zhǔn)備:知道各區(qū)域的游戲玩法。 2、物質(zhì)準(zhǔn)備:(1)各區(qū)游戲材料如:穿編游戲、飛行棋、小畫板等。 (2)新增游戲區(qū)域材料如:五子棋 3、區(qū)域內(nèi)容: (1)公共區(qū)域:大舞臺、美發(fā)屋等。(2)班級區(qū)域: (3)美食區(qū)(關(guān)東煮):肉串、涮爐等。 美食區(qū)(面包店):面包、披薩等。 美食區(qū)(咖啡店):咖啡機、桌椅等。 動手區(qū)(制作區(qū)):剪刀、雙面膠等。 動手區(qū)(編織區(qū)):編制籃等。 益智區(qū)(好玩的磁鐵):磁鐵、迷宮板等。 益智區(qū)(解鎖):鎖、鑰匙等。 閱讀區(qū):書籍,桌椅等。 三、活動過程: (一)介紹玩法,激發(fā)興趣。 教師:今天我們的益智區(qū)有了新的棋類游戲——五子 棋。 五子棋是中國民間的一種棋類小游戲,十分地簡單,誰先橫排、豎排、斜排列出5個棋子就算獲勝。 (在電腦上下載五子棋的小游戲進(jìn)行演示,并講解。) (二)提出要求,注意安全。 師: 游戲前老師有幾點要求提醒大家。 1、動手區(qū)里做粘貼畫時要注意不要把豆子撒在地上,更不能放進(jìn)鼻子耳朵里。 2、建構(gòu)區(qū)的小朋友在堆擺易拉罐的時候請輕拿輕放。 3、益智區(qū)里初學(xué)五子棋的小朋友遇到問題主動找老師。 4、要和其他小朋友文明交往、合作,學(xué)會謙讓。 5、垃圾放在垃圾桶,不可以隨地亂丟。 小朋友們坐坐好,坐的好的小朋友先插卡進(jìn)區(qū)。 (三)自主進(jìn)區(qū),觀察記錄 1、了解幼兒入?yún)^(qū)的情況,是否全部入?yún)^(qū),情緒如何。 2、關(guān)注各區(qū)域活動情況,教師適當(dāng)加入。 3、仔細(xì)觀察并記錄,給予有困難的幼兒幫助。 4、提醒幼兒遵守游戲規(guī)則,學(xué)會謙讓合作。 (四)重點指導(dǎo)手工區(qū)——五子棋 (五)結(jié)束活動,觀察記錄。整理和收拾 督促幼兒收拾整理,做到輕、快、齊,教師協(xié)助收拾整理。 (六)游戲評價 (1)講解與展示 幼兒自己介紹自己的作品,感受成功后的快樂。 (2)交流與發(fā)現(xiàn) 讓幼兒交流今天的活動,活動中開心的事情和遇到的問題。 (3)小結(jié) 表揚與批評,出示活動中拍攝的照片進(jìn)行點評,提出新要求。 軟件工程設(shè)計 專 業(yè):班 級:姓 名:學(xué) 號:指導(dǎo)老師: I 目錄 第一章 需求分析.......................................................1 1.1 總體分析..........................................................1 1.2 初始化............................................................1 1.3 主循環(huán)控制模塊....................................................1 1.4 玩家下子..........................................................1 1.5 盤面分析填寫棋型表................................................2 1.6 對方下子..........................................................2 1.7 勝負(fù)判斷..........................................................2 第二章 功能描述.......................................................3 2.1 功能模塊圖........................................................3 2.2 功能說明..........................................................3 第三章 系統(tǒng)設(shè)計.......................................................4 3.1 流程圖............................................................4 3.2 流程圖說明........................................................5 第四章 運行結(jié)果.......................................................6 第五章 總結(jié)...........................................................7 附錄一 源代碼.........................................................8 II 軟件工程設(shè)計 五子棋游戲 第一章 需求分析 1.1 總體分析 軟件需求分析是軟件開發(fā)周期的第一個階段,也是關(guān)系到軟件開發(fā)成敗的關(guān)鍵一步。對于任何一個軟件而言,需求分析工作都是至關(guān)重要的一步。只有通過軟件需求分析,才能把軟件的功能和性能由總體的概念性描述轉(zhuǎn)化為具體的規(guī)格說明,進(jìn)而建立軟件開發(fā)的基礎(chǔ)。實踐表明,需求分析工作進(jìn)行得好壞,在很大程度上決定了軟件開發(fā)的成敗。 軟件需求分析的任務(wù)是:讓用戶和開發(fā)者共同明確將要開發(fā)的是一個什么樣的軟件。具體而言,就是通過對問題及其環(huán)境的理解、分析和綜合,建立邏輯模型,完成新軟件的邏輯方案設(shè)計。 基于本游戲,首先得為整個棋盤建立一張表格用以記錄棋子信息,我們使用一個15*15的二維數(shù)組Table[15][15](15*15是五子棋棋盤的大小),數(shù)組的每一個元素對應(yīng)棋盤上的一個交叉點,用‘0’表示空位、‘1’代表己方的子、‘2’代表對方的子;這張表也是今后分析的基礎(chǔ)。在此之后還要為兩個玩家雙方各建立一張棋型表Computer[15][15][4]和Player[15][15][4],用來存放棋型數(shù)據(jù)。 1.2 初始化 首先,建立盤面數(shù)組Table[15][15]、對戰(zhàn)雙方的棋型表Computer[15][15][4]和Player[15][15][4]并將它們清零以備使用;然后初始化顯示器、鍵盤、鼠等輸入輸出設(shè)備并在屏幕上畫出棋盤(棋盤可以不顯示)。 1.3 主循環(huán)控制模塊 控制下棋順序,當(dāng)輪到某方下子時,負(fù)責(zé)將程序轉(zhuǎn)到相應(yīng)的模塊中去,主要擔(dān)當(dāng)一個調(diào)度者的角色。 1.4 玩家下子 當(dāng)輪到玩家下時,您通過鍵盤或鼠標(biāo)在棋盤上落子,程序會根據(jù)該點的位置,在Table[15][15]數(shù)組的相應(yīng)地方記錄‘2’,以表明該子是玩家下的。 軟件工程設(shè)計 1.5 盤面分析填寫棋型表 您在下五子棋時,一定會先根據(jù)棋盤上的情況,找出當(dāng)前最重要的一些點位,如“活三”、“沖四”等;然后再在其中選擇落子點。先來分析己方的棋型,我們從棋盤左上角出發(fā),向右逐行搜索,當(dāng)遇到一個空白點時,以它為中心向左挨個查找,如果遇到己方的子則記錄然后繼續(xù),如果遇到對方的子、空白點或邊界就停止查找。左邊完成后再向右進(jìn)行同樣的操作;最后把左右兩邊的記錄合并起來,得到的數(shù)據(jù)就是該點橫向上的棋型,然后把棋型的編號填入到Computer[x][y][n]中就行了(x、y代表坐標(biāo),n=0、1、2、3分別代表橫、豎、左斜、右斜四個方向)。而其他三個方向的棋型也可用同樣的方法得到,當(dāng)搜索完整張棋盤后,己方棋型表也就填寫完畢了。然后再用同樣的方法填寫對方棋型表。 注意:所有棋型的編號都要事先 定義好,越重要的號數(shù)越大! 1.6 對方下子 有了上面填寫的兩張棋型表,就是遍歷棋型表Computer[15][15][4]和Player[15][15][4]找出其中數(shù)值最大的一點,在該點下子即可。但這種算法的弱點非常明顯,只顧眼前利益,不能顧全大局,這就和許多五子棋初學(xué)者一樣犯了“目光短淺”的毛病。如果在這兒下子將會形成對手不得不防守的棋型(例如:‘沖四’、‘活三’);那么下一步對手就會照您的思路下子來防守您,如此一來便完成了第一步的預(yù)測。這時再調(diào)用模塊4對預(yù)測后的棋進(jìn)行盤面分析,如果出現(xiàn)了‘四三’、‘雙三’或‘雙四’等制勝點,那么己方就可以獲勝了(當(dāng)然對黑棋而言‘雙三’、‘雙四’是禁手,另當(dāng)別論);否則照同樣的方法向下分析,就可預(yù)測出第二步、第三步?? 等一等,要是盤面上沒有對手必須防的棋型,哪該怎么辦呢?進(jìn)攻不成的話就得考慮防守了,將自己和對手調(diào)換一下位置,然后用上面的方法來預(yù)測對手的棋,這樣既可以防住對手巧妙的攻擊,又能待機發(fā)動反擊,何樂而不為呢! 1.7 勝負(fù)判斷 務(wù)須多言,某方形成五子連即獲勝;若黑棋走出‘雙三’、‘雙四’或長連即以禁手判負(fù)。 軟件工程設(shè)計 第二章 功能描述 2.1 功能模塊圖 五子棋游戲判斷棋盤是否已滿判斷是否出錯并提示判斷那方獲勝交替循環(huán)雙方下棋 圖2.1 功能模塊圖 2.2 功能說明 該五子棋程序基本上實現(xiàn)了五子棋的游戲功能,有雙方下棋的界面及最終判定結(jié)果的界面。同時該游戲采用二維坐標(biāo)實現(xiàn),明了易懂,方便玩家在游戲過程中的基本操作,使游戲更加簡便。在細(xì)節(jié)方面,該系統(tǒng)提供實時存儲功能,隨時記錄為完成的游戲,使用戶可以很好的處理意外中斷的情況。該游戲基本實現(xiàn)了游戲的一些要求和特征。在游戲的源程序及文檔方面,我們也嚴(yán)格遵守軟件工程思想,立足實驗要求,確定任務(wù),需求分析,設(shè)計和編碼,每個步驟力求清晰易懂。原代碼注釋詳盡,各功能模塊功能分明,可移植性強。當(dāng)然該系統(tǒng)也有很多不足的地方,第一次進(jìn)行獨立的課程設(shè)計,也有很多細(xì)節(jié)方面是考慮到的,這款游戲也是在不斷的調(diào)試和修改中產(chǎn)生和完善的。希望老師能夠指出不足,幫助我不斷提高。 軟件工程設(shè)計 第三章 系統(tǒng)設(shè)計 3.1 流程圖 開始棋盤已滿是輸出平局否“0”方選位置判斷該位置是否有棋有另找位置無“0”方落子否判斷“0”方是否獲勝是輸出“0”方獲勝否棋盤已滿是輸出平局結(jié)束否“x”方選位置判斷該位置是否有棋有另找位置無“x”方落子判斷“x”方是否獲勝是輸出“x”方獲勝 圖3.1 流程圖 軟件工程設(shè)計 3.2 流程圖說明 本程序定義了各種操作函數(shù)、各種狀態(tài)判定宏,思想明確,思路清晰。各個判斷選擇了不同路徑,因此繼續(xù)進(jìn)行或輸出結(jié)果。程序中,“循環(huán)”的利用非常直接和清晰,雙方交替下棋,因此循環(huán)往復(fù)。最終決出勝負(fù)或最終平局。分析時,也考慮了許多種情況,針對各個情況均作出了相對措施和解決方案。 程序采用循環(huán)進(jìn)行雙方交替下棋,并進(jìn)行了很多判斷。首先判斷棋盤是否已滿,若棋盤已滿,則輸出平局,結(jié)束游戲;若棋盤未滿,則繼續(xù)進(jìn)行。然后判斷“0”方是否勝出,若“0”方獲勝,則輸出“0”方獲勝,結(jié)束游戲;若“0”方?jīng)]有獲勝,則繼續(xù)進(jìn)行。再判斷“x”方是否獲勝,若“x”方獲勝,則輸出“x”方獲勝,結(jié)束游戲;若“x”方?jīng)]有獲勝,則繼續(xù)進(jìn)行。回到“首先”的判斷。如此循環(huán)?? 軟件工程設(shè)計 第四章 運行結(jié)果 圖4.1 運行結(jié)果初始圖 圖4.2 游戲過程圖 圖4.3 軟件工程設(shè)計 圖4.4 圖4.5 軟件工程設(shè)計 圖4.6 圖4.7 軟件工程設(shè)計 圖4.8 游戲進(jìn)行圖 圖4.9 “0”方獲勝圖 軟件工程設(shè)計 附錄一 源代碼 #include using namespace std; int Hsheng(char a[][15]); //判斷o子是否獲勝的函數(shù) int Bsheng(char a[][15]); //判斷x子是否獲勝的函數(shù) int he(char a[][15]); //判斷是否平局(也就是棋盤下滿了)的函數(shù) void qipan(char a[15][15]) //執(zhí)行輸出棋盤命令 { cout<<“本游戲采用二維數(shù)組實現(xiàn),棋盤為15X15的二維直角坐標(biāo)系,均從1到15,祝二位游戲愉快.”;for(int i=0;i<15;i++) //打印棋盤 { for(int j=0;j<15;j++)cout< } } int main(){ char a[15][15]; int x,y; for(int i=0;i<15;i++) for(int j=0;j<15;j++) a[i][j]=' ';qipan(a); while(1)//用循環(huán)語句執(zhí)行o,x交替下子,這些while語句看起來似乎是個死循環(huán)~實際上都會經(jīng)過break結(jié)束 { int a1=1; while(1) { for(;a1;) { cout<<“請輸入o子下的位置:”; //輸入o子的位置 cin>>x>>y;if(a[x][y]=='o'||a[x][y]=='x') //判斷是否已有子 {cout<<“已有子請重下”<<“,”;continue;} else if(x>=15||y>=15){cout<<“輸入錯誤請重輸”<<“,”;continue;} else { a[x][y]='o';a1=0;} } break;} 軟件工程設(shè)計 qipan(a); //下好o子后將棋盤顯示 if(Hsheng(a)) //判斷o子是否已經(jīng)獲勝 {cout<<“o子獲勝”< while(1) //下x子 { cout<<“請輸入x子下的位置:”; cin>>x>>y; if(a[x][y]=='o'||a[x][y]=='x'||x>=15||y>=15) { for(;a[x][y]=='o'||a[x][y]=='x';) { cout<<“已有子請重下”; cout<<“請輸入x子下的位置:”; cin>>x>>y;continue;} for(;x>=15||y>=15||x;) { cout<<“輸入錯誤請重輸”<<“,”; //判斷輸入棋子位置是否正確 cout<<“請輸入x子下的位置:”; cin>>x>>y;continue;} a[x][y]='x';break; } else {a[x][y]='x';break;} } qipan(a); //再一次輸出棋盤 if(Bsheng(a)) //判斷x子是否已經(jīng)獲勝 {cout<<“x子獲勝”< if(he(a)) //判斷是否平局 {cout<<“平局”< } return 0; } int Hsheng(char a[][15]){ int i,j; //判斷橫著的5個是否都相等 for(i=0;i<15;i++) for(j=0;j<15;j++) if(a[i][j]=='o'&&a[i][j+1]=='o'&&a[i][j+2]=='o'&&a[i][j+3]=='o'&&a[i][j+4]=='o') return 1; for(j=0;j<15;j++) //判斷豎著的5個是否都相等 for(i=0;i<15;i++) if(a[i][j]=='o'&&a[i+1][j]=='o'&&a[i+2][j]=='o'&&a[i+3][j]=='o'&&a[i+4][j]=='o') 軟件工程設(shè)計 return 1; for(i=0;i<15;i++) //判斷左斜5個 for(j=0;j<15;j++) if(a[i][j]=='o'&&a[i+1][j+1]=='o'&&a[i+2][j+2]=='o'&&a[i+3][j+3]=='o'&&a[i+4][j+4]=='o') return 1; for(i=0;i<15;i++) //右斜5個 for(j=14;j>3;j--) if(a[i][j]=='H'&&a[i+1][j-1]=='o'&&a[i+2][j-2]=='o'&&a[i+3][j-3]=='o'&&a[i+4][j-4]=='o') return 1; return 0; } int Bsheng(char a[][15]) //同o,只是改字符 { int i,j; for(i=0;i<15;i++) for(j=0;j<15;j++) if(a[i][j]=='x'&&a[i][j+1]=='x'&&a[i][j+2]=='x'&&a[i][j+3]=='x'&&a[i][j+4]=='x') return 1; for(j=0;j<15;j++) for(i=0;i<15;i++) if(a[i][j]=='x'&&a[i+1][j]=='x'&&a[i+2][j]=='x'&&a[i+3][j]=='x'&&a[i+4][j]=='x') return 1; for(i=0;i<15;i++) for(j=0;j<15;j++) if(a[i][j]=='x'&&a[i+1][j+1]=='x'&&a[i+2][j+2]=='x'&&a[i+3][j+3]=='x'&&a[i+4][j+4]=='x') return 1; for(i=0;i<15;i++) for(j=14;j>3;j--) if(a[i][j]=='x'&&a[i+1][j-1]=='x'&&a[i+2][j-2]=='x'&&a[i+3][j-3]=='x'&&a[i+4][j-4]=='x') return 1; return 0; } int he(char a[][15]) { for(int i=0;i<15;i++) for(int j=0;j<15;j++) { if(a[i][j]==' ') //當(dāng)棋盤全部子都不是' '時才能return 1,即棋盤已下滿 return 0; } return 1; } 網(wǎng)絡(luò)092劉礪鋒 設(shè)計一個簡單的五子棋游戲 一、設(shè)計目標(biāo)與內(nèi)容 1.了解Windows編程的基礎(chǔ)知識,掌握MFC應(yīng)用程序的基本知識;2.基本掌握面向?qū)ο蟪绦蛟O(shè)計的基本思路和方法; 3.掌握用VC++開發(fā)應(yīng)用程序的的一般步驟和方法; 4.能夠利用所學(xué)的基本知識, 設(shè)計一個簡單的五子棋游戲,具有以下功能:①數(shù)據(jù)結(jié)構(gòu)的設(shè)計;五子棋棋盤的繪制。②兩人下棋時,兩人下棋算法的設(shè)計。③兩人下棋時,判斷任一方獲勝的算法的設(shè)計。 二、設(shè)計要求 1.用VC++進(jìn)行編碼,實現(xiàn)應(yīng)用程序的功能。注重編碼質(zhì)量,代碼要有適當(dāng)?shù)淖⑨專?/p> 提交設(shè)計報告一份(課程設(shè)計任務(wù)書、目錄、主要的數(shù)據(jù)結(jié)構(gòu)、設(shè)計的基本思路、設(shè)計的步驟及主要代碼、心得體會、參考文獻(xiàn))。總體設(shè)計 運行時效果如下: 網(wǎng)絡(luò)092劉礪鋒 圖3-1 這個程序只能進(jìn)行兩個人之間的對弈,不能進(jìn)行人機對弈,由于時間和個人能力的原因所以人機對弈的算法就沒有寫出。同時程序中也存在著很多漏洞,但基本的功能都已經(jīng)實現(xiàn),還有待繼續(xù)改進(jìn)。 詳細(xì)設(shè)計 ? 新建工程game_wzq 網(wǎng)絡(luò)092劉礪鋒 選擇單文檔應(yīng)用程序,在Step 4 of 6中先中Windows Sockets復(fù)選框。如下圖: 圖3-2 ? 資源編輯 黑白位圖Bitmap以表示棋盤上面的棋子: IDB_BLACK DB_WHITE 黑白鼠標(biāo)Cursor以替換當(dāng)前鼠標(biāo): IDC_CURSOR1 黑棋子 網(wǎng)絡(luò)092劉礪鋒 IDC_CURSOR2 白棋子 黑白圖標(biāo)Icon以顯示在狀態(tài)欄供以提示 IDI_BLACK IDI_WHITE 菜單以供操作: 開始: ID_START 保存: ID_SAVE 打開: ID_OPEN 如下圖所示: 圖3-3 ? 變量函數(shù) 首先,為了實現(xiàn)狀態(tài)欄的應(yīng)用,我們必須更改它的變量: 網(wǎng)絡(luò)092劉礪鋒 在MainFrm.h文件里面,把CStatusBar m_wndStatusBar 為public 接著是在game_wzqView.h文件里面添加變量函數(shù): //兩個鼠標(biāo) HCURSOR hcursorwhite;HCURSOR hcursorblack;//棋盤數(shù)組 int wzq[19][19];// colorwhite TRUE時白棋下,否則黑棋下 bool colorwhite;//棋子位圖 CBitmap m_bmblack;CBitmap m_bmwhite;//保存文件 void Save();//檢查是否結(jié)束 void over(CPoint point);//鼠標(biāo)操作 afx_msg void OnLButtonUp(UINT nFlags, CPoint point);//鼠標(biāo)圖形更換 afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message); 網(wǎng)絡(luò)092劉礪鋒 //菜單的開始 afx_msg void OnStart();//菜單的保存 afx_msg void OnSave();//菜單的打開 afx_msg void OnOpen(); ? 具體實現(xiàn) 1、由于我們的游戲的棋盤大小是一定的,不能改變大小的,是應(yīng)該符合要求的。在如下函數(shù)添加設(shè)置窗口大小的語句: BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs){ if(!CFrameWnd::PreCreateWindow(cs)) return FALSE;// TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs cs.dwExStyle=cs.dwExStyle|WS_EX_TOPMOST;cs.style=WS_SYSMENU|WS_OVERLAPPED|WS_MINIMIZEBOX;//設(shè)置窗口大小:400*340 cs.cx=450;cs.cy=500; 網(wǎng)絡(luò)092劉礪鋒 return TRUE;} 2、初始化變量: 在構(gòu)造函數(shù)里添加初始代碼: CGame_wzqView::CGame_wzqView(){ //Load鼠標(biāo)圖像和棋子位圖 hcursorblack=AfxGetApp()->LoadCursor(IDC_CURSOR1); hcursorwhite=AfxGetApp()->LoadCursor(IDC_CURSOR2);m_bmwhite.LoadBitmap(IDB_WHITE);m_bmblack.LoadBitmap(IDB_BLACK);//清理棋盤 //數(shù)組值為0表示沒有棋子 for(int i=0;i<19;i++)for(int j=0;j<19;j++)wzq[i][j]=0;//白棋先下 colorwhite=true;} 網(wǎng)絡(luò)092劉礪鋒 3、畫棋盤: 在OnDraw(CDC* pDC)函數(shù)中畫棋盤,由于在游戲過程中有可能重畫棋盤,而那時棋盤上面有棋子,所以,我們在這個函數(shù)里面必須有畫棋子的語句。 我們用數(shù)組的做為1表示白棋,-1表示黑棋。void CGame_wzqView::OnDraw(CDC* pDC){ CGame_wzqDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);//畫背景 CBrush mybrush1;mybrush1.CreateSolidBrush(RGB(192,192,192));CRect myrect1(0,0,1200,800);pDC->FillRect(myrect1,&mybrush1);//畫棋盤框線 CPen mypen;CPen*myoldPen; 網(wǎng)絡(luò)092劉礪鋒 mypen.CreatePen(PS_SOLID,1,RGB(0,0,0));myoldPen=pDC->SelectObject(&mypen);for(int i=0;i<19;i++){ pDC->MoveTo(40,40+i*20);pDC->LineTo(400,40+i*20);pDC->MoveTo(40+i*20,40);pDC->LineTo(40+i*20,400);} //重畫時顯示存在的棋子 CDC Dc;if(Dc.CreateCompatibleDC(pDC)==FALSE)AfxMessageBox(“Can't create DC”);for(int n=0;n<19;n++) for(int m=0;m<19;m++) if(wzq[n][m]==1) { //顯示白棋 Dc.SelectObject(m_bmwhite); pDC->BitBlt(n*20+32,m*20+32,160,160,&Dc,0,0,SRCCOPY); 網(wǎng)絡(luò)092劉礪鋒 } else if(wzq[n][m]==-1) { //顯示黑棋 Dc.SelectObject(m_bmblack); pDC->BitBlt(n*20+32,m*20+32,160,160,&Dc,0,0,SRCCOPY); } } 4、設(shè)置鼠標(biāo): 棋盤畫好了,接下來就是下棋了。但鼠標(biāo)并沒有像我們上面說的那樣變成白棋,加函數(shù)如下: BOOL CGame_wzqView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message){ if(nHitTest==HTCLIENT){ //白棋下,顯示白棋鼠標(biāo) if(colorwhite) { //調(diào)用主框架里面的狀態(tài)欄 網(wǎng)絡(luò)092劉礪鋒 CMainFrame *pFrm=(CMainFrame*)AfxGetApp()->m_pMainWnd; CStatusBar*pStatus=&pFrm->m_wndStatusBar; if(pStatus) { pStatus->GetStatusBarCtrl().SetIcon(0,AfxGetApp()->LoadIcon(IDI_WHITE)); pStatus->SetPaneText(0,“白棋下”); } SetCursor(hcursorwhite); } //顯示黑棋鼠標(biāo) else { SetCursor(hcursorblack); CMainFrame*pFrm=(CMainFrame*)AfxGetApp()->m_pMainWnd; CStatusBar*pStatus=&pFrm->m_wndStatusBar; if(pStatus) { 網(wǎng)絡(luò)092劉礪鋒 //顯示圖像 pStatus->GetStatusBarCtrl().SetIcon(0,AfxGetApp()->LoadIcon(IDI_BLACK)); //顯示文字 pStatus->SetPaneText(0,“黑棋下”); } } return 1;} return CView::OnSetCursor(pWnd, nHitTest, message);} 5、下棋操作: 這就涉及到OnLButtonDown(UINT nFlags, CPoint point)和OnLButtonUp(UINT nFlags, CPoint point)兩個函數(shù)了。要用哪一個或用兩個?用Down函數(shù)時是在鼠標(biāo)按下時放下棋子,可是,要是我們按下后意識到按錯了怎么辦;那就改用Up函數(shù),表示當(dāng)鼠標(biāo)鍵松開時放下棋子。OK!添加函數(shù)如下: void CGame_wzqView::OnLButtonUp(UINT nFlags, CPoint 網(wǎng)絡(luò)092劉礪鋒 point){ CView::OnLButtonUp(nFlags, point);CDC *pDC=GetDC();CDC Dc;if(Dc.CreateCompatibleDC(pDC)==FALSE) AfxMessageBox(“Can't create DC”);//是否在棋盤內(nèi) if(point.x>30&&point.x<410&&point.y>30&&point.y<410){ int px=(point.x-30)/20; int py=(point.y-30)/20; //是否已經(jīng)有棋子 if(colorwhite&&wzq[px][py]==0) { Dc.SelectObject(m_bmwhite); pDC->BitBlt(px*20+32,py*20+32,160,160,&Dc,0,0,SRCCOPY); //表示存在白棋 wzq[px][py]=1; //檢查是否結(jié)束 網(wǎng)絡(luò)092劉礪鋒 over(point); //換黑棋下 colorwhite=false; } else if(wzq[px][py]==0) { Dc.SelectObject(m_bmblack); pDC->BitBlt(px*20+32,py*20+32,160,160,&Dc,0,0,SRCCOPY); wzq[px][py]=-1; over(point); colorwhite=true; } } } 由上面可以看出,當(dāng)鼠標(biāo)鍵松開時判斷,如果那個位置沒有棋子,則放下,并把棋盤數(shù)組賦相應(yīng)的值:1或- 16、是否結(jié)束: 網(wǎng)絡(luò)092劉礪鋒 接著是用一個over()函數(shù)判斷是否結(jié)束,是則結(jié)束并重新開始;否則,接著把鼠標(biāo)變成對方棋子,表示對方下棋。那over()函數(shù)又是怎樣的呢? 此函數(shù)是利用剛下棋的位置為中心,檢查它各個方向上的連續(xù)五個棋子是否同色,是則結(jié)束并重新開始。 然而,我們又是怎樣判斷一個方向上的五個棋子的同色的?這就涉及地為什么我要把五子棋數(shù)組賦值為1和-1的問題。因為這樣有一個好處:利用連續(xù)五個棋子的值相加,如果它們的值的絕對值等于5,則說明是同色。當(dāng)然,這只是這樣賦值的一點作用,真正的作用將在后面介紹。添加如下: void CGame_wzqView::over(CPoint point){ //獲取鼠標(biāo)指向數(shù)組位置,即中心位置 int x=(point.x-30)/20;int y=(point.y-30)/20;//計算開始判斷的坐標(biāo) xx,yy int xx,yy;if(x<4)xx=0;else xx=x-4;if(y<4) 網(wǎng)絡(luò)092劉礪鋒 yy=0;else yy=y-4;int i,j,a;//橫向判斷 for(i=xx;i<15;i++){ a=0;for(j=i;j { a=a+wzq[j][y];//五個都是白棋 if(a==5){ AfxMessageBox(“白棋勝!”);//重新開始 OnStart(); return; } //五個都是黑棋 if(a==-5){ 網(wǎng)絡(luò)092劉礪鋒 AfxMessageBox(“黑棋勝!”);OnStart(); return;} } } //豎向判斷 for(i=yy;i<15;i++){ a=0;for(j=i;j return;} if(a==-5) 網(wǎng)絡(luò)092劉礪鋒 { AfxMessageBox(“黑棋勝!”);OnStart(); return;} } } //向右下角 //判斷起點位置 if(x yy=y-x;} else { if(yy==0) xx=x-y;} //參數(shù)over=1時退出循環(huán) int over=0;do 網(wǎng)絡(luò)092劉礪鋒 { a=0; for(i=0;i<5;i++) { if((xx+i)<19||(yy+i)<19) { a=a+wzq[xx+i][yy+i]; if(a==5) { AfxMessageBox(“白棋勝!”); OnStart(); return; } if(a==-5) { AfxMessageBox(“黑棋勝!”); OnStart(); return; } } //到了邊界 else 網(wǎng)絡(luò)092劉礪鋒 over=1; } xx+=1; yy+=1;} while(over==0);//向左下角 if(y>(18-x)){ if(x>13) { yy=y-(18-x); xx=18; } else { yy=y-4; xx=x+4; } } else { 網(wǎng)絡(luò)092劉礪鋒 if(y<5) { xx=x+y; yy=0; } else { yy=y-4; xx=x+4; } } over=0;do { a=0; for(i=0;i<5;i++) { if((xx-i)>=0||(yy+i)<19) { a=a+wzq[xx-i][yy+i]; if(a==5) { 網(wǎng)絡(luò)092劉礪鋒 AfxMessageBox(“白棋勝!”); OnStart(); return; } if(a==-5) { AfxMessageBox(“黑棋勝!”); OnStart(); return; } } //到了邊界 else over=1; } xx-=1; yy+=1;} while(over==0);} 網(wǎng)絡(luò)092劉礪鋒 ? 文件保存和讀取 1、保存文件函數(shù)是一個菜單選項。它的作用就是保存當(dāng)前游戲的狀態(tài)。首先,我們應(yīng)該為我們自己的文件定義一個后綴名:.wzq;接著是打開保存文件的公共對話框,如果確定,則表示保存,那么就先獲取文件名,然后按照一定的順序保存各個點的數(shù)組的值,最后保存當(dāng)前是哪種顏色下棋。void CGame_wzqView::OnSave(){ //設(shè)置保存的文件,后綴名wzq CFileDialog dlg(FALSE,“wzq”,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,“(*.WZQ)|*.wzq|All Files|*.*||”,this);//如果公共類對話框為確定 if(dlg.DoModal()==IDOK)//獲取文件名 dlg.GetFileName();//否則,退出 else return;//字符串變量 CString str;int i,j; 網(wǎng)絡(luò)092劉礪鋒 CStdioFile file;//如果有問題,退出 if(file.Open(dlg.GetFileName(),CFile::modeCreate|CFile::modeWrite|CFile::typeText)==0){ AfxMessageBox(“save error!”); return;} //循環(huán)把棋盤數(shù)組的值寫進(jìn)文件 for(i=0;i<19;i++) for(j=0;j<19;j++) { if(wzq[i][j]==-1) file.WriteString(“-1n”); if(wzq[i][j]==0) file.WriteString(“0n”); if(wzq[i][j]==1) file.WriteString(“1n”); } //保存當(dāng)前下棋顏色 if(colorwhite==true) file.WriteString(“1n”); 網(wǎng)絡(luò)092劉礪鋒 else file.WriteString(“0n”); //關(guān)閉文件 file.Close();} 2、讀文件就是把我們以前保存的文件打開,讀取當(dāng)前打開文件的內(nèi)容,并給數(shù)組賦值使和文件內(nèi)容相同,然后可以繼續(xù)進(jìn)行游戲。 void CGame_wzqView::OnOpen(){ CFileDialog dlg(TRUE,“wzq”,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,“(*.WZQ)|*.wzq|All Files|*.*||”,this);if(dlg.DoModal()==IDOK) dlg.GetFileName();else return;CString str;int i,j,m;CStdioFile file;if(file.Open(dlg.GetFileName(),CFile::modeRead)==0) 網(wǎng)絡(luò)092劉礪鋒 { AfxMessageBox(“open error!”); return;} CArchive ar(&file,CArchive::load);for(i=0;i<19;i++) for(j=0;j<19;j++) { ar.ReadString(str); sscanf(str,“%d”,&m); if(m==-1) wzq[i][j]=-1; if(m==0) wzq[i][j]=0; if(m==1) wzq[i][j]=1; } ar.ReadString(str); sscanf(str,“%d”,&m); if(m==1) colorwhite=true; else 網(wǎng)絡(luò)092劉礪鋒 colorwhite=false; file.Close(); ar.Close(); Invalidate(false);} OK,現(xiàn)在我們的程序已經(jīng)完成了,可以兩個人進(jìn)行對弈了。 4.系統(tǒng)總體設(shè)計與實現(xiàn) 4.1 總體設(shè)計分析 總體設(shè)計是軟件開發(fā)過程中的另一個重要階段,在這一階段中將根據(jù)需求分析中提出的邏輯模型,科學(xué)合理地進(jìn)行物理模型的設(shè)計。這個階段的主要目標(biāo)是將反映用戶信息需求的邏輯方案轉(zhuǎn)換成物理方案,并為下一階段提供必要的技術(shù)資料。 4.1.1 總體設(shè)計原則 (1)整體性:軟件是作為統(tǒng)一整體而存在的。因此,在總體設(shè)計中要從整個軟件的角度進(jìn)行考慮。 (2)靈活性:為保持軟件長久的生命力,要求該手機游戲軟件具有很強的環(huán)境適應(yīng)性。為此,游戲軟件應(yīng)具有較好的開放性和結(jié)構(gòu)的可變性。 (3)可靠性:可靠性是指軟件抵御外界干擾的能力及受外界干擾時的恢復(fù)能力。 (4)經(jīng)濟性:經(jīng)濟性是指在滿足游戲軟件需求的前提下,盡可能地減小游戲軟件的開銷。 4.1.2 軟件模塊總體設(shè)計 軟件中各模塊之間的關(guān)系通常利用層次圖來表示。它是一種一系列多層次的用樹形結(jié)構(gòu)的矩形框描繪數(shù)據(jù)的層次結(jié)構(gòu)框圖。一個單獨的矩形框作為樹形結(jié)構(gòu)的頂層,各個數(shù)據(jù)的子集由下面的各層矩形框代表,最底層的各個矩形框代表組成這個數(shù)據(jù)的實際數(shù)據(jù)元素(不能再分割的元素),它代表完整的數(shù)據(jù)結(jié)構(gòu)。這模式非常適合于需求分析階段的需要,層次方框圖對數(shù)據(jù)結(jié)構(gòu)描繪隨著結(jié)構(gòu)精細(xì)化也越來越詳細(xì)。反復(fù)細(xì)化沿著圖中每條路徑,從對頂層信息的分類開始,直到確定了數(shù)據(jù)結(jié)構(gòu)的全部細(xì)節(jié)為止。 開始游戲重新游戲游戲選項悔棋認(rèn)輸五子棋游戲背景音樂退出游戲先后手設(shè)置游戲設(shè)置棋盤底紋設(shè)置棋盤大小設(shè)置游戲幫助幫助關(guān)于 圖4-1 游戲功能結(jié)構(gòu) 本研究中將游戲軟件分為三大模塊,如圖4-1所示,包括:游戲選項、游戲設(shè)置和幫助。按照在調(diào)研中搜集的資料對每個模塊的功能進(jìn)行編排制作。依據(jù)上述功能的分析,本研究中,將游戲軟件在三大模塊的基礎(chǔ)上又對每一大模塊又分為幾個子模塊: 游戲選項包括六個模塊:開始游戲、重新游戲、悔棋、認(rèn)輸、背景音樂和退出游戲。 游戲設(shè)置包括三個模塊:先后手設(shè)置、棋盤底紋顏色設(shè)置和棋盤大小設(shè)置。 幫助包括兩個模塊:游戲幫助和關(guān)于。 4.2 游戲設(shè)計 4.2.1 游戲前的準(zhǔn)備 本游戲在開發(fā)之前需要做一些前期準(zhǔn)備工作,尤其是對于精通五子棋游戲的Java 游戲開發(fā)者來說。通常情況下,一款運用起來比較熟練地 J2ME 開發(fā)工具 是必不可少的。本游戲使用的是J2ME的簡化開發(fā)工具 Sun Java(TM)Wireless Toolkit 2.5.2 for CLDC,他需先將Java虛擬機安裝調(diào)試好之后才能使用。WTK 2.5.2 不帶有文本編輯功能,所以需要另尋搭配使用。本游戲采用 Ultra Edit 進(jìn)行編輯。本游戲需要幾張后綴名為.png格式的卡通圖,除了一張用作五子棋游戲的 Logo 外,其余的都將在游戲中使用。4.2.2 游戲界面和事件驅(qū)動設(shè)計 游戲的界面設(shè)計采取傳統(tǒng)游戲界面風(fēng)格,如圖4-2所示。游戲設(shè)計中采用傳統(tǒng)界面游戲風(fēng)格,首先啟動游戲,然后進(jìn)入游戲開始界面,界面中放置“設(shè)置”、“開局”、“幫助”、“關(guān)于”四個選項供玩家選擇。其中“設(shè)置”選項主要是對游戲的相關(guān)功能進(jìn)行設(shè)置,如游戲難度設(shè)置。另外還有“悔棋”、“重玩”等項目的設(shè)置。除此之外還包括查看游戲幫助、游戲介紹等。 圖4-2 游戲界面設(shè)計 所謂事件驅(qū)動,簡單地說就是你點什么按鈕(即產(chǎn)生什么事件),電腦執(zhí)行什么操作(即調(diào)用什么函數(shù))。當(dāng)然事件不僅限于用戶的操作。我們知道,事件是事件驅(qū)動的核心自然是。從事件角度說,一個事件收集器、一個事件發(fā)送器和一個事 件處理器組成了事件驅(qū)動程序的基本結(jié)構(gòu)。事件收集器專門負(fù)責(zé)收集包括來自硬件的(如時鐘事件等)、來自用戶的(如鍵盤、鼠標(biāo)事件等)及來自軟件的(如應(yīng)用程序本身、操作系統(tǒng)等)的所有事件。將收集器收集到的事件分發(fā)到目標(biāo)對象中則由事件發(fā)送器負(fù)責(zé)完成。具體的事件響應(yīng)工作則由事件處理器完成,它需要運用虛函數(shù)機制(函數(shù)名取為類似于 Handle Msg 的一個名字),它往往要到實現(xiàn)階段才完全確定。事件處理器對于框架的使用者來說是他們唯一能夠看到的。棋類游戲通常具備兩個重要特性,首先是對戰(zhàn)雙方輪流落子,其次是落子間隔通常是不確定的,尤其是對戰(zhàn)后期,可能每一步棋都要經(jīng)過深思熟慮,無論是人還是計算機,都無法對時間間隔有事先的預(yù)期。基于以上兩個特性,本游戲摒棄了大多數(shù)游戲采用的線程或定時器驅(qū)動游戲的方法,而采用了事件驅(qū)動的方法,即玩家的鍵盤或觸摸筆觸發(fā)游戲的下一個動作。事件驅(qū)動大大減少了不必要的工作量,只有玩家發(fā)出消息時,計算機才啟動運算,而在玩家思考期間,計算機不做任何運算和重繪操作。4.2.3 游戲的類設(shè)計 五子棋游戲?qū)儆诙S棋類游戲,因此可以定義一個 Chesses 類來表示棋子,用一個 Chess 類型的二維數(shù)組來包含棋盤上的所有棋子,對于該棋子玩家的區(qū)分使用Chesses 的 boolean 型的變量 is Player1 來區(qū)分。可以考慮直接生成數(shù)組的每一個對象而不是在數(shù)組建立后,而是把每一個棋子對象(Chesses)放在游戲的進(jìn)行中生成,這主要是考慮到移動設(shè)備的資源有限,盡可能減少系統(tǒng)資源占用。這樣在游戲進(jìn)行時,可以避免還沒有下的棋子在一開始就占用了系統(tǒng)內(nèi)存,玩家每下一步棋,在數(shù)組相應(yīng)位置生成該棋子的對象。 對于游戲中的每一類的設(shè)計,首先就是一個 MIDlet 類,Gobang 類繼承自MIDlet 類,通過方法 start App,pause App,destroy App 來通知游戲的開始,暫停和銷毀結(jié)束,用于連接設(shè)備的應(yīng)用程序管理器(Application Manager)。 本游戲共由7個類組成,它們各自的功能如下: (1)Gobang MIDlet類 負(fù)責(zé)程序的啟動和屏幕之間的切換; (2)Gobang Canvas 類 玩家的對戰(zhàn)平臺,他繼承于 Canvas 類;(3)Setting 類 用于創(chuàng)建游戲的各項設(shè)置參數(shù)表單; (4)Gobang Logic 類 游戲的邏輯類,負(fù)責(zé)勝負(fù)判斷和計算機落子; (5)Dot 類 棋子類,包含了棋子的位置信息;(6)Help 類 游戲的幫助類,包含五子棋的一些常識信息和五子棋教學(xué)內(nèi)容;(7)About類 游戲的關(guān)于類,包含游戲的版本、版權(quán)等信息。各個類之間的關(guān)系如圖4-3所示: 圖4-3游戲類設(shè)計 4.2.4 游戲的流程設(shè)計 對于棋盤界面的更新,游戲進(jìn)行繪制棋子時是按照棋子的二維數(shù)組來完成的,玩家下棋后,設(shè)置is Player1 值,程序修改數(shù)組相應(yīng)位置,然后重新繪制(repaint)。為了使游戲的操作盡可能的簡便,本文設(shè)計上不在游戲進(jìn)入時設(shè)計菜 單,玩家可以直接開始對戰(zhàn),而是在開始游戲的過程中設(shè)置重新開始和退出的按鈕。即一鍵開始,運行即玩,重來或退出都使用一鍵操作。游戲流程的設(shè)計依據(jù)主要是游戲的界面設(shè)計和游戲的類的設(shè)計。游戲啟動時,Gobang MIDlet 對象先顯示游戲的主屏幕,在屏幕下方一側(cè)是出軟鍵(軟鍵指描述抽象客戶端設(shè)備如何顯示),另一側(cè)是用軟件構(gòu)成的菜單,菜單元素主要有“開局”、“游戲設(shè)置”、“游戲幫助”、“關(guān)于”選項。當(dāng)玩家選擇“游戲設(shè)置”軟鍵時,則顯示游戲參數(shù)設(shè)置表單;當(dāng)玩家選擇“開局”軟鍵時,則顯示游戲?qū)?zhàn)主界面;當(dāng)玩家選擇“游戲幫助”軟鍵時,則顯示游戲幫助表單;當(dāng)玩家選擇“關(guān)于”軟鍵時,則顯示游戲關(guān)于表單。玩家進(jìn)入游戲參數(shù)設(shè)置表單,當(dāng)玩家按下“確定”軟鍵時,則確認(rèn)當(dāng)前游戲參數(shù),返回游戲主屏幕;當(dāng)玩家按下“取消”軟鍵時,則放棄此次對游戲的修改,直接返回游戲主屏幕。玩家進(jìn)入游戲?qū)?zhàn)畫布,對戰(zhàn)中畫布有兩個軟鍵,當(dāng)玩家按下“返回主菜單”軟鍵時,則退出游戲到達(dá)游戲主菜單;當(dāng)玩家按下“悔棋”軟鍵時,則進(jìn)行悔棋操作;當(dāng)游戲結(jié)束時,“悔棋”軟鍵被換成了“重玩”軟鍵。玩家進(jìn)入游戲介紹表單,當(dāng)玩家按下“確定”軟鍵時,返回游戲主屏幕。4.2.5 游戲算法的設(shè)計 1、五子棋的獲勝組合 有哪些獲勝組合是在一場五子棋的游戲中計算機必須要知道的,因此,獲勝組合的總數(shù)必須要求得。在本文中我們假定當(dāng)前的棋盤為15*15: (1)每一列的獲勝組合是11,共15列,計算水平方向的獲勝組合數(shù),所以水平方向的獲勝組合數(shù)為:11*15=165。 (2)每一行的獲勝組合是11,共15列,則可計算垂直方向的獲勝組合總數(shù),垂直方向的獲勝組合數(shù)為:11*15=165。 (3)同理,可計算正對角線方向的獲勝組合總數(shù),正對角線上的獲勝組合總數(shù)為11+(10+9+8+7+6+5+4+3+2+1)*2=121。 (4)計算反對角線上的獲勝組合總數(shù)。計算反對角線方向的獲勝組合總數(shù)可計算為11+(10+9+8+7+6+5+4+3+2+1)*2=121。這樣可計算得所有的獲勝組合數(shù)為:165+165+121+121=572。 2、設(shè)計獲勝棋型 通過上面的計算,一個15*15的屋子棋盤在此已經(jīng)計算出了會有572中獲勝方式,因此,我們就可以利用數(shù)組建立一些常規(guī)棋型,棋型的主要作用是: (1)判斷是否有任何一方獲勝; (2)根據(jù)當(dāng)前格局判斷最可能的落子方式。 然而在現(xiàn)實中,高手留給我們的經(jīng)驗就是把握前奏,如“沖四”、“活三”,除了“連五”以外,這些也是同向勝利的捷徑。 3、攻擊與防守 獲勝棋型的算法是中性的,不區(qū)分計算機和玩家,這就涉及到攻擊和防守何者優(yōu)先的問題。而許多高手都認(rèn)為五子棋的根本是“防守”,“攻擊”是靈魂。進(jìn)攻是取勝的手段,是防守的延續(xù)和發(fā)展。許多經(jīng)驗和研究表明,一個棋手只要掌握了全面的、基本的防守原理和技巧,就能和比自己棋力高一個等級的進(jìn)攻型選手對抗,起碼能立于不敗之地。對手進(jìn)過越偏激,則防守的效果越好。沒有進(jìn)攻的防守就像只開花不結(jié)果,沒有實際意義,頑強的防守是反攻的前奏,沒有進(jìn)攻的延續(xù),防守也失去了價值。而這缺一不可。根據(jù)以上原理,計算機在接受最佳的攻擊位置之前,還要計算當(dāng)前玩家的最佳攻擊位置。如果玩家存在最佳攻擊位置,那么計算機就將下一步的棋子擺在玩家的最佳攻擊位置上以阻止玩家的進(jìn)攻,否則計算機便將棋子下在自己的最佳攻擊位置上進(jìn)行攻擊。 4、用到的典型算法(1)坐標(biāo)變換算法 游戲的實質(zhì)其實是對所下棋子的位置進(jìn)行操作和判斷,因此將己方、對方以及棋盤上空點的位置坐標(biāo)存儲在相應(yīng)的List中。我對所下棋子的坐標(biāo)進(jìn)行了處理,因為我所采用的棋盤為15*15,所以棋子橫坐標(biāo)為0到14的整數(shù),縱坐標(biāo)也為0到14的整數(shù)。因此,每次在棋盤上下子之后,計算機在存儲該點的坐標(biāo)時,便要對坐標(biāo)進(jìn)行加工。假設(shè)左上角點為firstPoint,它的實際坐標(biāo)為(x1,y1),而我是將它作為(0,0)存儲的,其它的坐標(biāo),其它點都是以該點為標(biāo)準(zhǔn)進(jìn)行變換的,假設(shè)棋盤上每個格子的寬度為w,某實際點為(x2,y2),變換后的坐標(biāo)為(x,y),x=(x2-x1)/w,y=(y2-y1)/w。 (2)勝負(fù)判斷算法 勝負(fù)判斷的規(guī)則很簡單,就是判斷游戲雙方的棋子在同一條水平線、同一條豎線或是同一條斜線上誰先出現(xiàn)5個連續(xù)的棋子,誰先達(dá)到這樣的目標(biāo),誰就獲得勝利。在本設(shè)計中,是在每次下完一個子后進(jìn)行判斷,看己方是否達(dá)到了勝利的標(biāo)準(zhǔn),若勝利游戲便結(jié)束;否則,游戲繼續(xù)。 (3)人工智能算法 人工智能算法的主體思想分為以下三個步驟: 第一步:根據(jù)雙方的當(dāng)前的形勢循環(huán)地假設(shè)性的分別給自己和對方下一子(在某個范圍內(nèi)下子),并判斷此棋子能帶來的形勢上的變化,如能不能沖4,能不能形成我方或敵方雙3等。 第二步:根據(jù)上一步結(jié)果,組合每一步棋子所帶來的所有結(jié)果(如某一步棋子可能形成我方1個活3,1個沖4(我叫它半活4)等),包括敵方和我方的。 第三步:根據(jù)用戶給的規(guī)則對上一步結(jié)果進(jìn)行排序,并選子(有進(jìn)攻形、防守形規(guī)則)。 5、典型類的具體設(shè)計(1)應(yīng)用程序類 Gobang 類用于連接設(shè)備的應(yīng)用程序管理器(Application Manager),Gobang類繼承自 MIDlet 類,通過 Gobang 類的方法 start App,pause App,destroy App 來通知游戲的開始,暫停和銷毀結(jié)束。源代碼如下: package com.occo.j2me.game.gobang;import javax.microedition.lcdui.Display; import javax.microedition.midlet.MIDlet;public class Gobang extends MIDlet //定義游戲界面的 Canvas 類 Gobang Canvas 的對象 Gobang public { Gobang Canvas gobang;Gobang(){ super(); gobang=new Gobang Canvas(this);//生成 Gobang Canvas 類的對象 gobang } protected void start App(){ Display.get Display(this).set Current(gobang); } protected void pause App(){ } protected void destroy App(boolean arg0){ }} //在屏幕上繪出游戲見面 gobang(2)游戲界面類 Gobang Canvas 類繼承自 Canvas,游戲的核心類是 Gobang Canvas 類,此類將完成游戲的繪圖、互動、控制、邏輯、等所有功能,此類的框架代碼如下: Package com.occo.j2me.game.gobang;import javax.microedition.lcdui.Displayable;import javax.microedition.lcdui.Command;import javax.microedition.lcdui.Canvas; import javax.microedition.lcdui.Command Listener;public Gobang Canvas(Gobang gobang){ this.gobang=gobang; } protected void paint(Graphics g){ } import javax.microedition.lcdui.Graphics;public class Gobang Canvas extends Canvas implements Command Listener{protected Gobang gobang; public Gobang Canvas(){ } }(3)棋子類 整個棋盤是一個 Chesses 類型的二維數(shù)組,棋盤上的每一個棋子都對應(yīng)著一個Chesses 的對象,此類定義了一個棋子,源代碼如下: package com.occo.j2me.game.gobang;public Chesses(){ } public class Chesses {boolean is Player1; public Chesses(boolean is Player1){ this.is Player1=is Player1; }} 4.3 游戲?qū)崿F(xiàn) 4.3.1 主類的實現(xiàn) YpkWuZiQiActivity類是五子棋游戲的主類,同時也是五子棋游戲的入口,它繼承自Activity類。進(jìn)入程序后,首先調(diào)用init()方法,init()方法通過調(diào)用setContentView(R.layout.welcomeview)顯示登錄該游戲的第一個界面。welcomeview.xml是一個布局文件,里面存儲了界面信息。該界面中有四個Button,分別為welButton1、welButton12、welButton3、welButton4,點擊每個Button都會觸發(fā)一個事件,其中點擊welButton1和welButton2還會給它的成員變量FIGHTINGMODE賦值,因為在人人對戰(zhàn)和人機對戰(zhàn)是寫在同一個ChessBoard類中的,所以需要通過FIGHTINGMODE的值來區(qū)分是人人對戰(zhàn)還是人機對戰(zhàn)。 點擊welButton1時,F(xiàn)IGHTINGMODE=1,然后會調(diào)用initTwo()方法,該方法通過調(diào)用setContentView(R.layout.chess)方法,來顯示對戰(zhàn)的界面。chess.xml文件存儲了對戰(zhàn)界面的信息。在chess.xml文件中調(diào)用了ChessBoard類,該類中主要定義了棋盤的信息,下文會對該類做具體的介紹的。在對戰(zhàn)界面中也有四個Button,分別是b1、b2、b3、b4。 首先來介紹一下b2,該Button的功能是返回主頁,調(diào)用init()方法就可以實現(xiàn)。b3的功能是重新開始,這個也只需要調(diào)用initTwo()方法。b3的功能是退出,調(diào)用了系統(tǒng)方法:System.exit(1)。下面重點介紹一下b1,該Button的功能是悔棋。該Button設(shè)定的點擊事件詳細(xì)內(nèi)容如下: b1.setOnClickListener(new OnClickListener(){ public void onClick(View v){ ChessBoard chess =(ChessBoard)findViewById(R.id.chess);Point temp = null;if(chess.whoRun == 1){ if(chess.firstPlayer.getMyPoints().size()>=1 &&chess.secondPlayer!=null){ temp=chess.secondPlayer.getMyPoints().get(chess.secondPlayer.getMyPoints().size()-1); chess.secondPlayer.getMyPoints().remove(temp);chess.freePoints.add(temp);temp=chess.firstPlayer.getMyPoints().get(chess.firstPlayer.getMyPoints().size()-1);chess.firstPlayer.getMyPoints().remove(temp);chess.freePoints.add(temp);chess.freshCanvas(); } } if(chess.whoRun == 2){ if(chess.firstPlayer.getMyPoints().size()>=1 && chess.secondPlayer!=null){ temp=chess.firstPlayer.getMyPoints().get(chess.firstPlayer.getMyPoints().size()-1);chess.firstPlayer.getMyPoints().remove(temp);chess.freePoints.add(temp);temp=chess.secondPlayer.getMyPoints().get(chess.secondPlayer.getMyPoints().size()-1);chess.secondPlayer.getMyPoints().remove(temp);chess.freePoints.add(temp);chess.freshCanvas(); } })首先獲取ChessBoard對象,該對象繼承自View,詳細(xì)的定義了棋盤信息,主要負(fù)責(zé)顯示棋盤的內(nèi)容。接下來判斷一下觸發(fā)悔棋事件的是哪一個玩家,再判斷是否符合悔棋的條件,這個條件很簡單,就是棋盤上至少要有兩個棋子。之后便進(jìn)行悔棋操作,分別將兩個玩家最后下的棋子取出,程序?qū)崿F(xiàn)就是將兩個ArrayList的最后一個元素remove出來,再分別放到記錄棋盤中沒有棋子的點的} } 集合中,最后更新一下畫布,主要是調(diào)用ChessBoard的invalidate()方法。通過以上步驟之后,呈現(xiàn)在我們面前的便是悔完棋的畫面了。 點擊welButton2時,F(xiàn)IGHTINGMODE=2,之后的步驟便會點擊welButton1是相同的了,不同的是,由于對戰(zhàn)模式的改變,從人人對戰(zhàn)變成了人機對戰(zhàn)。 點擊welButton 3時,通 過 initThree() 方 法 調(diào) 用setContentView(R.layout.netchess)方法實現(xiàn)網(wǎng)絡(luò)對戰(zhàn)。詳細(xì)的對戰(zhàn)實現(xiàn)細(xì)節(jié)將會在下文一一介紹。在這個界面中只保留了兩個Button:b2和b4。這兩個Button所實現(xiàn)的功能和上面的b2和b4是相同的。 最后,welButton4比較簡單。它所實現(xiàn)的功能為退出應(yīng)用程序,調(diào)用System.exit(1)方法。4.3.2 游戲設(shè)置類的實現(xiàn) 游戲設(shè)置表單用來對游戲參數(shù)進(jìn)行設(shè)置,包括棋盤大小、先手選擇、智能級別。表單中使用了 Gauge 和 Choice Group 兩種高級用戶界面組件。 1、棋盤尺寸選擇 標(biāo)準(zhǔn)的五子棋棋盤為 15*15,但為了滿足不同玩家的需求,這里提供了大小為10*10 到 20*20 的棋盤,用戶可以通過 Gauge 組件改變。棋盤的最小值為 10,而Gauge 組件的最小值為 0,所以當(dāng)前的 Gauge 值需要角上 10 才是當(dāng)前棋盤大小。創(chuàng)建 Gauge 組件的代碼如下: form = new Form(“ 游戲設(shè)置”);// 創(chuàng)建參數(shù)設(shè)置表單并添加標(biāo)簽 gauge Size = new Gauge(“棋盤規(guī)格: ” + board Size + “ X ” + board Size, true, 10, board Size-10);//棋盤規(guī)格 form.append(gauge Size); 圖4-4 棋盤尺寸的設(shè)計 在Gauge交互模式下可以為Gauge對象所在的表單對象綁定一個Item State Listener 事件監(jiān)聽器,并在監(jiān)聽器上捕捉 Gauge 對象的事件,當(dāng) Gauge 的值發(fā)生變化時就會觸發(fā)事件。這里將根據(jù) Gauge 的當(dāng)前值改變標(biāo)簽,顯示當(dāng)前的棋盤大小。其代碼如下: public void item State Changed(Item item){ if(item == gauge Size)//當(dāng) Gauge 組件發(fā)生變化時 { int bs = gauge Size.get Value()+ 10;//獲取當(dāng)前的 Gauge 值并計算棋盤大小(加10) gauge Size.set Label(“棋盤規(guī)格: ” + bs + “ X ” + bs);//改變 Gauge 組件的標(biāo)簽 } } 2、難度選擇 游戲的難易程度根據(jù)計算機的智能級別來控制,創(chuàng)建及添加選項的方法和復(fù)選框一樣,所不同的是在創(chuàng)建 Choice Group 對象時,類型設(shè)置為 1(單選)。對于單選框,set Selected Index 只能用來指定某個選項被選中,因此,布爾值 selected 的值必然為 true,否則便沒有意義。 游戲共有 3 個難度級別,分別是:拜師學(xué)藝、棋行天下、誰與爭鋒(此游戲中并未作出區(qū)分),初始情況下為拜師學(xué)藝,該選項的索引值為 0。創(chuàng)建難度選擇單選框的代碼如下: level = 1;//默認(rèn)情況下的難度級別 choicelevel = new Choice Group(“電腦智能級別:”, 1);//創(chuàng)建難度級別選項組 choicelevel.append(“拜師學(xué)藝”, null);//難度 1 choicelevel.append(“棋行天下”, null);//難度 2 choicelevel.append(“誰與爭鋒”, null);//難度 3 choicelevel.set Selected Index(level-1 , true);//設(shè)置默認(rèn)情況為難度 1,索引值為0 form.append(choicelevel);//將選項組添加到主表單中 游戲設(shè)置選項表單還有兩個 Command 對象,分別用于玩家卻熱和取消,所以表單需要監(jiān)聽軟鍵事件和組件事件: public class Setting implements Command Listener, Item State Listener 3、棋手選擇 選擇先手和難度等級用 Choice Group 組件來實現(xiàn)。Choice Group 組件用來構(gòu)造選擇框,其構(gòu)造函數(shù)如下: Choice Group(String label, int choice Type)選擇先手的選項框為選擇組件,屬性為復(fù)選框,標(biāo)簽名為空。創(chuàng)建好選擇組件后,逐條添加選項元素。添加選項的方法如下: int append(String string Part, Image image Part)該方法追加一個選項元素到選擇組中,追加的選項為選擇組中的最后一個元素,選擇組的大小加 1。 對于多選類型的 Choice Group,還可以設(shè)置個別選項的選擇狀態(tài)。設(shè)置初始選擇狀態(tài)的方法如下: void set Selected Index(int element Num, Boolean selected)這里創(chuàng)建一個只有一個選項元素的多選框用于玩家設(shè)置是否計算機先行,在默認(rèn)情況下為true,創(chuàng)建完成多選框后將其添加到主表單中,代碼如下: Computer First = true;//在默認(rèn)情況下為計算機先行 choice First = new Choice Group(null, 2);//創(chuàng)建復(fù)選框 choice First.append(“電腦先手”, null);//添加選項元素 choice First.set Selected Index(0, Computer First);//設(shè)置多選框的默認(rèn)狀態(tài) form.append(choice First);//將多選框添加到主表單中 4.3.3 棋子類的實現(xiàn) 1、棋子的行列位置 此五子棋游戲是一個二維棋類游戲,所以定了了一個 Dot 類來表示棋子。由于移動設(shè)備的局限性,所以程序不在下每一步棋時生成一個對象,而是在游戲進(jìn)行時,玩家或者計算機沒下一步棋,在數(shù)組相應(yīng)位置生成該棋子的對象,而將已經(jīng)下過的棋子保存到數(shù)組中隨時檢索,這樣可以避免過多棋子對象占用系統(tǒng)內(nèi)存。Dot 類的 UML 圖如圖 4-5 所示: 圖4-5棋子行列設(shè)計 Dot 類主要有兩個變量 row 和 col,分別表示行和列: public int row;//行 public int col;//列 2、檢查越位 棋子的位置并非是任意的,玩家和計算機每走一步棋之前都要線檢查該位置的合法性,即棋子是否在棋盤上,否則判為無效落子。檢查是否越界的代碼如下: public boolean is In Board(int board Size)//判斷棋子是否越界(超出棋盤){ return row >= 0 && row < board Size && col >= 0 && col < board Size;} 3、修改棋子位置 在創(chuàng)建好 Dot 對象后,Dot 類提供了兩種方法更改棋子位置,包括設(shè)置行列位置和從已有棋子中復(fù)制參數(shù)。 public void set Row Col(int r, int c)//設(shè)置棋子位置 { row = r;col = c; } public void copy From(Dot d)//復(fù)制已有的棋子 { row = d.row; col = d.col; } 4.3.4 對戰(zhàn)邏輯類的實現(xiàn) 1、建立數(shù)據(jù)結(jié)構(gòu) 本程序以數(shù)組保存當(dāng)前盤面的情況,每個位置可能有三種狀態(tài):空、玩家的落子、計算機的落子,分別用 0、1、2 來表示。代碼如下: public static int PLAYER_NONE = 0;//該位置為空 public static int PLAYER_COMPUTER = 1;//該位置有電腦的落子 public static int PLAYER_HUMAN = 2;//該位置有玩家的落子 棋盤在初始情況下為空,即棋子上沒有任何棋子,在Gobang Logic類的構(gòu)造函數(shù)中對棋盤進(jìn)行初始化: table = new int[board Size][board Size];//創(chuàng)建棋盤數(shù)組 for(int r = 0;r < board Size;r++){ for(int c = 0;c < board Size;c++) table[r][c] = 0;//初始化盤面為空 } 除了記錄棋盤上每個位置的落子狀態(tài)外,程序還將對每種狀態(tài)的位置個數(shù)進(jìn)行統(tǒng)計,以對算法進(jìn)行簡化。對三種狀態(tài)的統(tǒng)計存儲在整型數(shù)組中,該數(shù)組為全局變量。 private int player Counter[]; 在 Gobang Logic 類的構(gòu)造函數(shù)中對三種狀態(tài)的計數(shù)進(jìn)行初始化,即棋盤上都是空、計算機的落子或玩家的落子狀態(tài)的個數(shù)為 0,在數(shù)據(jù)結(jié)構(gòu)上,把空也當(dāng)做某一特殊玩家。 初始化代碼如下: player Counter = new int[3];//落子狀態(tài)計數(shù)器 player Counter[0] = board Size * board Size;//整個棋盤都是空的狀態(tài) player Counter[1] = 0;//電腦落子0 player Counter[2] = 0;//玩家落子0 2、落子和悔棋 這里使用了一個 Dot 類棋子對象來記錄最后一步棋的位置,當(dāng)玩家下了一步棋后需要將上一步重新繪制,以消除旗子上的引導(dǎo)框。另外,還是用了堆棧來存儲最近的幾步落子,以便玩家悔棋。 private Dot last Dot;//棋子對象,存儲最后一步落子 private Stack steps;//棋子對象的堆棧 最后一步棋子和棋子堆棧在 Gobang Logic 類的構(gòu)造函數(shù)中進(jìn)行初始化; last Dot = new Dot(board Size);//創(chuàng)建棋子對象用來存儲最后一步棋,初始化 位置為棋盤中央steps = new Stack();//堆棧對象,用來存儲最近的幾部棋在棋盤上落子的代碼如下: private void go At(int row, int col, int player)//電腦或人在 row、col 位置上走 { int last Row = last Dot.row;//記錄上一步的行坐標(biāo) int last Col = last Dot.col;//記錄上一步的列坐標(biāo) table[row][col] = player;//當(dāng)前位置填充玩家代碼 last Dot.set Row Col(row, col);//將這一部設(shè)置為“最后一步” game Canvas.repaint At(last Row, last Col);//重新繪制上一步(將引導(dǎo)框去掉) game Canvas.repaint At(row, col);//繪制當(dāng)前這步 switch(player)//統(tǒng)計雙方落子數(shù)量 { case 1: player Counter[1]++;//電腦的步數(shù) break; case 2: player Counter[2]++;//玩家的步數(shù) break; } player Counter[0]--;//空白的個數(shù) if(steps.size()> 10)//堆棧數(shù)量超過上限(10) steps.remove Element At(0);//清除棧底 steps.push(new Dot(row, col));//將當(dāng)前這步棋子壓入堆棧 } Stack(堆棧類)從 Vector 集成而來,它使用 push()方法進(jìn)入堆棧,需要時使用 pop()方法從堆棧的頂部將其取出。悔棋動作由玩家做出,從數(shù)據(jù)結(jié)構(gòu)來看,是同時后退兩步(將最后兩步棋位置的落子狀態(tài)設(shè)置為空)。 Stack 類的 peek()方法將獲取棧頂對象,但不移。悔棋代碼如下: : public boolean undo()//悔棋 { if(steps.size()>= 3) { Dot d = new Dot();//創(chuàng)建棋子對象 d.copy From((Dot)steps.pop());//從堆棧彈出的棋子中復(fù)制行列位置坐標(biāo) table[d.row][d.col] = 0;//將該位置設(shè)置為空 game Canvas.repaint At(d.row, d.col);//在棋盤上重新繪制該位置 d.copy From((Dot)steps.pop());//從堆棧彈出的棋子中復(fù)制行列位置坐標(biāo) table[d.row][d.col] = 0;//將該位置設(shè)置為空 game Canvas.repaint At(d.row, d.col);//在棋盤上重新繪制該位置 d.copy From((Dot)steps.peek());//獲取棧頂對象,作為最后一步棋存儲 last Dot.copy From(d); game Canvas.repaint At(d.row, d.col);//重新繪制最后一步(添加引導(dǎo)框)return true;//悔棋成功 } else { return false; //悔棋失敗 } } 4.4 本章小結(jié) 本章主要內(nèi)容是游戲的實現(xiàn),包括主類的實現(xiàn),如構(gòu)造函數(shù)、事件處理等,游戲幫助和介紹表單類的實現(xiàn),游戲設(shè)置類的實現(xiàn),如棋盤、選手、難度等,旗子類的實現(xiàn),如棋子行列位置、檢查越界等,對戰(zhàn)邏輯類的實現(xiàn),如落子和悔棋、邏輯運算等的實現(xiàn)。第二篇:區(qū)域游戲五子棋
第三篇:五子棋游戲軟件工程課程設(shè)計
第四篇:MFC課程設(shè)計報告-一個簡單的五子棋游戲(本站推薦)
第五篇:五子棋游戲總體設(shè)計與實現(xiàn)