軟件工程畢業(yè)論文-五子棋對戰(zhàn)游戲平臺的設計與實現(xiàn)_第1頁
已閱讀1頁,還剩28頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、<p><b>  本科畢業(yè)論文</b></p><p><b>  (20 屆)</b></p><p>  五子棋對戰(zhàn)游戲平臺的設計與實現(xiàn)</p><p><b>  摘要</b></p><p>  五子棋作為一個棋類競技運動,在民間十分流行,為了熟悉五子棋規(guī)

2、則及技巧,以及研究簡單的人工智能,決定用Java開發(fā)五子棋游戲。主要完成了人機對戰(zhàn)以及玩家和玩家對戰(zhàn)這兩個功能。在人機對弈中通過深度搜索和估值模塊,來提高電腦棋手的智能。分析估值模塊中的影響精準性的幾個要素,以及提出若干提高精準性的辦法,以及對它們搜索的節(jié)點數(shù)進行比較,在這些算法的基礎上分析一些提高電腦AI方案,如遞歸算法、電腦學習等。算法的研究有助于理解程序結(jié)構(gòu),增強邏輯思維能力,在其他人工智能方面也有很大的參考作用。</p&g

3、t;<p>  本文主要講的是用Eclipse開發(fā)工具與Java開發(fā)語言開發(fā)的一個直觀大方的自定義界面的帶部分AI功能的五子棋游戲,游戲程序?qū)崿F(xiàn)人機對弈和人人對弈,自動智能計算最佳落子位置,而且程序能夠自動的判定游戲的獲勝方和游戲的結(jié)束與否,實現(xiàn)對戰(zhàn)雙方順利進行博弈。</p><p>  關(guān)鍵詞:深度搜索;估值;電腦AI;五子棋;算法</p><p><b>  A

4、bstract</b></p><p>  As a sport, gobang is very popular in civil, in order to become familiar with gobang rules and techniques, and the study of simple artificial intelligence, I decide to use the Java

5、 to develope gobang games and complete the two functions including man-machine war and man-man war. Network Connection is Socket Programming for some applications, client and server interaction is definited by Class Mess

6、age, which is a very good scalability, Client interface is responsible for the collection and mainte</p><p>  Keywords: Search depth; Valuation; Computer AI; Gobang ; Algorithm </p><p><b>

7、  目 錄</b></p><p><b>  1引言1</b></p><p>  1.1選題背景1</p><p>  1.2本課題研究的意義1</p><p>  1.3本課題的研究方法2</p><p>  2課題相關(guān)基礎2</p><

8、p><b>  2.1五子棋2</b></p><p>  2.1.1棋盤和棋子2</p><p>  2.1.2規(guī)則及解釋3</p><p>  2.1.3五子棋常用術(shù)語4</p><p>  2.1.4五子棋攻防6</p><p><b>  2.2Java

9、7</b></p><p>  2.2.1Java簡介7</p><p>  2.2.2Java開發(fā)環(huán)境9</p><p>  3課題詳細研究方法10</p><p>  3.1程序結(jié)構(gòu)說明10</p><p>  3.2棋盤及棋子的類11</p><p>  3.

10、2.1棋盤11</p><p>  3.2.2棋子13</p><p>  3.3勝負判斷條件16</p><p>  3.4電腦AI17</p><p><b>  結(jié)論22</b></p><p><b>  參考文獻23</b></p>

11、<p><b>  致謝24</b></p><p><b>  引言</b></p><p><b>  選題背景</b></p><p>  五子棋是起源于中國古代的傳統(tǒng)黑白棋種之一?,F(xiàn)代五子棋日文稱之為連珠,英譯為Renju,英文稱之為Gobang或FIR(Five in a Ro

12、w 的縮寫),亦有連五子、五子連、串珠、五目、五目碰、五格等多種稱謂。</p><p>  五子棋起源于古代中國,發(fā)展于日本,風靡于歐洲。對于它與圍棋的關(guān)系有兩種說法,一說早于圍棋,早在 “ 堯造圍棋 ” 之前,民間就已有五子棋游戲;一說源于圍棋,是圍棋發(fā)展的一個分支。在中國的文化里,倍受人們的青睞。本世紀初五子棋傳入歐洲并迅速風靡全歐。通過一系列的變化,使五子棋這一簡單的游戲復雜化、規(guī)范化,而最終成為今天的職業(yè)

13、連珠五子棋,同時也成為一種國際比賽棋。</p><p>  Java語言是當今最為流行的程序設計語言之一 作為一門非常優(yōu)秀和極為健壯的編程語言,它同時具有的面向?qū)ο?,與平臺無關(guān),分布式應用,安全,穩(wěn)定和多線程等優(yōu)良的特征,使用Java語言,不僅可以開發(fā)出功能強大的大型應用程序,而且Java語言本身突出的跨平臺的特性也使得它特別適合于Internet上的應用開發(fā),可以這樣說,Java的出現(xiàn)使得所開發(fā)的應用程序“一次

14、編寫,處處可用”的實現(xiàn)成為了可能。

15、 </p><p><b>  本課題研究的意義</b></p><p>  近來隨著計算機的快速發(fā)展,各種各樣的電腦游戲?qū)映霾桓F,使得我們能有更多的娛樂項目,而棋類游

