第一篇:五子棋游戲總體設(shè)計與實現(xiàn)
4.系統(tǒng)總體設(shè)計與實現(xiàn)
4.1 總體設(shè)計分析
總體設(shè)計是軟件開發(fā)過程中的另一個重要階段,在這一階段中將根據(jù)需求分析中提出的邏輯模型,科學(xué)合理地進行物理模型的設(shè)計。這個階段的主要目標(biāo)是將反映用戶信息需求的邏輯方案轉(zhuǎn)換成物理方案,并為下一階段提供必要的技術(shù)資料。
4.1.1 總體設(shè)計原則
(1)整體性:軟件是作為統(tǒng)一整體而存在的。因此,在總體設(shè)計中要從整個軟件的角度進行考慮。
(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ù)上述功能的分析,本研究中,將游戲軟件在三大模塊的基礎(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 進行編輯。本游戲需要幾張后綴名為.png格式的卡通圖,除了一張用作五子棋游戲的 Logo 外,其余的都將在游戲中使用。4.2.2 游戲界面和事件驅(qū)動設(shè)計
游戲的界面設(shè)計采取傳統(tǒng)游戲界面風(fēng)格,如圖4-2所示。游戲設(shè)計中采用傳統(tǒng)界面游戲風(fēng)格,首先啟動游戲,然后進入游戲開始界面,界面中放置“設(shè)置”、“開局”、“幫助”、“關(guān)于”四個選項供玩家選擇。其中“設(shè)置”選項主要是對游戲的相關(guā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)放在游戲的進行中生成,這主要是考慮到移動設(shè)備的資源有限,盡可能減少系統(tǒng)資源占用。這樣在游戲進行時,可以避免還沒有下的棋子在一開始就占用了系統(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è)計
對于棋盤界面的更新,游戲進行繪制棋子時是按照棋子的二維數(shù)組來完成的,玩家下棋后,設(shè)置is Player1 值,程序修改數(shù)組相應(yīng)位置,然后重新繪制(repaint)。為了使游戲的操作盡可能的簡便,本文設(shè)計上不在游戲進入時設(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)于表單。玩家進入游戲參數(shù)設(shè)置表單,當(dāng)玩家按下“確定”軟鍵時,則確認(rèn)當(dāng)前游戲參數(shù),返回游戲主屏幕;當(dāng)玩家按下“取消”軟鍵時,則放棄此次對游戲的修改,直接返回游戲主屏幕。玩家進入游戲?qū)?zhàn)畫布,對戰(zhàn)中畫布有兩個軟鍵,當(dāng)玩家按下“返回主菜單”軟鍵時,則退出游戲到達(dá)游戲主菜單;當(dāng)玩家按下“悔棋”軟鍵時,則進行悔棋操作;當(dāng)游戲結(jié)束時,“悔棋”軟鍵被換成了“重玩”軟鍵。玩家進入游戲介紹表單,當(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)為五子棋的根本是“防守”,“攻擊”是靈魂。進攻是取勝的手段,是防守的延續(xù)和發(fā)展。許多經(jīng)驗和研究表明,一個棋手只要掌握了全面的、基本的防守原理和技巧,就能和比自己棋力高一個等級的進攻型選手對抗,起碼能立于不敗之地。對手進過越偏激,則防守的效果越好。沒有進攻的防守就像只開花不結(jié)果,沒有實際意義,頑強的防守是反攻的前奏,沒有進攻的延續(xù),防守也失去了價值。而這缺一不可。根據(jù)以上原理,計算機在接受最佳的攻擊位置之前,還要計算當(dāng)前玩家的最佳攻擊位置。如果玩家存在最佳攻擊位置,那么計算機就將下一步的棋子擺在玩家的最佳攻擊位置上以阻止玩家的進攻,否則計算機便將棋子下在自己的最佳攻擊位置上進行攻擊。
4、用到的典型算法(1)坐標(biāo)變換算法
游戲的實質(zhì)其實是對所下棋子的位置進行操作和判斷,因此將己方、對方以及棋盤上空點的位置坐標(biāo)存儲在相應(yīng)的List中。我對所下棋子的坐標(biāo)進行了處理,因為我所采用的棋盤為15*15,所以棋子橫坐標(biāo)為0到14的整數(shù),縱坐標(biāo)也為0到14的整數(shù)。因此,每次在棋盤上下子之后,計算機在存儲該點的坐標(biāo)時,便要對坐標(biāo)進行加工。假設(shè)左上角點為firstPoint,它的實際坐標(biāo)為(x1,y1),而我是將它作為(0,0)存儲的,其它的坐標(biāo),其它點都是以該點為標(biāo)準(zhǔ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è)計中,是在每次下完一個子后進行判斷,看己方是否達(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é)果進行排序,并選子(有進攻形、防守形規(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類。進入程序后,首先調(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ā)悔棋事件的是哪一個玩家,再判斷是否符合悔棋的條件,這個條件很簡單,就是棋盤上至少要有兩個棋子。之后便進行悔棋操作,分別將兩個玩家最后下的棋子取出,程序?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ù)進行設(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 值并計算棋盤大?。?0)
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è)備的局限性,所以程序不在下每一步棋時生成一個對象,而是在游戲進行時,玩家或者計算機沒下一步棋,在數(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ù)中對棋盤進行初始化:
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ù)進行統(tǒng)計,以對算法進行簡化。對三種狀態(tài)的統(tǒng)計存儲在整型數(shù)組中,該數(shù)組為全局變量。
private int player Counter[];
在 Gobang Logic 類的構(gòu)造函數(shù)中對三種狀態(tài)的計數(shù)進行初始化,即棋盤上都是空、計算機的落子或玩家的落子狀態(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ù)中進行初始化;
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()方法進入堆棧,需要時使用 pop()方法從堆棧的頂部將其取出?;谄鍎幼饔赏婕易龀?,從數(shù)據(jù)結(jié)構(gòu)來看,是同時后退兩步(將最后兩步棋位置的落子狀態(tài)設(shè)置為空)。
Stack 類的 peek()方法將獲取棧頂對象,但不移?;谄宕a如下: :
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)。
第二篇:QT基于linux的五子棋游戲設(shè)計與實現(xiàn)
課題名稱:基于linux的五子棋游戲設(shè)計與實現(xiàn)
專業(yè):計算機科學(xué)與技術(shù)(計算機工程方向)
開發(fā)工具及語言:,ubuntu12.04,QT
運行環(huán)境:linux下的QT
論文字?jǐn)?shù):1w左右
是否需要PPT:是
是否需要安裝說明:是
所在城市:武漢市
所在學(xué)校:華中農(nóng)業(yè)大學(xué)楚天學(xué)院
功能需求分析
系統(tǒng)的基本功能需求分析如下:
(1)游戲進入界面的菜單選擇,有自我對戰(zhàn)、人機對戰(zhàn)、網(wǎng)絡(luò)對戰(zhàn)和退出 游戲四個選項;
(2)進入游戲之后,顯示一個十三行十三列的五子棋的棋盤。棋盤旁邊顯 示一個菜單,菜單選項有棋局重現(xiàn)、繼續(xù)上步、上級菜單和退出游戲,在界面上可以在棋盤落子操作和菜單操作之間進行切換,用鍵盤的按鍵來控制,棋局重現(xiàn)功能是在某方勝利之后才能手動操作一步步查看并回顧雙方下棋的過程;繼續(xù)上步可以切換回棋盤操作;上級菜單功能可以使五子棋游戲退出當(dāng)前的游戲模塊(自我對戰(zhàn)、人機對戰(zhàn)、網(wǎng)絡(luò)對戰(zhàn)其中的一種),回到游戲開始界面時候的菜單,進行重新選擇;退出游戲是退出整個游戲界面;
(3)棋盤上顯示光標(biāo),可以對光標(biāo)進行移動操作,也可以在棋盤和菜單來 回切換的時候重繪和擦除;
(4)在上面棋盤將光標(biāo)移動到上面對應(yīng)的位置,可以落子,棋盤上將在光 標(biāo)顯示處出現(xiàn)相應(yīng)的棋子,并且棋子在橫縱交點處;
(5)自我對戰(zhàn)的過程中有悔棋的功能;
(6)游戲的過程中會有提示信息,如該哪一方落子,棋盤旁邊顯示相應(yīng)按 鍵對應(yīng)的操作列表;
(7)可以自動判斷勝負(fù),勝利一方形成一列的五個或5個以上的棋子閃 爍數(shù)次,顯示是黑方或者白方已經(jīng)勝利的字樣,并且停止落子的功能;
(8)能夠?qū)崿F(xiàn)三種游戲模式,自我對戰(zhàn)、人機對戰(zhàn)和網(wǎng)絡(luò)對戰(zhàn)。
非功能需求分析
非功能需求如下:
(1)在程序運行的過程中程序不能崩潰,更不能使系統(tǒng)出現(xiàn)問題,造成 災(zāi)難性的后果;
(2)希望在此項目的基礎(chǔ)上不做改動或做很少的改動就能在其他的系統(tǒng) 或設(shè)備上運行;
(3)界面清晰容易看懂,方便玩家操作;
(4)游戲運行速度不能太慢,要反應(yīng)及時,以免影響玩家的興趣。
(5)程序代碼必須每行都有詳細(xì)注釋。以上是要登記的內(nèi)容。這個是例子。自己修改相關(guān)信息。一定要寫的詳細(xì),開發(fā)以文檔為依據(jù)。注意請把文件名換成自己的作品名,以防技術(shù)開發(fā)錯誤
注意事項:
第三篇:區(qū)域游戲五子棋
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個棋子就算獲勝。
(在電腦上下載五子棋的小游戲進行演示,并講解。)
(二)提出要求,注意安全。
師:
游戲前老師有幾點要求提醒大家。
1、動手區(qū)里做粘貼畫時要注意不要把豆子撒在地上,更不能放進鼻子耳朵里。
2、建構(gòu)區(qū)的小朋友在堆擺易拉罐的時候請輕拿輕放。
3、益智區(qū)里初學(xué)五子棋的小朋友遇到問題主動找老師。
4、要和其他小朋友文明交往、合作,學(xué)會謙讓。
5、垃圾放在垃圾桶,不可以隨地亂丟。
小朋友們坐坐好,坐的好的小朋友先插卡進區(qū)。
(三)自主進區(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é)
表揚與批評,出示活動中拍攝的照片進行點評,提出新要求。
第四篇:Java五子棋實現(xiàn)報告
一、實驗?zāi)康?/p>
(1)使用Java編寫五子棋程序
(2)掌握編寫過程的一些類和類成員的使用,并且了解五子棋制作過程的一些步驟和了解一些算法。
二、實驗環(huán)境
在電子樓2樓,裝有My Eclipse 的計算機上進行
三、實驗內(nèi)容
編寫一個五子棋程序。程序主要實現(xiàn)以下功能:
1.實現(xiàn)五子棋界面,要求人性化界面簡潔美觀; 2.實現(xiàn)黑白色輪流下棋功能,能提示下棋方; 3.實現(xiàn)連成五子自動判斷功能; 4.實現(xiàn)時間設(shè)置功能,認(rèn)輸功能;
核心代碼如下:
1.我的第一步是設(shè)計界面。在這個過程的要使用到以下的步驟:
1.使用MyEclipse 創(chuàng)建一個Project關(guān)于這個工程,加入兩個類,分別是ChessFrame和Chess,而ChessFrame是這個工程中最重要的一個部分。創(chuàng)建過程中要繼承JFrame類,并且要繼承Runnable 和 MouseListener 這兩個接口,分別是用來監(jiān)聽鼠標(biāo)的移動和時間的變化。2.在給這個JFrame設(shè)置大小和顏色等一些東西。這里最主要的是使用了兩個函數(shù),是以前沒見過的:
1.這個是用來設(shè)置默認(rèn)的窗口關(guān)閉事件的
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);2.這兩個是用來獲得屏幕的大小的
Toolkit.getDefaultToolkit().getScreenSize().height;Toolkit.getDefaultToolkit().getScreenSize().width;
3.把本地的背景圖片加到這個窗口中,作為這個窗口的背景圖:
使用的到的類有BufferedImage和 ImageIO這兩個類,這兩個類是專門用來處理這種功能的。主要的代碼如下:
BufferedImage bg = null;bg = ImageIO.read(new File(“e:/background.jpg”));g.drawImage(bg,0,0,this);這樣這個圖片就加到了這個窗口的背景去了。
這里有一個改進就是雙緩沖技術(shù),可以防止閃屏。這個技術(shù)就是在界面和內(nèi)存都有一幅圖,我們的改動不是直接畫界面,而是內(nèi)存中先畫好然后把內(nèi)存中直接顯示出來,那樣就沒有了一前一后的,那就沒有了閃屏的事情發(fā)生了。
4.就是畫棋盤和寫一些游戲信息:
這步比較簡單,也沒什么可以說的,用到的一些畫線的函數(shù),和寫String的一些函數(shù)。
以上做完以后就可以出現(xiàn)以下的界面:
1.我的第二步就是增加對mouse的點擊和移動的處理,這樣以后就可以用來下棋。在這個過程的要使用到以下的步驟: 1.增加對mouse的監(jiān)視,然后重寫它的一些函數(shù):
1.我們在ChessFrame的構(gòu)造函數(shù)中加入了addMouseListener()函數(shù),然后重寫關(guān)于這個的四個函數(shù),我們這這里不重寫所有的函數(shù),就改寫一個MousePress函數(shù)就可以了。改寫的代碼如下:
public void mousePress(MouseEvent arg0){
this.x = arg0.getX();this.y = arg0.getY();if(this.canplay)
} this.repaint();現(xiàn)在要處理的就是加上棋子了,我在這個做了一下小改動可以更加準(zhǔn)確的定位下棋的位置:
if(x >= 10 && x <= 374 && y >= 72 && y <= 450){
int sx1 =(this.x72)/ 20;int yx1 =(this.x72)% 20;if(yx1 >= 10){ } if(yy2 >= 10){ } sy2++;sx1++;就是這個,我們通過監(jiān)控鼠標(biāo)的就可以得到點擊的X,Y坐標(biāo),我在這里通過對它求余,假如余數(shù)大于10(就是一個格子的一半)那就給+1,不然不變。后面的畫棋子是很簡單的一個過程,使用的是現(xiàn)成的函數(shù)(drawoval)
2.這部要做的就是記錄棋子和五子連的判斷:
1.我們通過一個數(shù)組int給保存棋子,如果是0就是沒子,1表示是黑子,2表示白子。在每次重繪的時候遍歷這個數(shù)組顯示,這樣就可以保存棋子了。2.判斷五子連起來然后獲勝的算法: 這個算法是鑒戒例子上的:
private boolean isline(int x, int y, int xchange, int ychange, int color){
int tempx = xchange;int tempy = ychange;int count = 1;while(x + xchange >= 0 && y + ychange >= 0
&& color == chess1[x + xchange][y + ychange]){ count++;if(xchange!= 0){ } if(ychange!= 0){ if(ychange < 0){ xchange++;
}
}
}
} ychange--;ychange++;} else { xchange = tempx;ychange = tempy;while(xychange >= 0
} if(count >= 5){
} return true;return false;} else { && color == chess1[xychange]){ count++;if(xchange!= 0){ } if(ychange!= 0){
} if(ychange < 0){
} ychange--;ychange++;} else { xchange++;中心思想就是要判斷就要判斷8個方向,其中有的只是相反的方向,我們使用關(guān)于X,Y的相對的變化來判斷,并且使用count來計數(shù),如果到了5個就可以判斷勝利啦。
1.我的第三步就是時間的變化和一些鍵的設(shè)置
1.關(guān)于時間的變化主要是在于線程的使用,這里我們這個JFrame它繼承了Runnable 這個接口,不過我們要重寫Run函數(shù),這個run函數(shù)的代碼如下: public void run(){
if(this.second > 0){
while(true){
this.repaint();if(this.isblack){
this.ss1--;
if(this.ss1 == 0){
JOptionPane
.showMessageDialog(this, “黑方超時~~~~?¤游戲結(jié)束”);
this.message1=“0:0:0”;
{
“白方超時~~~~?¤?¤游戲結(jié)束”);this.message2=“0:0:0”;this.canplay = false;
{
{ }
this.ss2--;
if(this.ss2 == 0){
this.message1 = this.ss
1/ 3600 + “ : ”
+(this.ss1 / 60this.ss1 / 60 *
this.ss1=-1;
this.canplay = false;
}else if(this.ss1>0)3600 * 60)60this.ss2 / 3600 + “ : ”
+(this.ss2this.ss2 / 3600 * 60 * 60);
this.repaint();}else { }
try {
}
Thread.sleep(1000);e.printStackTrace();} catch(InterruptedException e){ 這個函數(shù)是用來事時間的變化,所以每操作以后就讓線程sleep(1000)就可以了,那樣就是一秒鐘。這樣就可以倒計時了。2.現(xiàn)在我們要點擊一個按鈕要它有響應(yīng)。
這里我們其實就沒用到什么button,那為什么會有反應(yīng)呢,因為我們通過鼠標(biāo)的點擊范圍來確定要響應(yīng)什么函數(shù),這就是這里面的秘密.在public void mouseClicked(MouseEvent arg0)函數(shù)里有下面這些if的判斷
if(x1 >= 404 && x1 <= 473 && y1 >= 74 && y1 <= 103)if(x1 >= 404 && x1 <= 473 && y1 >= 127 && y1 <= 155)if(x1 >= 404 && x1 <= 473 && y1 >= 179 && y1 <= 208)if(x1 >= 404 && x1 <= 473 && y1 >= 286 && y1 <= 316)if(x1 >= 404 && x1 <= 473 && y1 >= 338 && y1 <= 367)if(x1 >= 404 && x1 <= 473 && y1 >= 390 && y1 <= 419)這就是為了確定鼠標(biāo)的范圍,然后相對調(diào)用函數(shù)。
其他還有就是一些Debug處理,在程序已經(jīng)處理了,結(jié)果的還是蠻可以處理的,不過只能是人人對戰(zhàn)。
四、實驗心得與小結(jié)
這次試驗總的來說沒有想像中那么難,還有視屏的幫助,感覺起還是很容易動手的,不過由于自己沒上心,沒有做比較大的改動,最主要的人機的對戰(zhàn)沒做出來是滿遺憾的,不過通過這個試驗,讓我學(xué)習(xí)了不少的知識,比如雙緩沖,mouselistener 等許多許多的知識,還有關(guān)于五子棋算法的設(shè)計也是一部分。不管怎么說還是有學(xué)到知識的,沒什么改動,但對現(xiàn)有的知識的掌握還是很可以的。
五、指導(dǎo)教師評議
成績評定:
指導(dǎo)教師簽名:
第五篇:五子棋游戲軟件工程課程設(shè)計
軟件工程設(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ī)格說明,進而建立軟件開發(fā)的基礎(chǔ)。實踐表明,需求分析工作進行得好壞,在很大程度上決定了軟件開發(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ù),如果遇到對方的子、空白點或邊界就停止查找。左邊完成后再向右進行同樣的操作;最后把左右兩邊的記錄合并起來,得到的數(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ù)測后的棋進行盤面分析,如果出現(xiàn)了‘四三’、‘雙三’或‘雙四’等制勝點,那么己方就可以獲勝了(當(dāng)然對黑棋而言‘雙三’、‘雙四’是禁手,另當(dāng)別論);否則照同樣的方法向下分析,就可預(yù)測出第二步、第三步??
等一等,要是盤面上沒有對手必須防的棋型,哪該怎么辦呢?進攻不成的話就得考慮防守了,將自己和對手調(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)也有很多不足的地方,第一次進行獨立的課程設(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ù)進行或輸出結(jié)果。程序中,“循環(huán)”的利用非常直接和清晰,雙方交替下棋,因此循環(huán)往復(fù)。最終決出勝負(fù)或最終平局。分析時,也考慮了許多種情況,針對各個情況均作出了相對措施和解決方案。
程序采用循環(huán)進行雙方交替下棋,并進行了很多判斷。首先判斷棋盤是否已滿,若棋盤已滿,則輸出平局,結(jié)束游戲;若棋盤未滿,則繼續(xù)進行。然后判斷“0”方是否勝出,若“0”方獲勝,則輸出“0”方獲勝,結(jié)束游戲;若“0”方?jīng)]有獲勝,則繼續(xù)進行。再判斷“x”方是否獲勝,若“x”方獲勝,則輸出“x”方獲勝,結(jié)束游戲;若“x”方?jīng)]有獲勝,則繼續(xù)進行?;氐健笆紫取钡呐袛?。如此循環(huán)??
軟件工程設(shè)計
第四章 運行結(jié)果
圖4.1 運行結(jié)果初始圖
圖4.2 游戲過程圖
圖4.3
軟件工程設(shè)計
圖4.4
圖4.5
軟件工程設(shè)計
圖4.6
圖4.7
軟件工程設(shè)計
圖4.8 游戲進行圖
圖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++)
//打印棋盤
{