第一篇:基于C#的網絡五子棋游戲設計
基于C#的網絡五子棋游戲設計
摘 要:文章是應用C#語言來完成網絡五子棋的設計實現,其中完成了網絡五子棋的界面設計、網絡通信類的設計實現,以及游戲勝負的設計實現等主要功能模塊。
關鍵詞:C#;網絡;五子棋
五子棋起源于中國古代的黑白棋種之一,經過多年的一系列變化,使得這一簡單游戲變得復雜化、規范化,最終成為今天的職業連珠五子棋,同時也是一項國際比賽項目。五子棋不僅能增強思維能力,提高智力,并且富有哲理,有助于修身養性;既具有簡單易學的特性,又有深奧的技巧和高水平的國際比賽。而隨著網絡的普及,網絡游戲迅猛發展,一些小型的網絡游戲受到用戶的熱衷,如五子棋、圍棋、象棋等。文章主要應用C#語言完成網絡五子棋游戲的設計實現。網絡五子棋游戲的功能需求
網絡五子棋游戲需要具備如下基本功能:
1.1 該游戲能夠在局域網上運行,游戲雙方具有相同的界面。
1.2 “選擇白棋”或“選擇黑棋”,然后查找局域網中的在線玩家進行連接。
1.3 黑棋先行,黑白棋子交替進行,任何一方不可以連下兩步棋。
1.4 程序能夠判斷哪方獲勝,一旦某方獲勝,程序結束,開始下一局。界面設計
五子棋游戲規定,任何一方棋子落下后是不需要再動的,所以棋盤可以采取一張棋盤圖片,其中方格的大小為20*20像素,黑子和白子也分別使用20*20的圖片。在程序中應用ImageList控件的Draw方法來實現對黑子和白子的管理,即在指定位置顯示指定的圖像。該方法在本程序中的使用格式如下:
public void Draw(Graphics g,int x,int y,int width,int height,int index){ }
監聽類和發送類設計
監聽類主要監聽對方發過來的消息,然后交給信息處理方法DoInformation,該方法會根據不同的消息內容作出相應處理。發送類主要完成數據發送,如客戶IP信息,連接信息,下棋信息,退出信息等信息的發送。其中監聽類的主要功能代碼如下:
private void Listener()//監聽方法
{ try { tcpLisn=new TcpListener(5858); tcpLisn.Start();
while(listenerRun)
{ Socket sk=tcpLisn.AcceptSocket(); tring remote=sk.RemoteEndPoint.ToString();
Byte[] stream=new Byte[80]; int i=sk.Receive(stream);
string msg=System.Text.Encoding.UTF8.GetString(stream);
AddChessEventArgs arg=new AddChessEventArgs();
arg.site=msg; OnAddChess(this,arg)}......發送類的主要功能代碼如下:
public void Send(string stream){ try { TcpClient tcpclt = new TcpClient(obj,5858);
NetworkStream netStream = tcpclt.GetStream();
StreamWriter streamwrite = new StreamWriter(netStream);
streamwrite.Write(stream); streamwrite.Flush();
streamwrite.Close(); tcpclt.Close(); }......4 消息出來方法設計
設計一個信息處理方法DoInformation,用來處理Listener對象收到對方發送過來的消息,該方法會根據字符串中包含的CONN(連接)、SITE(對方下棋)或QUIT(對方退出),來進行相應不同的處理。主要功能代碼如下所示:
public void InformationDo(object sender,AddChessEventArgs e)
{......switch(sp)
{ case “SITE”: x = Convert.ToInt32(sp[1])/ 100;
y = Convert.ToInt32(sp[1])% 100; Point p = new Point(x,y);
if(Convert.ToInt32(sp[2])== 0)
{ str = “white”; type = WHITE; rdoWhite.Enabled = false; }
else { str = “black”; type = BLACK; rdoBlack.Enabled = false;}
AddChess(p,type); DrawNextPlayerMark();......游戲的勝負設計實現
根據五子棋的游戲規則,5個同色棋子先連成一條線的一方獲勝,其中連線方式有四種:橫、豎、左對角線、右對角線。所以在程序設計時,需要以剛下的棋子為中心,分別檢查其所在行、列、左對角線、右對角線四個方向有沒有連成5個同色的棋子。
nt x,y,n,LastPlayer=(nextPlayer==WHITE)?BLACK:WHITE;
n=1; //查看該行有沒有5個同色棋子 y = LastPoint.Y;
for(x = LastPoint.X-1; x >= 0; x--)
{ if(GameBoard[y,x] == LastPlayer)n++; else break; }
for(x = LastPoint.X + 1; x < 15; x++)
{ if(GameBoard[y,x] == LastPlayer)n++; else break; }
if(n >= 5){ WhoWin(LastPlayer); return; }
結束語
網絡五子棋游戲是被廣大用戶熟識的益智小游戲,文章主要應用C#語言來實現了該游戲的界面設計、網絡通信等主要功能框架。
參考文獻
[1]呂尚榕,基于flash的五子棋軟件的設計與實現[D].復旦大學,2012.[2]陳青華.C#網絡開發項目教程[M].電子工業出版社,2012.
第二篇:區域游戲五子棋
10:10-10:40 區域游戲
一、活動目標:
1、新增區域中幼兒能迅速接受理解新游戲。
2、大膽選擇自己喜歡的游戲材料和游戲內容,自主愉快地游戲。
3、能與同伴合作游戲,積極交流自己的想法。
二、活動準備:
1、經驗準備:知道各區域的游戲玩法。
2、物質準備:(1)各區游戲材料如:穿編游戲、飛行棋、小畫板等。
(2)新增游戲區域材料如:五子棋
3、區域內容:
(1)公共區域:大舞臺、美發屋等。(2)班級區域:
(3)美食區(關東煮):肉串、涮爐等。
美食區(面包店):面包、披薩等。
美食區(咖啡店):咖啡機、桌椅等。
動手區(制作區):剪刀、雙面膠等。
動手區(編織區):編制籃等。
益智區(好玩的磁鐵):磁鐵、迷宮板等。
益智區(解鎖):鎖、鑰匙等。
閱讀區:書籍,桌椅等。
三、活動過程:
(一)介紹玩法,激發興趣。
教師:今天我們的益智區有了新的棋類游戲——五子 棋。
五子棋是中國民間的一種棋類小游戲,十分地簡單,誰先橫排、豎排、斜排列出5個棋子就算獲勝。
(在電腦上下載五子棋的小游戲進行演示,并講解。)
(二)提出要求,注意安全。
師:
游戲前老師有幾點要求提醒大家。
1、動手區里做粘貼畫時要注意不要把豆子撒在地上,更不能放進鼻子耳朵里。
2、建構區的小朋友在堆擺易拉罐的時候請輕拿輕放。
3、益智區里初學五子棋的小朋友遇到問題主動找老師。
4、要和其他小朋友文明交往、合作,學會謙讓。
5、垃圾放在垃圾桶,不可以隨地亂丟。
小朋友們坐坐好,坐的好的小朋友先插卡進區。
(三)自主進區,觀察記錄
1、了解幼兒入區的情況,是否全部入區,情緒如何。
2、關注各區域活動情況,教師適當加入。
3、仔細觀察并記錄,給予有困難的幼兒幫助。
4、提醒幼兒遵守游戲規則,學會謙讓合作。
(四)重點指導手工區——五子棋
(五)結束活動,觀察記錄。整理和收拾
督促幼兒收拾整理,做到輕、快、齊,教師協助收拾整理。
(六)游戲評價
(1)講解與展示
幼兒自己介紹自己的作品,感受成功后的快樂。
(2)交流與發現
讓幼兒交流今天的活動,活動中開心的事情和遇到的問題。
(3)小結
表揚與批評,出示活動中拍攝的照片進行點評,提出新要求。
第三篇:五子棋游戲軟件工程課程設計
軟件工程設計
專 業:班 級:姓 名:學 號:指導老師:
I
目錄
第一章 需求分析.......................................................1 1.1 總體分析..........................................................1 1.2 初始化............................................................1 1.3 主循環控制模塊....................................................1 1.4 玩家下子..........................................................1 1.5 盤面分析填寫棋型表................................................2 1.6 對方下子..........................................................2 1.7 勝負判斷..........................................................2 第二章 功能描述.......................................................3 2.1 功能模塊圖........................................................3 2.2 功能說明..........................................................3 第三章 系統設計.......................................................4 3.1 流程圖............................................................4 3.2 流程圖說明........................................................5 第四章 運行結果.......................................................6 第五章 總結...........................................................7 附錄一 源代碼.........................................................8
II
軟件工程設計
五子棋游戲
第一章 需求分析
1.1 總體分析
軟件需求分析是軟件開發周期的第一個階段,也是關系到軟件開發成敗的關鍵一步。對于任何一個軟件而言,需求分析工作都是至關重要的一步。只有通過軟件需求分析,才能把軟件的功能和性能由總體的概念性描述轉化為具體的規格說明,進而建立軟件開發的基礎。實踐表明,需求分析工作進行得好壞,在很大程度上決定了軟件開發的成敗。
軟件需求分析的任務是:讓用戶和開發者共同明確將要開發的是一個什么樣的軟件。具體而言,就是通過對問題及其環境的理解、分析和綜合,建立邏輯模型,完成新軟件的邏輯方案設計。
基于本游戲,首先得為整個棋盤建立一張表格用以記錄棋子信息,我們使用一個15*15的二維數組Table[15][15](15*15是五子棋棋盤的大小),數組的每一個元素對應棋盤上的一個交叉點,用‘0’表示空位、‘1’代表己方的子、‘2’代表對方的子;這張表也是今后分析的基礎。在此之后還要為兩個玩家雙方各建立一張棋型表Computer[15][15][4]和Player[15][15][4],用來存放棋型數據。
1.2 初始化
首先,建立盤面數組Table[15][15]、對戰雙方的棋型表Computer[15][15][4]和Player[15][15][4]并將它們清零以備使用;然后初始化顯示器、鍵盤、鼠等輸入輸出設備并在屏幕上畫出棋盤(棋盤可以不顯示)。
1.3 主循環控制模塊
控制下棋順序,當輪到某方下子時,負責將程序轉到相應的模塊中去,主要擔當一個調度者的角色。
1.4 玩家下子
當輪到玩家下時,您通過鍵盤或鼠標在棋盤上落子,程序會根據該點的位置,在Table[15][15]數組的相應地方記錄‘2’,以表明該子是玩家下的。
軟件工程設計
1.5 盤面分析填寫棋型表
您在下五子棋時,一定會先根據棋盤上的情況,找出當前最重要的一些點位,如“活三”、“沖四”等;然后再在其中選擇落子點。先來分析己方的棋型,我們從棋盤左上角出發,向右逐行搜索,當遇到一個空白點時,以它為中心向左挨個查找,如果遇到己方的子則記錄然后繼續,如果遇到對方的子、空白點或邊界就停止查找。左邊完成后再向右進行同樣的操作;最后把左右兩邊的記錄合并起來,得到的數據就是該點橫向上的棋型,然后把棋型的編號填入到Computer[x][y][n]中就行了(x、y代表坐標,n=0、1、2、3分別代表橫、豎、左斜、右斜四個方向)。而其他三個方向的棋型也可用同樣的方法得到,當搜索完整張棋盤后,己方棋型表也就填寫完畢了。然后再用同樣的方法填寫對方棋型表。
注意:所有棋型的編號都要事先 定義好,越重要的號數越大!
1.6 對方下子
有了上面填寫的兩張棋型表,就是遍歷棋型表Computer[15][15][4]和Player[15][15][4]找出其中數值最大的一點,在該點下子即可。但這種算法的弱點非常明顯,只顧眼前利益,不能顧全大局,這就和許多五子棋初學者一樣犯了“目光短淺”的毛病。如果在這兒下子將會形成對手不得不防守的棋型(例如:‘沖四’、‘活三’);那么下一步對手就會照您的思路下子來防守您,如此一來便完成了第一步的預測。這時再調用模塊4對預測后的棋進行盤面分析,如果出現了‘四三’、‘雙三’或‘雙四’等制勝點,那么己方就可以獲勝了(當然對黑棋而言‘雙三’、‘雙四’是禁手,另當別論);否則照同樣的方法向下分析,就可預測出第二步、第三步??
等一等,要是盤面上沒有對手必須防的棋型,哪該怎么辦呢?進攻不成的話就得考慮防守了,將自己和對手調換一下位置,然后用上面的方法來預測對手的棋,這樣既可以防住對手巧妙的攻擊,又能待機發動反擊,何樂而不為呢!
1.7 勝負判斷
務須多言,某方形成五子連即獲勝;若黑棋走出‘雙三’、‘雙四’或長連即以禁手判負。
軟件工程設計
第二章 功能描述
2.1 功能模塊圖
五子棋游戲判斷棋盤是否已滿判斷是否出錯并提示判斷那方獲勝交替循環雙方下棋 圖2.1 功能模塊圖
2.2 功能說明
該五子棋程序基本上實現了五子棋的游戲功能,有雙方下棋的界面及最終判定結果的界面。同時該游戲采用二維坐標實現,明了易懂,方便玩家在游戲過程中的基本操作,使游戲更加簡便。在細節方面,該系統提供實時存儲功能,隨時記錄為完成的游戲,使用戶可以很好的處理意外中斷的情況。該游戲基本實現了游戲的一些要求和特征。在游戲的源程序及文檔方面,我們也嚴格遵守軟件工程思想,立足實驗要求,確定任務,需求分析,設計和編碼,每個步驟力求清晰易懂。原代碼注釋詳盡,各功能模塊功能分明,可移植性強。當然該系統也有很多不足的地方,第一次進行獨立的課程設計,也有很多細節方面是考慮到的,這款游戲也是在不斷的調試和修改中產生和完善的。希望老師能夠指出不足,幫助我不斷提高。
軟件工程設計
第三章 系統設計
3.1 流程圖
開始棋盤已滿是輸出平局否“0”方選位置判斷該位置是否有棋有另找位置無“0”方落子否判斷“0”方是否獲勝是輸出“0”方獲勝否棋盤已滿是輸出平局結束否“x”方選位置判斷該位置是否有棋有另找位置無“x”方落子判斷“x”方是否獲勝是輸出“x”方獲勝 圖3.1 流程圖
軟件工程設計
3.2 流程圖說明
本程序定義了各種操作函數、各種狀態判定宏,思想明確,思路清晰。各個判斷選擇了不同路徑,因此繼續進行或輸出結果。程序中,“循環”的利用非常直接和清晰,雙方交替下棋,因此循環往復。最終決出勝負或最終平局。分析時,也考慮了許多種情況,針對各個情況均作出了相對措施和解決方案。
程序采用循環進行雙方交替下棋,并進行了很多判斷。首先判斷棋盤是否已滿,若棋盤已滿,則輸出平局,結束游戲;若棋盤未滿,則繼續進行。然后判斷“0”方是否勝出,若“0”方獲勝,則輸出“0”方獲勝,結束游戲;若“0”方沒有獲勝,則繼續進行。再判斷“x”方是否獲勝,若“x”方獲勝,則輸出“x”方獲勝,結束游戲;若“x”方沒有獲勝,則繼續進行?;氐健笆紫取钡呐袛唷H绱搜h??
軟件工程設計
第四章 運行結果
圖4.1 運行結果初始圖
圖4.2 游戲過程圖
圖4.3
軟件工程設計
圖4.4
圖4.5
軟件工程設計
圖4.6
圖4.7
軟件工程設計
圖4.8 游戲進行圖
圖4.9 “0”方獲勝圖
軟件工程設計
附錄一 源代碼
#include
using namespace std;
int Hsheng(char a[][15]);
//判斷o子是否獲勝的函數
int Bsheng(char a[][15]);
//判斷x子是否獲勝的函數
int he(char a[][15]);
//判斷是否平局(也就是棋盤下滿了)的函數
void qipan(char a[15][15])
//執行輸出棋盤命令 {
cout<<“本游戲采用二維數組實現,棋盤為15X15的二維直角坐標系,均從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)//用循環語句執行o,x交替下子,這些while語句看起來似乎是個死循環~實際上都會經過break結束 { 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;} 軟件工程設計 qipan(a); //下好o子后將棋盤顯示 if(Hsheng(a)) //判斷o子是否已經獲勝 {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子是否已經獲勝 {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') 軟件工程設計 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]==' ') //當棋盤全部子都不是' '時才能return 1,即棋盤已下滿 return 0; } return 1; } -《軟件技術基礎》項目報告 《軟件技術基礎》課程項目報告 項目名稱:用VC++實現的五子棋游戲 專業班級: G11009 項目成員:崔光浩 程德武 付強 付鈺 李洪潤 尚振興 沈婷玉 佟承雨 周彤姣 指導老師: 殷黎 完成時間: 2011/10/31 -《軟件技術基礎》項目報告 目錄 摘要 一、需求分析.............................................................................................................1.1 開發背景................................................................................................................1.2 項目目標................................................................................................................1.3 運行環境................................................................................................................1.4 游戲說明................................................................................................................1.5 項目任務書............................................................................................................二、技術路線.......................................................................................................................2.1 總體方案................................................................................................................2.2 詳細設計................................................................................................................三、工程進度.......................................................................................................................3.1 前期準備部分(1-3)天.......................................................................................3.2中期實現功能部分(4-7)天................................................................................3.3后期總結完善部分(8-10)天..............................................................................四、測試報告.....................................................................................................................4.1 第5天:測試棋譜..............................................................................................4.2 第6天:基本功能測試......................................................................................4.3 第7天:悔棋功能..............................................................................................4.4第8天:測試其他的附加功能...........................................................................4.5第9、10天:總體測試.......................................................................................五、個人小結.....................................................................................................................六、主要算法.....................................................................................................................1判斷勝負..................................................................................................................-《軟件技術基礎》項目報告 2鼠標模擬..................................................................................................................摘要 五子棋是起源于中國古代的傳統黑白棋種之一。現代五子棋日文稱之為“連珠”,英譯為“Renju”,英文稱之為“Gobang”或“FIR”(Five in a Row的縮寫),亦有“連五子”、“五子連”、“串珠”、“五目”、“五目碰”、“五格”等多種稱謂。 五子棋不僅能增強思維能力,提高智力,而且富含哲理,有助于修身養性。五子棋既有現代休閑的明顯特征“短、平、快”,又有古典哲學的高深學問“陰陽易理”;它既有簡單易學的特性,為人民群眾所喜聞樂見,又有深奧的技巧和高水平的國際性比賽;它的棋文化源淵流長,具有東方的神秘和西方的直觀;既有“場”的概念,亦有“點”的連接。它是中西文化的交流點,是古今哲理的結晶。 -《軟件技術基礎》項目報告 一、需求分析 1.1 開發背景 五子棋是一種兩人對弈的純策略型棋類游戲,是起源于中國古代的傳統黑白棋種之一。發展于日本,流行于歐美。五子棋容易上手,老少皆宜,而且趣味橫生,引人入勝;不僅能增強思維能力,提高智力,而且富含哲理,有助于修身養性。傳統五子棋的棋子分為黑白兩色,采用圍棋棋盤,棋子放置于棋盤線交叉點上。兩人對局,各執一色,輪流下一子,先將橫、豎或斜線的5個同色棋子連成不間斷的一排者為勝。 棋類游戲規則簡單,對外部要求不高,人們可以隨時隨地進行對弈。但是,真正能夠精通棋類游戲的人卻不是很多,主要是棋類游戲具有變化莫測的特點,人們經常得在棋局上深思熟慮才能找到克敵制勝的辦法。因此,各種棋類游戲都具有開發智力的效能。在休閑中使自己得到真正的長進,這或許就是其倍受人們青睞的原因所在! 1.2 項目目標 我們將主要通過VC++語言,運用面向對象的程序設計方法,開發此款五子棋游戲。力爭使程序短小精悍,簡潔明了;游戲界面優美,容易操作;功能豐富,趣味性強。現在將我們對項目期望實現的目標一一介紹: a.能供兩人對弈。 b.可以實現經典棋局的回放。c.可以悔棋。 D.能實現棋局步數的排名。e.操作方便,容易上手。 1.3 運行環境 本游戲短小精悍,而且對電腦配置的要求均不高,目前幾乎所有的PC機均可運行該游戲。但是為了能讓大家更好地體驗該款游戲,我們給出如下的最低配置: -《軟件技術基礎》項目報告 最低配置:CPU1GHz 內存 32M 硬盤 4G Windows 95 Microsoft Visual C++ 6.0 同時結合我們開發該游戲的環境,我們強烈推薦用戶使用如下的配置: 最佳配置:CPU2GHz及以上 內存256M及以上 硬盤80G及以上 Windows XP及以上 Microsoft Visual C++ 6.0 1.4 游戲說明 (1)游戲流程: 啟動游戲后,顯示主菜單。里面包括開始游戲、讀取游戲、排行榜、關于游戲、游戲幫助、退出。讀取游戲中包含經典棋局的回放和未下完的棋局。排行榜中顯示的是棋局步數的排名。(2)游戲規則: 落子:對陣雙方交替落子,任何一方不能多下一步,也不能在已有棋子的地方繼續落子,否則會有錯誤提示。 贏棋:任何一方先出現在棋盤的橫、縱或斜線上形成連續的五子,則該方獲勝。排行榜:可以判斷贏者是否可以進入排行榜。 (3)特別提示: ? 雙人對弈模式下,悔棋的過程為:首先由玩家向對方發送悔棋請求(悔棋消息),然后由對方決定是否允許玩家悔棋,在玩家得到對方的響應消息(允許或者拒絕)之后,才進行悔棋與否的操作。 1.5 項目任務書 (1)班級:G11009(2)組長:崔光浩 (3)成員:尚振興、李洪潤、沈婷玉、程德武、付強、周彤嬌、佟承雨、付鈺(4)項目名稱: 五子棋 -《軟件技術基礎》項目報告 (5)項目背景:五子棋是起源于中國古代的傳統黑白棋種之一。五子棋不僅能增強思維能力,提高智力,而且富含哲理,有助于修身養性。五子棋既有現代休閑的明顯特征“短、平、快”,又有古典哲學的高深學問“陰陽易理”。 (6)項目分工:程德武:顯示棋盤、顯示幫助、游戲版權、顯示在線幫助文檔。 李洪潤:排行榜全部。 付 強:下棋、經典棋局的回放。 沈婷玉:構造函數、初始化所有數據、析構函數。 尚振興:負責文檔規劃。 周彤姣:文件的保存和讀取。 付 鈺:技術支持。 (7)項目進度:1-3天:前期準備,各類資料收集,流程圖,算法等同時完成。4-7天:實現基本功能和附加功能。8-10天:最后測試,最后優化。 (各類文檔的設計與編寫穿插于始終) -《軟件技術基礎》項目報告 二、技術路線 2.1 總體方案 游戲的簡單流程如下圖: 開始開始游戲 讀取游戲排行榜幫助否關于退出 設定用戶信息 下棋判斷是否贏是悔棋鼠標模擬進排行榜否 是否保存保存是認輸 2.2 詳細設計 a.實現玩家的類Player。其中實現各個成員變量的set和get方法,以及構造和析構函數。 b.實現五子棋的類Gobang。其中實現各個功能的函數如下: 1.開始游戲 :開始、下棋、悔棋、認輸、保存 void startGame();2.顯示幫助文檔 void showHelp();3.顯示版權 void showEdition();4.顯示棋盤 void showChessBoard();5.顯示在線在幫助文檔 void showOnlineHelp(); -《軟件技術基礎》項目報告 6.顯示菜單 void showMenu();7.播放歷史棋局 void movieGoBang();8.讀取排行榜 void setWinnerHome();9.顯示排行榜 void showWinnerHome();10.修改排行榜 void editWinnerHome(Player &player);11.保存歷史記錄、保存經典、繼續 int saveHD(char *arr);12.讀取歷史記錄、讀取經典、繼續 int loadHD(char *arr);13.鼠標模擬 1.void monitor();2.bool agree(int a);14.悔棋 void repent();15.判斷五子連線 bool fun();16.顯示已保存文檔、有經典文檔和繼續文檔 int showSave(int choice); -《軟件技術基礎》項目報告 三、工程進度 本次作業歷時十天時間,總的說起來可以分為三個部分: 3.1 前期準備部分(第1-3天) 主要完成方案的討論、資料的收集、流程圖、算法等前期工作,編寫報告中需求分析的一部分和總體方案的一部分及項目任務書。 第1天:選定題名,進行方案的討論。收集資料,寫出需求分析中的開發背景部分。第2-3天:商定算法,將軟件總體分塊,寫出項目任務書。 3.2中期實現功能部分(第4-7天) 主要完成預先設想的基本功能和附加功能,完成項目文檔中的技術路線和需求分析的剩余部分,完成調試報告中的單功能調適。 第4天:開始軟件編寫,完成棋盤的設計部分。完成下棋部分程序的編寫,測試棋盤設計部分。完成悔棋部分程序的編寫,測試下棋部分程序。 第5-6天:完成兩人對弈部分程序的編寫,測試基本功能,測試悔棋部分。 第7天:完成附加功能,測試對弈部分情況。完善各項功能,測試附加功能。 3.3后期總結完善部分(第8-10天) 總體功能的調試改進,完成項目文檔。 第8天:功能調試,優化軟件。第9-10天:其它報告剩余部分。 0-《軟件技術基礎》項目報告 四、測試報告 4.1 第4天:測試棋譜 測試人:程德武 測試內容:通過VC++語言,我們編寫了基于對話框的游戲界面。我們將測試它的最基本面貌,希望其是符合我們要求的界面模式! 測試過程:運行程序以后,彈出了棋局的對話框,整體棋局呈現白色,棋局右邊和上邊都有一些空出的區域,這是我們為將來實現其他附加功能預留的地方。但是測試過程中我們始終發現一個問題,棋格的位圖沒有按照我們的設想正確放置,出現了躍出棋盤的怪現象! 問題解決:通過反復推敲程序相關部分,我們覺得可能是算法有疏漏,于是修改了一下算法。我們將每個棋格的位圖封裝了起來,將其位置作為成員數據。再運行程序,問題就不再出現了。反復運行程序再也沒有出現異常情況! 4.2 第5天:基本功能測試 測試人:佟承雨 測試內容:程序的基本框架已經編好了,希望能按我們的預期目標能實現供兩人對弈功能! 測試過程:將程序編譯、鏈接、運行后,彈出棋局的對話框,然后開始下棋,我們一步一步觀察了每步落子后棋局的變化過程,均與我們預期的變化過程一樣,我們非常欣喜,這說明我們設計下棋程序時的算法準確無誤! 1-《軟件技術基礎》項目報告 4.3 第6天:悔棋功能 測試人:沈婷玉 測試內容: 測試悔棋功能能否正常實現。 測試過程:我們測試了悔棋功能,反復的測試,此功能運行良好,能夠一步一步悔棋,直到無子可悔,而且通過記錄觀察,每步的悔棋過程均準確無誤! 4.4第7天:測試其他的附加功能 測試人:李洪潤 測試內容:我們對排行榜,經典棋局回放功能進行了測試 測試過程:我們開始游戲后,正常下棋取得勝利后,程序默認將勝方步數與排行榜中已存在的玩兒家步數進行比較,滿足條件則進入排行榜,否則不進入。如果是前五次玩的話默認都進入排行榜。關于經典棋局,進入游戲后,載入經典棋局,每按一次回車,回放一步,經測試無異常。 4.5第8-10天:總體測試 測試人:崔廣浩 測試內容:我們將在總體上對程序的運行效果和運行環境進行測試,以完善所有功能,達到軟件的最優化! 測試過程: 首先我們測試了軟件對運行環境的要求,我們先在Windows xp操作系統中運行了一遍,結果并無異常情況出現;隨后我們在CPU只有1GHz頻率的硬件系統中運行,也并未發現任何問題!我們基本上可以得出結論,我們的軟件在一般的軟、硬件環境下都能正常穩定地運行,對機子的配置基本沒有什么要求,適合于廣大的電腦擁有者使用! 2-《軟件技術基礎》項目報告 五、個人小結 通過本次五子棋程序的設計,我想我學到了很多東西。我主要是負責大報告的設計和編寫,同時也編寫一部分程序。編程的確是非常辛苦,主要是第一次利用VC++編寫程序。我的VC++學的不是很好,編程時遇到了很多的困難,好在我們班的崔光浩同學不辭辛苦的幫助我調試程序,我們參考了很多的資料,像我們《軟件基礎》大作業中的優秀作品,網上的有關VC++的一些實用的編程技巧,還有一些經典的算法。善于利用已有的資源,是我在本次大作業中學到得很寶貴的經驗,對于網絡,我們懂得了不只要用它來實現低級的聊天、看電影、打游戲等功能,我們還要實現獲取有用的信息、學習別人先進的方法、查閱相關的電子資料等功能,充分發揮它的作用。 我們這次的作品,雖然只是一個比較簡單游戲的實現,但是通過這次合作,我也有很大的收獲。雖然是一個小組,但每個人有不同的看問題的方法,我們在做這個軟件的時候,大家也曾有過意見的分歧,我們也曾因為預期的功能沒有實現而互相指責,也曾為有一點小小的進步而欣喜若狂。一路風風雨雨,我們畢竟是基本完成了預期的功能,努力沒有白費,心里特別的充實,這就是創造的快樂,也是合作的快樂。我還編寫了大作業的文檔,由于自身能力的有限,我雖然竭盡全力,但總的感覺還是不能讓我滿意,不過,我也從中學到了一些東西: 總的說來,這次作業中我鍛煉了自己的能力,也培養了團隊合作的精神,感謝我的隊友!感謝老師!感謝生活! ——尚振興 在本軟件的開發中,還是有不少地方是不太滿意的,首先我通過單純的VC++語言來實現功能。雖然VC++的強大功能足以應付這種軟件的開發要求了,但是由于控件的缺乏,語法的繁瑣,在實現很多功能的實現中花費了不少力氣。但是由于知識水平的缺乏,無法使用Delphi,flash等更簡便的手段來實現功能,希望以后可以彌補這一點。其次,缺乏完成大工程的經驗,沒有建立一個有效可行的工作計劃。在工作中時而通宵奮戰,時而停頓不前,既浪費了寶貴的時間,也耗費了大量精力,實在得不償失。 但值得注意的是,在軟件的開發中,我也學到了很多書本上學不到的經驗。首先,我使用了別人開發的思想,雖然開始很不習慣,但是上手之后就深深的體會到模塊化開發和面向對象語言的方便與高效。其次,這次開發中我使用了很多以前沒接觸過的函數。除了上網學習資料外。熟練的使用老師提供的參考資料,相信對我以后的工作會有很大的益處。 3-《軟件技術基礎》項目報告 我覺得通過這個小項目很好地考察了每個學生的知識水平,每個人都發揮了個人最佳的狀態。雖然這種形式比普通的卷面考試要難,但是卻能夠充分調動每個人的積極性去學習自己尚未接觸的知識和運用自己已經學過的知識。實驗中,我們小組成員之間配合默契,共同商討問題,使我們在碰到一個一個的問題后,能快速找到相關的答案。難能可貴的是,在軟件制作最緊張的時候,大家都義無反顧地放棄了一點休息時間,和團隊一起堅持奮斗!所以通過這次實驗的合作,我們小組成員之間更加增進了了解,增進了團結! ——崔光浩 六、主要算法 以下時詳細算法中提到的主要函數,其他函數在程序中。 1判斷勝負 五子棋的勝負,在于判斷棋盤上是否有一個點,從這個點開始的右、下、右下、左下四個方向是否有連續的五個同色棋子出現,判斷勝負方向如下圖 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-《軟件技術基礎》項目報告 { 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-《軟件技術基礎》項目報告 2鼠標模擬 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-《軟件技術基礎》項目報告 } } 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-《軟件技術基礎》項目報告 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-《軟件技術基礎》項目報告 } } } } break;case 5: //悔棋 repent();break;case 6: //保存 showSave(1);break;case 7: //退出 chose = 0;break;default: break; 4.系統總體設計與實現 4.1 總體設計分析 總體設計是軟件開發過程中的另一個重要階段,在這一階段中將根據需求分析中提出的邏輯模型,科學合理地進行物理模型的設計。這個階段的主要目標是將反映用戶信息需求的邏輯方案轉換成物理方案,并為下一階段提供必要的技術資料。 4.1.1 總體設計原則 (1)整體性:軟件是作為統一整體而存在的。因此,在總體設計中要從整個軟件的角度進行考慮。 (2)靈活性:為保持軟件長久的生命力,要求該手機游戲軟件具有很強的環境適應性。為此,游戲軟件應具有較好的開放性和結構的可變性。 (3)可靠性:可靠性是指軟件抵御外界干擾的能力及受外界干擾時的恢復能力。 (4)經濟性:經濟性是指在滿足游戲軟件需求的前提下,盡可能地減小游戲軟件的開銷。 4.1.2 軟件模塊總體設計 軟件中各模塊之間的關系通常利用層次圖來表示。它是一種一系列多層次的用樹形結構的矩形框描繪數據的層次結構框圖。一個單獨的矩形框作為樹形結構的頂層,各個數據的子集由下面的各層矩形框代表,最底層的各個矩形框代表組成這個數據的實際數據元素(不能再分割的元素),它代表完整的數據結構。這模式非常適合于需求分析階段的需要,層次方框圖對數據結構描繪隨著結構精細化也越來越詳細。反復細化沿著圖中每條路徑,從對頂層信息的分類開始,直到確定了數據結構的全部細節為止。 開始游戲重新游戲游戲選項悔棋認輸五子棋游戲背景音樂退出游戲先后手設置游戲設置棋盤底紋設置棋盤大小設置游戲幫助幫助關于 圖4-1 游戲功能結構 本研究中將游戲軟件分為三大模塊,如圖4-1所示,包括:游戲選項、游戲設置和幫助。按照在調研中搜集的資料對每個模塊的功能進行編排制作。依據上述功能的分析,本研究中,將游戲軟件在三大模塊的基礎上又對每一大模塊又分為幾個子模塊: 游戲選項包括六個模塊:開始游戲、重新游戲、悔棋、認輸、背景音樂和退出游戲。 游戲設置包括三個模塊:先后手設置、棋盤底紋顏色設置和棋盤大小設置。 幫助包括兩個模塊:游戲幫助和關于。 4.2 游戲設計 4.2.1 游戲前的準備 本游戲在開發之前需要做一些前期準備工作,尤其是對于精通五子棋游戲的Java 游戲開發者來說。通常情況下,一款運用起來比較熟練地 J2ME 開發工具 是必不可少的。本游戲使用的是J2ME的簡化開發工具 Sun Java(TM)Wireless Toolkit 2.5.2 for CLDC,他需先將Java虛擬機安裝調試好之后才能使用。WTK 2.5.2 不帶有文本編輯功能,所以需要另尋搭配使用。本游戲采用 Ultra Edit 進行編輯。本游戲需要幾張后綴名為.png格式的卡通圖,除了一張用作五子棋游戲的 Logo 外,其余的都將在游戲中使用。4.2.2 游戲界面和事件驅動設計 游戲的界面設計采取傳統游戲界面風格,如圖4-2所示。游戲設計中采用傳統界面游戲風格,首先啟動游戲,然后進入游戲開始界面,界面中放置“設置”、“開局”、“幫助”、“關于”四個選項供玩家選擇。其中“設置”選項主要是對游戲的相關功能進行設置,如游戲難度設置。另外還有“悔棋”、“重玩”等項目的設置。除此之外還包括查看游戲幫助、游戲介紹等。 圖4-2 游戲界面設計 所謂事件驅動,簡單地說就是你點什么按鈕(即產生什么事件),電腦執行什么操作(即調用什么函數)。當然事件不僅限于用戶的操作。我們知道,事件是事件驅動的核心自然是。從事件角度說,一個事件收集器、一個事件發送器和一個事 件處理器組成了事件驅動程序的基本結構。事件收集器專門負責收集包括來自硬件的(如時鐘事件等)、來自用戶的(如鍵盤、鼠標事件等)及來自軟件的(如應用程序本身、操作系統等)的所有事件。將收集器收集到的事件分發到目標對象中則由事件發送器負責完成。具體的事件響應工作則由事件處理器完成,它需要運用虛函數機制(函數名取為類似于 Handle Msg 的一個名字),它往往要到實現階段才完全確定。事件處理器對于框架的使用者來說是他們唯一能夠看到的。棋類游戲通常具備兩個重要特性,首先是對戰雙方輪流落子,其次是落子間隔通常是不確定的,尤其是對戰后期,可能每一步棋都要經過深思熟慮,無論是人還是計算機,都無法對時間間隔有事先的預期?;谝陨蟽蓚€特性,本游戲摒棄了大多數游戲采用的線程或定時器驅動游戲的方法,而采用了事件驅動的方法,即玩家的鍵盤或觸摸筆觸發游戲的下一個動作。事件驅動大大減少了不必要的工作量,只有玩家發出消息時,計算機才啟動運算,而在玩家思考期間,計算機不做任何運算和重繪操作。4.2.3 游戲的類設計 五子棋游戲屬于二維棋類游戲,因此可以定義一個 Chesses 類來表示棋子,用一個 Chess 類型的二維數組來包含棋盤上的所有棋子,對于該棋子玩家的區分使用Chesses 的 boolean 型的變量 is Player1 來區分??梢钥紤]直接生成數組的每一個對象而不是在數組建立后,而是把每一個棋子對象(Chesses)放在游戲的進行中生成,這主要是考慮到移動設備的資源有限,盡可能減少系統資源占用。這樣在游戲進行時,可以避免還沒有下的棋子在一開始就占用了系統內存,玩家每下一步棋,在數組相應位置生成該棋子的對象。 對于游戲中的每一類的設計,首先就是一個 MIDlet 類,Gobang 類繼承自MIDlet 類,通過方法 start App,pause App,destroy App 來通知游戲的開始,暫停和銷毀結束,用于連接設備的應用程序管理器(Application Manager)。 本游戲共由7個類組成,它們各自的功能如下: (1)Gobang MIDlet類 負責程序的啟動和屏幕之間的切換; (2)Gobang Canvas 類 玩家的對戰平臺,他繼承于 Canvas 類;(3)Setting 類 用于創建游戲的各項設置參數表單; (4)Gobang Logic 類 游戲的邏輯類,負責勝負判斷和計算機落子; (5)Dot 類 棋子類,包含了棋子的位置信息;(6)Help 類 游戲的幫助類,包含五子棋的一些常識信息和五子棋教學內容;(7)About類 游戲的關于類,包含游戲的版本、版權等信息。各個類之間的關系如圖4-3所示: 圖4-3游戲類設計 4.2.4 游戲的流程設計 對于棋盤界面的更新,游戲進行繪制棋子時是按照棋子的二維數組來完成的,玩家下棋后,設置is Player1 值,程序修改數組相應位置,然后重新繪制(repaint)。為了使游戲的操作盡可能的簡便,本文設計上不在游戲進入時設計菜 單,玩家可以直接開始對戰,而是在開始游戲的過程中設置重新開始和退出的按鈕。即一鍵開始,運行即玩,重來或退出都使用一鍵操作。游戲流程的設計依據主要是游戲的界面設計和游戲的類的設計。游戲啟動時,Gobang MIDlet 對象先顯示游戲的主屏幕,在屏幕下方一側是出軟鍵(軟鍵指描述抽象客戶端設備如何顯示),另一側是用軟件構成的菜單,菜單元素主要有“開局”、“游戲設置”、“游戲幫助”、“關于”選項。當玩家選擇“游戲設置”軟鍵時,則顯示游戲參數設置表單;當玩家選擇“開局”軟鍵時,則顯示游戲對戰主界面;當玩家選擇“游戲幫助”軟鍵時,則顯示游戲幫助表單;當玩家選擇“關于”軟鍵時,則顯示游戲關于表單。玩家進入游戲參數設置表單,當玩家按下“確定”軟鍵時,則確認當前游戲參數,返回游戲主屏幕;當玩家按下“取消”軟鍵時,則放棄此次對游戲的修改,直接返回游戲主屏幕。玩家進入游戲對戰畫布,對戰中畫布有兩個軟鍵,當玩家按下“返回主菜單”軟鍵時,則退出游戲到達游戲主菜單;當玩家按下“悔棋”軟鍵時,則進行悔棋操作;當游戲結束時,“悔棋”軟鍵被換成了“重玩”軟鍵。玩家進入游戲介紹表單,當玩家按下“確定”軟鍵時,返回游戲主屏幕。4.2.5 游戲算法的設計 1、五子棋的獲勝組合 有哪些獲勝組合是在一場五子棋的游戲中計算機必須要知道的,因此,獲勝組合的總數必須要求得。在本文中我們假定當前的棋盤為15*15: (1)每一列的獲勝組合是11,共15列,計算水平方向的獲勝組合數,所以水平方向的獲勝組合數為:11*15=165。 (2)每一行的獲勝組合是11,共15列,則可計算垂直方向的獲勝組合總數,垂直方向的獲勝組合數為:11*15=165。 (3)同理,可計算正對角線方向的獲勝組合總數,正對角線上的獲勝組合總數為11+(10+9+8+7+6+5+4+3+2+1)*2=121。 (4)計算反對角線上的獲勝組合總數。計算反對角線方向的獲勝組合總數可計算為11+(10+9+8+7+6+5+4+3+2+1)*2=121。這樣可計算得所有的獲勝組合數為:165+165+121+121=572。 2、設計獲勝棋型 通過上面的計算,一個15*15的屋子棋盤在此已經計算出了會有572中獲勝方式,因此,我們就可以利用數組建立一些常規棋型,棋型的主要作用是: (1)判斷是否有任何一方獲勝; (2)根據當前格局判斷最可能的落子方式。 然而在現實中,高手留給我們的經驗就是把握前奏,如“沖四”、“活三”,除了“連五”以外,這些也是同向勝利的捷徑。 3、攻擊與防守 獲勝棋型的算法是中性的,不區分計算機和玩家,這就涉及到攻擊和防守何者優先的問題。而許多高手都認為五子棋的根本是“防守”,“攻擊”是靈魂。進攻是取勝的手段,是防守的延續和發展。許多經驗和研究表明,一個棋手只要掌握了全面的、基本的防守原理和技巧,就能和比自己棋力高一個等級的進攻型選手對抗,起碼能立于不敗之地。對手進過越偏激,則防守的效果越好。沒有進攻的防守就像只開花不結果,沒有實際意義,頑強的防守是反攻的前奏,沒有進攻的延續,防守也失去了價值。而這缺一不可。根據以上原理,計算機在接受最佳的攻擊位置之前,還要計算當前玩家的最佳攻擊位置。如果玩家存在最佳攻擊位置,那么計算機就將下一步的棋子擺在玩家的最佳攻擊位置上以阻止玩家的進攻,否則計算機便將棋子下在自己的最佳攻擊位置上進行攻擊。 4、用到的典型算法(1)坐標變換算法 游戲的實質其實是對所下棋子的位置進行操作和判斷,因此將己方、對方以及棋盤上空點的位置坐標存儲在相應的List中。我對所下棋子的坐標進行了處理,因為我所采用的棋盤為15*15,所以棋子橫坐標為0到14的整數,縱坐標也為0到14的整數。因此,每次在棋盤上下子之后,計算機在存儲該點的坐標時,便要對坐標進行加工。假設左上角點為firstPoint,它的實際坐標為(x1,y1),而我是將它作為(0,0)存儲的,其它的坐標,其它點都是以該點為標準進行變換的,假設棋盤上每個格子的寬度為w,某實際點為(x2,y2),變換后的坐標為(x,y),x=(x2-x1)/w,y=(y2-y1)/w。 (2)勝負判斷算法 勝負判斷的規則很簡單,就是判斷游戲雙方的棋子在同一條水平線、同一條豎線或是同一條斜線上誰先出現5個連續的棋子,誰先達到這樣的目標,誰就獲得勝利。在本設計中,是在每次下完一個子后進行判斷,看己方是否達到了勝利的標準,若勝利游戲便結束;否則,游戲繼續。 (3)人工智能算法 人工智能算法的主體思想分為以下三個步驟: 第一步:根據雙方的當前的形勢循環地假設性的分別給自己和對方下一子(在某個范圍內下子),并判斷此棋子能帶來的形勢上的變化,如能不能沖4,能不能形成我方或敵方雙3等。 第二步:根據上一步結果,組合每一步棋子所帶來的所有結果(如某一步棋子可能形成我方1個活3,1個沖4(我叫它半活4)等),包括敵方和我方的。 第三步:根據用戶給的規則對上一步結果進行排序,并選子(有進攻形、防守形規則)。 5、典型類的具體設計(1)應用程序類 Gobang 類用于連接設備的應用程序管理器(Application Manager),Gobang類繼承自 MIDlet 類,通過 Gobang 類的方法 start App,pause App,destroy App 來通知游戲的開始,暫停和銷毀結束。源代碼如下: 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 類型的二維數組,棋盤上的每一個棋子都對應著一個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 游戲實現 4.3.1 主類的實現 YpkWuZiQiActivity類是五子棋游戲的主類,同時也是五子棋游戲的入口,它繼承自Activity類。進入程序后,首先調用init()方法,init()方法通過調用setContentView(R.layout.welcomeview)顯示登錄該游戲的第一個界面。welcomeview.xml是一個布局文件,里面存儲了界面信息。該界面中有四個Button,分別為welButton1、welButton12、welButton3、welButton4,點擊每個Button都會觸發一個事件,其中點擊welButton1和welButton2還會給它的成員變量FIGHTINGMODE賦值,因為在人人對戰和人機對戰是寫在同一個ChessBoard類中的,所以需要通過FIGHTINGMODE的值來區分是人人對戰還是人機對戰。 點擊welButton1時,FIGHTINGMODE=1,然后會調用initTwo()方法,該方法通過調用setContentView(R.layout.chess)方法,來顯示對戰的界面。chess.xml文件存儲了對戰界面的信息。在chess.xml文件中調用了ChessBoard類,該類中主要定義了棋盤的信息,下文會對該類做具體的介紹的。在對戰界面中也有四個Button,分別是b1、b2、b3、b4。 首先來介紹一下b2,該Button的功能是返回主頁,調用init()方法就可以實現。b3的功能是重新開始,這個也只需要調用initTwo()方法。b3的功能是退出,調用了系統方法:System.exit(1)。下面重點介紹一下b1,該Button的功能是悔棋。該Button設定的點擊事件詳細內容如下: 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,詳細的定義了棋盤信息,主要負責顯示棋盤的內容。接下來判斷一下觸發悔棋事件的是哪一個玩家,再判斷是否符合悔棋的條件,這個條件很簡單,就是棋盤上至少要有兩個棋子。之后便進行悔棋操作,分別將兩個玩家最后下的棋子取出,程序實現就是將兩個ArrayList的最后一個元素remove出來,再分別放到記錄棋盤中沒有棋子的點的} } 集合中,最后更新一下畫布,主要是調用ChessBoard的invalidate()方法。通過以上步驟之后,呈現在我們面前的便是悔完棋的畫面了。 點擊welButton2時,FIGHTINGMODE=2,之后的步驟便會點擊welButton1是相同的了,不同的是,由于對戰模式的改變,從人人對戰變成了人機對戰。 點擊welButton 3時,通 過 initThree() 方 法 調 用setContentView(R.layout.netchess)方法實現網絡對戰。詳細的對戰實現細節將會在下文一一介紹。在這個界面中只保留了兩個Button:b2和b4。這兩個Button所實現的功能和上面的b2和b4是相同的。 最后,welButton4比較簡單。它所實現的功能為退出應用程序,調用System.exit(1)方法。4.3.2 游戲設置類的實現 游戲設置表單用來對游戲參數進行設置,包括棋盤大小、先手選擇、智能級別。表單中使用了 Gauge 和 Choice Group 兩種高級用戶界面組件。 1、棋盤尺寸選擇 標準的五子棋棋盤為 15*15,但為了滿足不同玩家的需求,這里提供了大小為10*10 到 20*20 的棋盤,用戶可以通過 Gauge 組件改變。棋盤的最小值為 10,而Gauge 組件的最小值為 0,所以當前的 Gauge 值需要角上 10 才是當前棋盤大小。創建 Gauge 組件的代碼如下: form = new Form(“ 游戲設置”);// 創建參數設置表單并添加標簽 gauge Size = new Gauge(“棋盤規格: ” + board Size + “ X ” + board Size, true, 10, board Size-10);//棋盤規格 form.append(gauge Size); 圖4-4 棋盤尺寸的設計 在Gauge交互模式下可以為Gauge對象所在的表單對象綁定一個Item State Listener 事件監聽器,并在監聽器上捕捉 Gauge 對象的事件,當 Gauge 的值發生變化時就會觸發事件。這里將根據 Gauge 的當前值改變標簽,顯示當前的棋盤大小。其代碼如下: public void item State Changed(Item item){ if(item == gauge Size)//當 Gauge 組件發生變化時 { int bs = gauge Size.get Value()+ 10;//獲取當前的 Gauge 值并計算棋盤大小(加10) gauge Size.set Label(“棋盤規格: ” + bs + “ X ” + bs);//改變 Gauge 組件的標簽 } } 2、難度選擇 游戲的難易程度根據計算機的智能級別來控制,創建及添加選項的方法和復選框一樣,所不同的是在創建 Choice Group 對象時,類型設置為 1(單選)。對于單選框,set Selected Index 只能用來指定某個選項被選中,因此,布爾值 selected 的值必然為 true,否則便沒有意義。 游戲共有 3 個難度級別,分別是:拜師學藝、棋行天下、誰與爭鋒(此游戲中并未作出區分),初始情況下為拜師學藝,該選項的索引值為 0。創建難度選擇單選框的代碼如下: level = 1;//默認情況下的難度級別 choicelevel = new Choice Group(“電腦智能級別:”, 1);//創建難度級別選項組 choicelevel.append(“拜師學藝”, null);//難度 1 choicelevel.append(“棋行天下”, null);//難度 2 choicelevel.append(“誰與爭鋒”, null);//難度 3 choicelevel.set Selected Index(level-1 , true);//設置默認情況為難度 1,索引值為0 form.append(choicelevel);//將選項組添加到主表單中 游戲設置選項表單還有兩個 Command 對象,分別用于玩家卻熱和取消,所以表單需要監聽軟鍵事件和組件事件: public class Setting implements Command Listener, Item State Listener 3、棋手選擇 選擇先手和難度等級用 Choice Group 組件來實現。Choice Group 組件用來構造選擇框,其構造函數如下: Choice Group(String label, int choice Type)選擇先手的選項框為選擇組件,屬性為復選框,標簽名為空。創建好選擇組件后,逐條添加選項元素。添加選項的方法如下: int append(String string Part, Image image Part)該方法追加一個選項元素到選擇組中,追加的選項為選擇組中的最后一個元素,選擇組的大小加 1。 對于多選類型的 Choice Group,還可以設置個別選項的選擇狀態。設置初始選擇狀態的方法如下: void set Selected Index(int element Num, Boolean selected)這里創建一個只有一個選項元素的多選框用于玩家設置是否計算機先行,在默認情況下為true,創建完成多選框后將其添加到主表單中,代碼如下: Computer First = true;//在默認情況下為計算機先行 choice First = new Choice Group(null, 2);//創建復選框 choice First.append(“電腦先手”, null);//添加選項元素 choice First.set Selected Index(0, Computer First);//設置多選框的默認狀態 form.append(choice First);//將多選框添加到主表單中 4.3.3 棋子類的實現 1、棋子的行列位置 此五子棋游戲是一個二維棋類游戲,所以定了了一個 Dot 類來表示棋子。由于移動設備的局限性,所以程序不在下每一步棋時生成一個對象,而是在游戲進行時,玩家或者計算機沒下一步棋,在數組相應位置生成該棋子的對象,而將已經下過的棋子保存到數組中隨時檢索,這樣可以避免過多棋子對象占用系統內存。Dot 類的 UML 圖如圖 4-5 所示: 圖4-5棋子行列設計 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、修改棋子位置 在創建好 Dot 對象后,Dot 類提供了兩種方法更改棋子位置,包括設置行列位置和從已有棋子中復制參數。 public void set Row Col(int r, int c)//設置棋子位置 { row = r;col = c; } public void copy From(Dot d)//復制已有的棋子 { row = d.row; col = d.col; } 4.3.4 對戰邏輯類的實現 1、建立數據結構 本程序以數組保存當前盤面的情況,每個位置可能有三種狀態:空、玩家的落子、計算機的落子,分別用 0、1、2 來表示。代碼如下: public static int PLAYER_NONE = 0;//該位置為空 public static int PLAYER_COMPUTER = 1;//該位置有電腦的落子 public static int PLAYER_HUMAN = 2;//該位置有玩家的落子 棋盤在初始情況下為空,即棋子上沒有任何棋子,在Gobang Logic類的構造函數中對棋盤進行初始化: table = new int[board Size][board Size];//創建棋盤數組 for(int r = 0;r < board Size;r++){ for(int c = 0;c < board Size;c++) table[r][c] = 0;//初始化盤面為空 } 除了記錄棋盤上每個位置的落子狀態外,程序還將對每種狀態的位置個數進行統計,以對算法進行簡化。對三種狀態的統計存儲在整型數組中,該數組為全局變量。 private int player Counter[]; 在 Gobang Logic 類的構造函數中對三種狀態的計數進行初始化,即棋盤上都是空、計算機的落子或玩家的落子狀態的個數為 0,在數據結構上,把空也當做某一特殊玩家。 初始化代碼如下: player Counter = new int[3];//落子狀態計數器 player Counter[0] = board Size * board Size;//整個棋盤都是空的狀態 player Counter[1] = 0;//電腦落子0 player Counter[2] = 0;//玩家落子0 2、落子和悔棋 這里使用了一個 Dot 類棋子對象來記錄最后一步棋的位置,當玩家下了一步棋后需要將上一步重新繪制,以消除旗子上的引導框。另外,還是用了堆棧來存儲最近的幾步落子,以便玩家悔棋。 private Dot last Dot;//棋子對象,存儲最后一步落子 private Stack steps;//棋子對象的堆棧 最后一步棋子和棋子堆棧在 Gobang Logic 類的構造函數中進行初始化; last Dot = new Dot(board Size);//創建棋子對象用來存儲最后一步棋,初始化 位置為棋盤中央steps = new Stack();//堆棧對象,用來存儲最近的幾部棋在棋盤上落子的代碼如下: private void go At(int row, int col, int player)//電腦或人在 row、col 位置上走 { int last Row = last Dot.row;//記錄上一步的行坐標 int last Col = last Dot.col;//記錄上一步的列坐標 table[row][col] = player;//當前位置填充玩家代碼 last Dot.set Row Col(row, col);//將這一部設置為“最后一步” game Canvas.repaint At(last Row, last Col);//重新繪制上一步(將引導框去掉) game Canvas.repaint At(row, col);//繪制當前這步 switch(player)//統計雙方落子數量 { case 1: player Counter[1]++;//電腦的步數 break; case 2: player Counter[2]++;//玩家的步數 break; } player Counter[0]--;//空白的個數 if(steps.size()> 10)//堆棧數量超過上限(10) steps.remove Element At(0);//清除棧底 steps.push(new Dot(row, col));//將當前這步棋子壓入堆棧 } Stack(堆棧類)從 Vector 集成而來,它使用 push()方法進入堆棧,需要時使用 pop()方法從堆棧的頂部將其取出?;谄鍎幼饔赏婕易龀?,從數據結構來看,是同時后退兩步(將最后兩步棋位置的落子狀態設置為空)。 Stack 類的 peek()方法將獲取棧頂對象,但不移?;谄宕a如下: : public boolean undo()//悔棋 { if(steps.size()>= 3) { Dot d = new Dot();//創建棋子對象 d.copy From((Dot)steps.pop());//從堆棧彈出的棋子中復制行列位置坐標 table[d.row][d.col] = 0;//將該位置設置為空 game Canvas.repaint At(d.row, d.col);//在棋盤上重新繪制該位置 d.copy From((Dot)steps.pop());//從堆棧彈出的棋子中復制行列位置坐標 table[d.row][d.col] = 0;//將該位置設置為空 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);//重新繪制最后一步(添加引導框)return true;//悔棋成功 } else { return false; //悔棋失敗 } } 4.4 本章小結 本章主要內容是游戲的實現,包括主類的實現,如構造函數、事件處理等,游戲幫助和介紹表單類的實現,游戲設置類的實現,如棋盤、選手、難度等,旗子類的實現,如棋子行列位置、檢查越界等,對戰邏輯類的實現,如落子和悔棋、邏輯運算等的實現。第四篇:五子棋游戲項目報告
第五篇:五子棋游戲總體設計與實現