16、戲能起到鍛煉人的思維和修身養(yǎng)性的作用,而且棋類游戲水平頗高,大有與人腦分庭抗禮之勢。其中戰(zhàn)勝過國際象棋世界冠軍-卡斯帕羅夫的“深藍”便是最具說服力的代表;其它像圍棋的“手淡”、象棋的“將族”等也以其優(yōu)秀的人工智能深受棋迷喜愛。 </p><p>  越來越多的具有智能的機器進入了人類的生活,人工智能的重要性如今顯而易見。自己對人工智能比較感興趣,而五子棋游戲程序的開發(fā)實現(xiàn)這個課題,正好提供給我這樣一個研究的

17、機會,通過對人工智能中博弈方面的研究(人機對弈),讓我在簡單的人機對弈全局設計,以及具體到相關(guān)算法上有了深入的了解。人工智能屬于計算機科學的領(lǐng)域,它以計算機技術(shù)為基礎,近幾十年來,它的理論和技術(shù)已經(jīng)日益成熟,應用領(lǐng)域也正在不斷擴大,顯示出強大的生命力。人工智能大致可以分成幾個學科,它們每一個都是獨特的,但是它們常常又互相結(jié)合起來完成設計任務,這時,這些學科之間的差別就變的很模糊。人工智能在專家系統(tǒng),自然語言理解,自動定理證明,自動程序設

18、計,人工智能在機器人學、模式識別、物景分析、數(shù)據(jù)庫的智能檢索、機器下棋(實質(zhì)上是博弈論問題)和家用電器智能化等領(lǐng)域都有廣泛的應用。而這個課題就是和人工智能中的博弈論領(lǐng)域緊密相關(guān)的。</p><p>  這個題目核心是人工智能和Socekt編程,。并且人工智能中的博弈部分,由于采用了大量的搜索算法,其中很多被利用到各方面。它的概念、方法和技術(shù),正在各行各業(yè)廣泛滲透。智能已經(jīng)成為當今各種新產(chǎn)品、新裝備的發(fā)展方向。所以

19、,趁著這個機會,對人工智能中比較容易實現(xiàn)的人機博弈進行了解研究學習,也是很實用且很有必要的。</p><p><b>  本課題的研究方法</b></p><p>  在進行游戲設計之前,首先決定的第一個問題就是,使用什么開發(fā)環(huán)境來編寫環(huán)境? 自己雖然比較熟悉Java語言,但是實際開發(fā)項目經(jīng)驗很少,所以決定用Jcreator,其擁有高亮語法編輯、使用向?qū)б约巴耆ㄖ频?/p>

20、用戶界面,最主要的是能夠自動查找文件于 Main 方法或 Html 文件以支持Java 小應用程序,然后啟動相應的工具。</p><p>  其次確定整個程序的結(jié)構(gòu)框架。由于Applet運行速度較慢,如果在加上算法搜索時間,顯然不符合程序的設計要求,決定用Java應用程序開發(fā).整個程序的功能實現(xiàn)流程是這樣的:網(wǎng)絡對戰(zhàn)涉及算法較少,所以先實現(xiàn)網(wǎng)絡部分,實現(xiàn)基本的棋盤和棋子的類,添加判斷勝負條件,這部是基礎,也是很重

21、要的,電腦AI也在這些基礎上添加上來的。這個題目的2個功能包括2個重要算法,電腦AI和勝負條件,勝負條件運算量不大,有固定的模式。難點是人工智能,可以這樣說,人工智能的好壞決定了這個題目的完成深度。所以,大部份時間花在AI算法的研究和改進上,對于算法我掌握的不多,研究了一些國內(nèi)的五子棋算法,參考了一些游戲設計算法,詳細比較各種算法的優(yōu)缺點,而且參考了現(xiàn)代五子棋比賽的各種規(guī)則和技巧,盡量聯(lián)系實際,努力提高電腦AI。</p>

22、<p><b>  課題相關(guān)基礎</b></p><p><b>  五子棋</b></p><p><b>  棋盤和棋子</b></p><p>  現(xiàn)代五子棋棋盤,經(jīng)過國際棋聯(lián)的多次修改,最終定為15 X 15路,即棋盤由橫豎各15條平行線交叉組成,共有225個交叉點;棋盤上共有五個星

23、位,中間的星位稱為天元,周圍四點為小星,與圍棋盤略有不同。見圖2-1</p><p><b>  。</b></p><p><b>  圖2-1 棋盤</b></p><p>  五子棋的棋子和圍棋相同,分黑白2種顏色,通常為散圓形,有一面凸起或二面凸起等形狀,一副棋子總數(shù)為225枚,其中黑子113枚,白子112枚。&l

24、t;/p><p>  關(guān)于計時,正規(guī)比賽按不同級別設置了不同的時間限制,一般的玩家都沒有這個限制。</p><p><b>  規(guī)則及解釋</b></p><p>  1:黑棋先行,白棋隨后。從天元開始相互順序落子。</p><p>  2:最先在棋盤的橫向、豎向、斜向形成連續(xù)的相同色五個棋子的一方為勝利。</p>

25、;<p>  3:黑棋禁手判負、白棋無禁手。黑棋禁手包括“三、三”;“四、四”;“長連”。黑方只能用“四、三”去取勝。</p><p>  4:如分不出勝負,則定位平局。</p><p>  5:對局中拔子、中途退場均判為負</p><p>  6:五連與禁手同時形成,先五為勝。</p><p>  7:黑方禁手形成時,白方應立

26、即指出。若白方未發(fā)現(xiàn)或發(fā)現(xiàn)后不立即指正,反而繼續(xù)落子,則不能判黑方負。 </p><p>  五子棋是由兩個人在一盤棋上進行對抗的競技運動。在對局開始時,先由執(zhí)黑棋的一方將一枚棋子的落在“天元”上,然后由執(zhí)白棋的一方在黑棋周圍的交叉點上落子。如此輪流落子直到某一方首先在棋盤的直線 橫線或斜線上形成連續(xù)的五子或五子以上,則該方就算獲勝。但是五子棋的特點是先行的一方優(yōu)勢很大。因此,在職業(yè)比賽種對黑方做了種種限制,以利

27、公平競爭。黑白雙方的勝負結(jié)果必須按照職業(yè)五子棋的規(guī)則要求來決定。</p><p>  五子棋常用術(shù)語 </p><p>  二:二是五子棋的一切進攻的基礎;又分為活二和死二。</p><p>  活二:即再下一子可形成活三的二,見圖2-2。</p><p>  死二:即再下一子可形成死三的二,見圖2-3。</p><

28、p>  圖 2-2 活二 圖2-3 死二</p><p>  三:三是五子棋最常見的攻擊手段。三分為活三、死三、眠三。</p><p>  活三:為再下一子即可變成活四的三(活四介紹見后)?;蛉譃檫B三、跳三。見圖2-4。</p><p>  我們通常所說的“三”。就是指活三而言。如

29、果是死三,將特別指出。</p><p>  死三:即對方有棋子在同一條線相鄰交叉點防守的三;死三分為三種。見圖2-5。 </p><p>  眠三:是死三的一種特性,它看上去相鄰點沒有對方棋子防守,很像活三,但由于受空間限制,不論如何發(fā)展都不可能稱為活四,故稱為“眠三“。見圖2-5。</p><p>  圖2-4 活三

30、 圖2-5 死三</p><p>  反三:反三不是指一種“三”的形狀,而是指再阻止對方進攻的同時使自己稱為一道活三的反攻,稱為反三。</p><p>  四:四的形狀有三種,它分為:活四,沖四、跳沖四。</p><p>  活四:在同一條線上相連的四個同色棋子成為“連五”,如圖2-6所示。</p><p>  沖四:在同

31、一條線上相連的相同顏色的四個棋子,它與活四不同的是,其中的一端有對方的棋子進行阻擋,它只有再在另一端下一手棋才可形成“連五”。 </p><p>  跳沖四:它的形狀在“四”中是比較特殊的,一般分為兩種,它的特點是同一條線上的同色的四個棋子,有一個或兩個棋子與另外三個或兩個棋子之間有一個交叉點的間隔,它的下一手棋只有下在間隔的交叉點上才能形成“連五”,因此,對方的棋子防守時,也只能阻擋在間隔的交叉點上,見圖2-7

32、。</p><p>  圖2-7 跳沖四 圖2-8 反沖四</p><p>  如圖2-8,黑棋在1點進攻,形成一子雙殺,這時白棋的妙手是在a位活三,它同時阻擋了黑棋的兩種取勝方法。當黑棋仍在c位跳沖四活三時,白棋即在b位阻斷黑棋沖四并形成反沖四,是黑棋的進攻功虧一簣。</p><p>  一子

33、雙殺:指用同一手棋同時形成兩個勝點的著法。 </p><p>  追下取勝:是指白棋逼迫黑棋形成禁手而取勝的方法。</p><p>  自由獲勝:除了追下取勝以外的獲勝方法,稱之為自由取勝。</p><p>  禁手(Forbidden):指黑方一子落下同時形成兩個或兩個以上的活三、沖四或形成長連的棋形,是對局中

34、對黑棋禁止使用的戰(zhàn)術(shù)或被判為負的行棋手段,見圖15。白棋無禁手,如果黑子在落下的關(guān)鍵的第五子即形成五連的同時,又形成禁手。此時,因黑方已成連五,故禁手失效,黑方勝利。之所以這么規(guī)定也是為了規(guī)范比賽,其實我們業(yè)余的棋手,黑白棋子誰先下都不限制,只是先落子會有比較大的優(yōu)勢,另一方始終處于防守的被動狀態(tài)。所以那一方先下子,他就有禁手,這是為了保持公平的一種手段。但是職業(yè)連珠五子棋雖然對黑棋采取了種限制,但是先行的一方優(yōu)勢依然很大。在高段位的比

35、賽中還添加了一些規(guī)定,由于很少用到,就不必詳細敘述了。</p><p>  A B C D</p><p>  E F </p><p><b>  圖2-9 禁手</b></p>&

36、lt;p>  見圖9。A、B、C 中的 x 點為三、三禁手。D、E 中的 X 點為四、四禁手。F中的 X 點為長連禁手。</p><p>  長連:相同顏色的連續(xù)六子或六子以上。 </p><p><b>  五子棋攻防</b></p><p>  五子棋是一項對抗性很強的運動,在開局進入五手兩打后,就開始進入了白刃戰(zhàn),相互爭奪先手,任何

37、一方都不能掉以輕心,要盡可能少犯錯誤,甚至不犯錯誤,否則將會導致速敗。</p><p>  眾所周知,連珠五子,連五為勝。有四才能有五,有三才有四,以此類推。所以,在五子棋的對局眾進攻和防守都是從“二”和“三”的爭奪開始的?!昂玫拈_始是成功的一半”,這條格言用在五子棋里再合適不過了。</p><p>  五子棋的點的選擇十分關(guān)鍵。五子棋實際上是通過選擇最佳的落點,加上正確的落子次序,一步一

38、步地占領(lǐng)各個要點,最終獲得勝利。</p><p>  對局的早期,選點的著眼點主要是使本方的棋子保持聯(lián)系,為以后創(chuàng)造盡可能多的成三、成四的機會,同時盡量限制對方成為好形。由于在五子棋對弈過程中,通過行棋落點來控制對方的落點是可能的,比如活三 沖四的應點是可以預知的,完全有可能通過不斷走出這樣的先手來控制對方的著點直至勝利。所以,在對局的后期,就要在精確計算的前提下,盡早發(fā)動攻勢,以取得棋局的控制權(quán),否則一旦貽誤戰(zhàn)

39、機,被對方搶先發(fā)動攻勢,就會成為被控制的一方。</p><p>  當有多個攻擊點可供選擇時,要選擇后續(xù)手段多,又不會被對方反先的著點。如果是黑方,還特別要注意進攻終被對方反擊時出現(xiàn)的各種禁手點的可能性。 </p><p>  進攻分為單攻棋和雙攻棋,單攻棋指單線即單行或單向的攻棋子,包括三子攻棋(活三、填四)和四子攻棋(沖四、填五)。而雙攻棋指雙

40、向或雙行的攻棋。包括三、三攻棋(雙活三、雙填四、填四活三);四、三攻棋(沖四活三、沖四填四、填五活三、填五填四);四四攻棋(雙沖四、雙填五、填五沖四)。</p><p>  五子棋的取勝思路是由一個子開始,目標是運用各種方法在棋盤上發(fā)展出五連乃至長連而取勝。在這個發(fā)展過程中必然要經(jīng)過由一子到兩子 兩子到三子 三子到四子的過程。因此說,把各種形狀和各個方面上的二 三 四等子力結(jié)構(gòu)爛熟于胸,做到舉一反三,是學習五子棋

41、的基本功,更是能靈活運用五種取勝技巧的基礎。</p><p><b>  2.2Java</b></p><p>  2.2.1Java簡介</p><p>  Java是美國Sun公司開發(fā)的語言,它使用解釋器執(zhí)行代碼,因此,無需對源代碼進行任何更改即可在不同計算機上運行,是真正跨平臺的編程開發(fā)語言。

42、 </p><p>  Java有以下主要特點:</p><p>  1:簡單(Simple)</p><p>  制定Java的原則之一,是要建立一種結(jié)構(gòu)簡單而且使用容易的系統(tǒng),可以讓用戶不必接受很深的訓練就可以開始設計程序,所以Java的語法盡可能與在當前許多程序設計師都采用的C及C++語言相似。并且,Java刪除了C及C++許多極少使用、不易理解或常被混淆

43、的功能,多多重繼承、指針等。</p><p>  2:面向?qū)ο?Object-Oriented)</p><p>  面向?qū)ο笫墙陙硇畔⒔鐝V為使用的概念和技術(shù)。它有許多良好的特性。對象的封裝性可以使對象的接口定義明確;繼承性可以增加軟件的可重用性,有助于分類及模版設計等。實現(xiàn)面向?qū)ο蟮母拍罴捌涓鞣N良好的特性是Java的設計理念之一。</p><p>  3:分布式

44、(Distributed)</p><p>  計算機網(wǎng)絡的發(fā)展使得信息應用朝著分布式的環(huán)境發(fā)展,所以現(xiàn)代的信息開發(fā)語言及環(huán)境要有配合分布式的特性及功能。Java具有一個網(wǎng)絡功能的程序庫,其中包含與如HTTP和FTP等TCP/IP網(wǎng)絡通信協(xié)議整合的能力。</p><p>  4:強壯性(Robust)</p><p>  由Java所編寫的程序要能在各種情況下運行,

45、而且必須具有高的穩(wěn)定性。Java在制定時即加入了能防止存儲器被覆寫和數(shù)據(jù)損壞的相關(guān)處理機制。</p><p>  5:安全性(Secure)</p><p>  Java是被設計用于網(wǎng)絡及分布式環(huán)境中的,所以安全性是一個很重要的考慮。Java擁有數(shù)個從簡單到復雜的安全保護措施,能有效地防止病毒的侵入和破壞行為的發(fā)生。</p><p>  6:結(jié)構(gòu)中立性(Archit

46、ecture Neutral)</p><p>  在網(wǎng)絡上存在許多不同類型的計算機,從中央處理器到操作系統(tǒng)的機構(gòu)均有很高的差異性。因此要使應用程序在每一種機器上均能運行是相當困難的。針對這個目的,Java的編譯器可以產(chǎn)生一種結(jié)構(gòu)中立的目標碼文件格式――字節(jié)碼(Byte Code)。這種字節(jié)碼可以在許多種不同的計算機上運行。</p><p>  7:多線程(Multithreaded)&l

47、t;/p><p>  多線程是開發(fā)復雜和功能強大的程序所必須的手段之一,Java同樣支持這個重要功能。</p><p>  一個Java程序的開發(fā)過程如圖3-1所示。</p><p>  圖3-1 Java程序的開發(fā)過程</p><p>  源文件:使用一個文本編輯器,如Edit或記事本來編寫源文件。不可使用Word編輯器,因為它含有不可見字符

48、。將編好的源文件保存起來,源文件的擴展名必須是Java。</p><p>  編譯器:源文件要經(jīng)過編譯器(Javac.exe)的編譯生成可擴展名為.Class的字節(jié)碼文件。字節(jié)碼文件是由與平臺無關(guān)的二進制碼組成的,執(zhí)行時由解釋器解釋成本地機器碼。</p><p>  運行Java程序:Java程序分為兩大類——Java應用程序(Application)和Java小應用程序(Applet)。

49、Java應用程序必須通過Java解釋器(java.exe)來解釋執(zhí)行其字節(jié)碼文件;Java小應用程序可通過支持Java標準的瀏覽器來解釋執(zhí)行。</p><p>  2.2.2Java開發(fā)環(huán)境</p><p>  使用Eclipse開發(fā)環(huán)境必須安裝JDK,我安裝的版本是1.5.0,在環(huán)境變量里新建名為Path的變量名,變量值為D:\軟件\JAVA\bin(根據(jù)JDK的安裝目錄而定)。在命令提

50、示窗口輸入Java -version如果能正確顯示版本號,則表示環(huán)境配置成功。如圖3-2所示。</p><p><b>  圖3-2 環(huán)境變量</b></p><p>  Eclipse的安裝很簡單,這里不在詳細敘述,把路徑配置好就可以了。如圖3-3。</p><p>  圖3-3 Eclipse IDE </p>&l

51、t;p><b>  課題詳細研究方法</b></p><p><b>  程序結(jié)構(gòu)說明</b></p><p>  既然是Java Application,要實現(xiàn)網(wǎng)絡對戰(zhàn),故采用C/S模式編寫,程序包含3個獨立的類文件-Chess.java、FiveChessFrame.java、FrameSize.java。</p><

52、;p>  其中FrameSize.java主要負責定義窗口的尺寸。FiveChessFrame.java定義了主窗體的各種功能以及實現(xiàn)。Chess.java中包含了程序的入口以及各種事件。見圖4-1。</p><p>  棋盤及棋子的類 </p><p><b>  棋盤</b></p><p>  圖3

53、.2.1棋盤的繪制</p><p><b>  棋盤的繪制:</b></p><p>  public FiveChessFrame() {</p><p>  this.setTitle("五子棋");</p><p>  this.setSize(680, 580);</p><

54、;p>  this.setLocation((width - 680) / 2, (height - 580) / 2);</p><p>  this.setResizable(false);</p><p>  this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);</p><p>  this.addMo

55、useListener(this);</p><p>  th.start();</p><p>  th.suspend();</p><p>  this.repaint();</p><p><b>  try {</b></p><p>  bgImage1 = ImageIO.read(

56、new File("./chessimage/圍棋圖片1.jpg"));</p><p>  bgImage2 = ImageIO.read(new File("./chessimage/人人對戰(zhàn).png"));</p><p>  bgImage3 = ImageIO.read(new File("./chessimage/人機對戰(zhàn).pn

57、g"));</p><p>  bgImage4 = ImageIO.read(new File("./chessimage/重新開始.png"));</p><p>  bgImage5 = ImageIO.read(new File("./chessimage/時間設置.png"));</p><p>  bgI

58、mage6 = ImageIO.read(new File("./chessimage/悔棋.png"));</p><p>  bgImage7 = ImageIO.read(new File("./chessimage/認輸.png"));</p><p>  bgImage8 = ImageIO.read(new File("./ch

59、essimage/游戲說明.png"));</p><p>  bgImage9 = ImageIO.read(new File("./chessimage/返回.png"));</p><p>  // bgImageBlack = ImageIO.read(new File("D:/我的文檔/Desktop/黑子.png"));<

60、/p><p>  // bgImageWhite = ImageIO.read(new File("D:/我的文檔/Desktop/白子1.png"));</p><p>  // bgImage1 = ImageIO.read(new</p><p>  // File("D:/我的文檔/Desktop/新建文件夾/開始游戲.png&qu

61、ot;));</p><p>  } catch (IOException e) {</p><p>  // TODO Auto-generated catch block</p><p>  e.printStackTrace();</p><p><b>  }</b></p><p>  

62、this.setVisible(true);</p><p><b>  }</b></p><p>  棋盤繪制設置了窗口的各種屬性,并設置并顯示了程序中用到了圖片。</p><p><b>  棋子</b></p><p><b>  圖3.2棋子</b></p>

63、;<p>  public void paint(Graphics g) {</p><p>  // 雙緩沖技術(shù)防止屏幕閃爍</p><p>  BufferedImage buff = new BufferedImage(680, 580,</p><p>  BufferedImage.TYPE_INT_ARGB);</p><

64、;p>  Graphics g1 = buff.createGraphics();</p><p>  g1.setColor(Color.BLACK);</p><p>  g1.drawImage(bgImage1, 0, 28, this);</p><p>  g1.drawImage(bgImage2, 545, 110, this);</p&

65、gt;<p>  g1.drawImage(bgImage3, 545, 155, this);</p><p>  g1.drawImage(bgImage4, 545, 200, this);</p><p>  g1.drawImage(bgImage5, 545, 245, this);</p><p>  g1.drawImage(bgIma

66、ge6, 545, 310, this);</p><p>  g1.drawImage(bgImage7, 545, 355, this);</p><p>  g1.drawImage(bgImage8, 545, 400, this);</p><p>  g1.drawImage(bgImage9, 545, 445, this);</p>&

67、lt;p>  g1.setFont(new Font("華文行楷", 0, 40));</p><p>  g1.drawString("游戲信息: " + message, 120, 85);</p><p>  g1.setFont(new Font("華文隸書", 0, 20));</p><p&g

68、t;  g1.drawString("黑方時間:" + blackMessage, 100, 545);</p><p>  g1.drawString("白方時間:" + whiteMessage, 305, 545);</p><p>  for (int i = 0; i < 15; i++) {</p><p>

69、  g1.drawLine(80, 100 + 30 * i, 500, 100 + 30 * i);</p><p>  g1.drawLine(80 + 30 * i, 100, 80 + 30 * i, 520);</p><p><b>  }</b></p><p>  g1.fillOval(167, 187, 6, 6);<

70、/p><p>  g1.fillOval(287, 187, 6, 6);</p><p>  g1.fillOval(407, 187, 6, 6);</p><p>  g1.fillOval(167, 307, 6, 6);</p><p>  g1.fillOval(287, 307, 6, 6);</p><p>

71、;  g1.fillOval(407, 307, 6, 6);</p><p>  g1.fillOval(167, 427, 6, 6);</p><p>  g1.fillOval(287, 427, 6, 6);</p><p>  g1.fillOval(407, 427, 6, 6);</p><p>  for (int i =

72、0; i < 15; i++) {</p><p>  for (int j = 0; j < 15; j++) {</p><p>  if (allChess[i][j] == 1) {</p><p>  int tempx = i * 30 + 80;</p><p>  int tempy = j * 30 + 100;

73、</p><p>  // g1.drawImage(bgImageBlack, tempx - 17, tempx - 17, this);</p><p>  g1.setColor(Color.BLACK);</p><p>  g1.fillOval(tempx - 15, tempy - 15, 30, 30);</p><p>&

74、lt;b>  }</b></p><p>  if (allChess[i][j] == 2) {</p><p>  int tempx = i * 30 + 80;</p><p>  int tempy = j * 30 + 100;</p><p>  // g1.drawImage(bgImageWhite, te

75、mpx - 17, tempx - 17, this);</p><p>  g1.setColor(Color.WHITE);</p><p>  g1.fillOval(tempx - 15, tempy - 15, 30, 30);</p><p>  g1.setColor(Color.BLACK);</p><p>  g1.dra

76、wOval(tempx - 15, tempy - 15, 30, 30);</p><p><b>  }</b></p><p><b>  }</b></p><p><b>  }</b></p><p>  g.drawImage(buff, 0, 0, this);

77、</p><p><b>  }</b></p><p><b>  勝負判斷條件</b></p><p>  要判斷四個方向,橫向、豎向、以及2個斜向。思想還是比較簡單,相同顏色連成五子即勝利,網(wǎng)上有些網(wǎng)友評論說完整的判斷勝負條件包括連五和活四,我覺得完全沒必要,活四還要檢查兩邊的棋子,雖然運算量不大,但五子棋的標準就是

78、連五即勝,一步之差,我們既要遵守規(guī)則,也要簡化代碼實現(xiàn)盡完整的功能。</p><p>  我們要事先建立一個盤面數(shù)組allChess[ ][ ],即棋型表,數(shù)組的每一個元素對應棋盤上的一個交叉點,用‘0’表示空位,‘1’表示黑棋,‘2’表示白棋。由于代碼太多,下面給出了一般狀況的判斷勝負函數(shù),及以坐標(x,y)為中心的9X9矩形,只能在棋盤的內(nèi)部,如果超過棋盤,就要另外考慮。下面的代碼就是一般情況,整個矩形在棋盤

79、內(nèi)部的時候的判斷勝負條件,如圖4-2。</p><p><b>  圖4-2 獲勝</b></p><p>  private boolean checkWin() {</p><p>  boolean flag = false;</p><p>  // 判斷橫向是否有5個棋子相連,特點縱坐標相同,即allChess

80、【x】【y】中y值相同;</p><p>  int color = allChess[x][y];</p><p><b>  // 判斷橫向</b></p><p>  int count = this.checkCount(1, 0, color);</p><p>  if (count >= 5) {&l

81、t;/p><p>  flag = true;</p><p><b>  } else {</b></p><p><b>  // 判斷縱向</b></p><p>  count = this.checkCount(0, 1, color);</p><p>  if (c

82、ount >= 5) {</p><p>  flag = true;</p><p><b>  } else {</b></p><p>  // 判斷左下,右上</p><p>  count = this.checkCount(1, -1, color);</p><p>  if

83、(count >= 5) {</p><p>  flag = true;</p><p><b>  } else {</b></p><p>  // 判斷左上,右下</p><p>  count = this.checkCount(1, 1, color);</p><p>  if

84、 (count >= 5) {</p><p>  flag = true;</p><p><b>  }</b></p><p><b>  }</b></p><p><b>  }</b></p><p><b>  }</

85、b></p><p>  return flag;</p><p><b>  }</b></p><p>  為保證公平,先下子的就有禁手。但是我們一般沒有這個規(guī)則限制,都是輪流先下子。理論上是這樣的。但很多專家表明,先下子有很大的幾率獲勝,即使有禁手,先下子的一方還是有很大的優(yōu)勢,我覺得對于我們一般玩家而言,這些規(guī)定可以不考慮。<

86、;/p><p>  需要注意的一點是落下的棋子如果離任何一方的邊界小于4,則以邊界為限制判斷是否有一方獲勝,這樣的話也要考慮多種方向,但原理還是和基本情況是一樣的。</p><p><b>  電腦AI</b></p><p>  廣義上來講,博弈是指在一定的環(huán)境條件和一定的規(guī)則約束下,依靠自己所能夠掌握的信息,從各自選擇的行為或是策略進行選擇并加

87、以實施,并從各自取得相應結(jié)果或收益的過程。馮·諾伊曼(John von Neumann,1903-1957)和摩根斯坦恩(Oskar Margenstern, 1902-1977)在1944年出版了《博弈論與經(jīng)濟行為》(Theory of Games and Economic Behavior)一書中,最早地提出了關(guān)于博弈論的概念。但是,對于非合作、純競爭型博弈,諾伊曼所解決的只有二人零和博弈。在這里所抽象化后的博弈問題是,已

88、知參與者集合(兩方),策略集合(所有棋著),和盈利集合(贏子輸子),最終是想去找到一個理論上的解或平衡,也就是對參與雙方來說都最合理、最優(yōu)的具體策略。</p><p>  而在這里狹義的講,博弈論主要是研究棋手們落子中理性化、邏輯化的部分,并將其系統(tǒng)化為一門科學。換言之,博弈就是研究個體如何在錯綜復雜的相互影響中得出最合理的策略,博弈論正是衍生于古老的游戲或曰博弈如象棋、撲克等。數(shù)學家們將具體的問題抽象化,通過建

89、立自完備的邏輯框架、體系研究其規(guī)律及變化。</p><p>  參考了很多五子棋算法,大部分思想差不多,就是搜索估值確定重要性,然后選取最大的一個點下子。具體做法如下:為電腦和玩家各建立一張表,用來存放棋型數(shù)據(jù),比如“20”代表“沖四”的點,用“15”代表“活三”的點,那么在計算重要性時,就可以根據(jù)20>15得出前者比后者重要,下子時電腦便會自動選擇“沖四”的點,這里還要說明一點的事,還要考慮四個方向。因為

90、有可能有復合棋型,比如“四三”..從第一步起,不管是哪一方下子,電腦都有以這點為中心搜索9X9的矩陣內(nèi)的所有空白點上棋子的重要性,一顆棋子對棋型影響的大小有9X9。重要看來雖然說進攻和防守的重要性一樣的,但是我認為防守更重要。</p><p>  在估值的時候,必須要考慮棋子的合法落子情況。不同的棋類博弈,其估值必定有極大的差別,各種因為規(guī)則而造成的不同因素影響估值的設計。不同的棋類游戲各有所謂的規(guī)則,規(guī)則中就有

91、博弈雙方都可以走哪些著法。某些博弈游戲很容易就找到合理著法,我所實現(xiàn)的五子棋,它就具有很簡單的落子規(guī)則,即棋盤上所有的空位都可以落子,它們都是合理的著法。但是有些棋類游戲,比如在中國象棋和國際象棋中,情況就有些復雜了,每個棋子都有它特定的著法,</p><p>  電腦下子要考慮自己和玩家的棋型,優(yōu)先防守,如果沒有要防的棋型,則搜索自己的棋型下子。</p><p>  努力提高電腦AI一直

92、是五子棋游戲關(guān)鍵,第一步的人工智能只是估值和搜索算法的集合,要真正的提高電腦AI還有很多步,例如,我的電腦AI只是片面的分析了雙方的器型,沒有前瞻性。如果玩家多想幾步,電腦就發(fā)現(xiàn)不了。不過即使沒采用遞歸算法,要是讓電腦先下子的話,你的大部分時間也是花在防守上,可能是我的棋力太菜了,我自己還沒有下贏過電腦。</p><p>  目前有2種方法提高電腦棋力:一是遞歸算法,二是增加細致的特定棋形的判斷,鑒于自己對算法方

93、面欠缺甚多,沒有辦法完成這個功能,實在是遺憾。我大體說一下這2種算法的思路:遞歸算法的意思可以說成“今后幾步預測法”,首先讓電腦分析一個可能的點,如果在這兒下子將會形成對手不得不防守的棋型(例如:“沖四”、“活三”);那么下一步對手就會照你的思路來防守你,如此一來便完成了第一步的預測。這時候在調(diào)用盤面分析模塊對預測后的棋型進行分析,如果出現(xiàn)了“四三”、“雙三”或“雙四”等制勝點,那么己方就可以獲勝了。否則照同樣的方法向下分析,就可以預測

94、出多步。如果盤面上沒有對手必須防的棋型,進攻不成的話就得考慮防守了,將自己和對手調(diào)換一下位置,然后用上面的方法來預測對手的棋重要防守和攻擊都可以平衡,不過缺點是預測的算法量比較大。關(guān)于增加細致的特定棋形的判斷,前面已經(jīng)說過,以為不同的棋型,例如“死四”就有不同的幾種情況,如果對每一種設置不同的重要值,也可以提高電腦AI,但是要設置合適的分數(shù)就要在實踐中檢驗了,因為這個不是大小的問題,而是相差多少。正如前面所說,增加對細致棋型的判斷也會提

95、高電腦AI,雖然沒有遞歸算法明顯</p><p>  關(guān)于電腦學習,這聽起來似乎是算法無法實現(xiàn)的功能。但是在對弈中卻是非常有用的,但還只是些理論上的東西,比如棋局結(jié)束后,反向搜索,在自己的棋庫中設置相關(guān)記憶。但我并不以為這是很好的方法。因為用這種方法,很有可能它沒有找準原因,又或者進行學習的時候反而把劣等的學習進去;并且這種學習是很片面的,它只會認準一種極相似的情況(或者說一模一樣的棋局情況),而不會辨識出相似的

96、棋局情況。</p><p>  public void mousePressed(MouseEvent e) {</p><p>  x = e.getX();</p><p>  y = e.getY();</p><p>  if (x >= 80 && x <= 500 && y >=

97、100 && y <= 520) {</p><p>  if (canPlay) {</p><p>  if ((x - 80) % 30 < 15) {</p><p>  x = (x - 80) / 30;</p><p><b>  } else {</b></p>

98、<p>  x = (x - 80) / 30 + 1;</p><p><b>  }</b></p><p>  if ((y - 100) % 30 < 15) {</p><p>  y = (y - 100) / 30;</p><p><b>  } else {</b>

99、</p><p>  y = (y - 100) / 30 + 1;</p><p><b>  }</b></p><p>  if (allChess[x][y] == 0) {</p><p>  if (isBlack) {</p><p>  allChess[x][y] = 1;<

100、;/p><p>  repaint();</p><p>  if (mm == 1) {</p><p>  boolean winFlag = this.checkWin();</p><p>  if (winFlag) {</p><p>  JOptionPane.showMessageDialog(this,

101、"游戲結(jié)束"</p><p>  + (allChess[x][y] == 1 ? "黑方" : "白方")</p><p><b>  + "獲勝!");</b></p><p>  canPlay = false;</p><p>  t

102、h.suspend();</p><p>  repaint();</p><p><b>  }</b></p><p><b>  }</b></p><p>  repaint();</p><p>  // 保存x,y值,悔棋時用;</p><p&

103、gt;  tx[ti] = x;</p><p>  ty[ti] = y;</p><p><b>  ti++;</b></p><p>  if (mm == 1) {</p><p>  if (canPlay) {</p><p>  this.computerDo();</p&g

104、t;<p>  this.repaint();</p><p>  // 保存x,y值,悔棋時用;</p><p>  tx[ti] = x;</p><p>  ty[ti] = y;</p><p><b>  ti++;</b></p><p><b>  }<

105、/b></p><p><b>  } else {</b></p><p>  isBlack = false;</p><p>  message = "輪到白方";</p><p><b>  }</b></p><p><b>  

106、} else {</b></p><p>  if (mm == 0) {</p><p>  allChess[x][y] = 2;</p><p>  isBlack = true;</p><p>  message = "輪到黑方";</p><p>  tx[ti] = x;&

107、lt;/p><p>  ty[ti] = y;</p><p><b>  ti++;</b></p><p><b>  }</b></p><p><b>  }</b></p><p>  boolean winFlag = this.checkWin

108、();</p><p>  if (winFlag) {</p><p>  JOptionPane.showMessageDialog(this, "游戲結(jié)束"</p><p>  + (allChess[x][y] == 1 ? "黑方" : "白方") + "獲勝!");</

109、p><p>  canPlay = false;</p><p>  // th.stop();</p><p>  th.suspend();</p><p><b>  }</b></p><p><b>  } else {</b></p><p>

110、  JOptionPane.showMessageDialog(this, "當前位置已經(jīng)有棋子,請重新落子!");</p><p><b>  }</b></p><p>  this.repaint();</p><p><b>  } else {</b></p><p>

111、  JOptionPane.showMessageDialog(this, "請選擇作戰(zhàn)方式!");</p><p><b>  }</b></p><p><b>  }</b></p><p><b>  // 人人對戰(zhàn)按鈕</b></p><p>  

112、if (e.getX() >= 545 && e.getX() <= 626 && e.getY() >= 110&& e.getY() <= 135)</p><p><b>  {</b></p><p>  int result = JOptionPane.showConfirmDialog

113、(this, "是否確定選擇人人對戰(zhàn)?");</p><p>  if (result == 0) {</p><p><b>  mm = 0; </b></p><p>  for (int i = 0; i < 15; i++) {</p><p>  for (int j = 0; j

114、< 15; j++) {</p><p>  allChess[i][j] = 0;</p><p><b>  }</b></p><p><b>  }</b></p><p>  // th.start();</p><p>  message = "黑

115、方先行";</p><p>  isBlack = true;</p><p>  canPlay = true;</p><p>  blackTime = maxTime;</p><p>  whiteTime = maxTime;</p><p>  if (maxTime > 0) {<

116、/p><p>  blackMessage = blackTime / 3600 + ":" + (blackTime % 3600)</p><p>  / 60 + ":" + (blackTime % 3600) % 60;</p><p>  whiteMessage = whiteTime / 3600 + "

117、:" + (whiteTime % 3600)</p><p>  / 60 + ":" + (whiteTime % 3600) % 60;</p><p>  th.resume();</p><p><b>  } else {</b></p><p>  blackMessage =

118、 "無限制";</p><p>  whiteMessage = "無限制";</p><p><b>  }</b></p><p>  this.repaint();</p><p><b>  }</b></p><p><

119、b>  }</b></p><p><b>  // 人機對戰(zhàn)按鈕</b></p><p>  if (e.getX() >= 545 && e.getX() <= 626 && e.getY() >= 155&& e.getY() <=180) { </p>&

120、lt;p>  int result = JOptionPane.showConfirmDialog(this, "是否選擇人機對戰(zhàn)");</p><p>  if (result == 0) {</p><p><b>  mm = 1;</b></p><p>  for (int i = 0; i < 15;

121、 i++) {</p><p>  for (int j = 0; j < 15; j++) {</p><p>  allChess[i][j] = 0;</p><p><b>  }</b></p><p><b>  }</b></p><p>  messag

溫馨提示

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

評論

0/150

提交評論