版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、<p> 畢 業(yè) 論 文 (設 計)</p><p> 題 目 五子棋人機對弈系統(tǒng) </p><p> 英文題目 Five chess human-computer system</p><p> 院 系 信息科學與技術學院 </p><p> 專 業(yè) 計算機科學與技術 &l
2、t;/p><p><b> 二零一零年一月 </b></p><p><b> 摘 要</b></p><p> 人工智能是一門正在迅速發(fā)展的新興的,綜合性很強的邊緣科學。它與生物工程、空間技術一起被并列為二十一世界三大尖端技術。它的中心任務是研究如何使計算機去做那些過去只能靠人的智力才能做的工作。目前各發(fā)達國家都把人
3、工智能作為重點列入本車的高科技發(fā)展計劃當中,投入巨大的人力和物力。</p><p> 計算機人機對弈也是其中之一。作為人智能研究的一個重要分支,計算機博弈是檢驗人工水平的一個重要方面。它的研究為人工智能帶來了很多重要的方法和理論,產(chǎn)生了廣泛的社會影響和學術影響。</p><p> 五子棋人機對弈是計算機博弈中的一種。研究其計算機算法,可以讓我們看到人工智能的初影,也有助于我們人腦的開發(fā)
4、。五子棋是我國發(fā)明的,研究它可以讓更多的外國人了解,有助于我國優(yōu)秀文化的推廣。</p><p> [關鍵詞]:人工智能,計算人機對弈,五子棋,算法</p><p><b> Abstract</b></p><p> Artificial intelligence is a rapidly developing new, integrat
5、ed a strong Frontier Science. It is with bio-engineering, space technology has been listed as 21 in the world along with the three cutting-edge technology. Its central task is to study how to make the computer do that in
6、 the past to rely on human intelligence to do. AI is currently regarded as the focus of the developed countries included in this car's high-tech development projects invested tremendous human and material resources.
7、 </p><p> [KeyWords] :Artificial intelligence , Man-machine chess computer , </p><p> Man-machine chess,algorithm</p><p><b> 目 錄</b></p><p> 摘要…………………
8、……………………………………………………………………Ⅰ</p><p> Abstract……………………………………………………………………………………Ⅱ</p><p> 概述………………………………………………………………………………11.1背景分析………………………………………………………………………11.2國內外現(xiàn)狀……………………………………………………………………2&
9、lt;/p><p> 需求分析…………………………………………………………………………32.1 需求分析……………………………………………………………………32.2 性能需求……………………………………………………………………32.3 系統(tǒng)平臺需求………………………………………………………………32.4數(shù)據(jù)流圖及數(shù)據(jù)字典………………………………………………………4</p><p>
10、 總體設計…………………………………………………………………………53.1 系統(tǒng)流程圖………………………………………………………………53.2系統(tǒng)分析……………………………………………………………………5</p><p> 系統(tǒng)實現(xiàn)…………………………………………………………………………114.1界面實現(xiàn)……………………………………………………………………114.2智能計算實現(xiàn)…………………………………
11、……………………………12</p><p> 系統(tǒng)維護………………………………………………………………………305.1 系統(tǒng)測試……………………………………………………………………305.2 系統(tǒng)維護……………………………………………………………………31</p><p> 總結……………………………………………………………………………31</p><p>
12、 參考文獻…………………………………………………………………………………33</p><p> 致謝………………………………………………………………………………………34</p><p><b> 第一章 概 述</b></p><p> 當電腦進入我們的生活中,許多與相關學科都欣欣的向上發(fā)展。典型的有電子商務、電子郵件等。當然也有人智
13、能了。人們在驚嘆機器人高效的工作時,也會想起自己聰明的一面。人工智能也這方面也就深受我們喜愛。</p><p><b> 1.1背景分析</b></p><p> 五子棋是起源于中國古代的傳統(tǒng)黑白棋種之一。現(xiàn)代五子棋日文稱之為“連珠”,英譯為“Ren-ju”,英文稱之為“Gobang”或“FIR”(Five in a Row的縮寫),亦有“連五子”、“五子連”、“
14、串珠”、“五目”、“五目碰”、“五格”等多種稱謂。五子棋不僅能增強思維能力,提高智力,而且變化多端,非常富有趣味性和消遣性,因此為人民群眾所喜聞樂見。</p><p> 另一方面,人工智能也在最近幾年發(fā)展迅速。人們不斷的研究出機器人之類的,使它能勝任人們能做的一些復雜的事,或是一些人們不適宜做的事,如水下探測等。而隨著人們工作的加大,運動的時間也越來越少,大部分呆在家里或是工作的地方。這樣人們就通過上網(wǎng)、購物等
15、之類的事來取代生活中的不足。當然也有一部分群體在玩游戲之類的了。而五子棋由于其經(jīng)典、易學等。深受人們的喜愛。人們在玩的同時也增加了自己的智慧。</p><p><b> 1.任務提出</b></p><p> 開發(fā)者:九江學院信息科學與技術學院</p><p> 用戶類型:各類棋牌游戲愛好者</p><p> 用
16、戶特點:玩者只要了解五子棋的幾條規(guī)則,能用基本的windows xp操作就能玩此系統(tǒng)。</p><p><b> 2.系統(tǒng)目標</b></p><p> 系統(tǒng)目標是總體設計的根據(jù),是系統(tǒng)具體實現(xiàn)的前提,本系統(tǒng)將達到以下目標:</p><p> (1) 便于一般懂五子棋群體。</p><p><b> (
17、2) 便于新手玩</b></p><p><b> 1.2 國內外現(xiàn)狀</b></p><p> 國內外研究五子棋的算法不少。有遞歸法、二叉樹等。當然我所討論的是一般的算了法。</p><p> 無論何種算法,其大體遵循兩條原則:1.使規(guī)則更加自然流暢,更容易被人接受。2.使棋的內容更加豐富多彩。而對于五子棋來說,所面臨的困境
18、歸根結底是來自于其最本質的特點,也是目前一切規(guī)則的共同之處:連五終局(注意是連五終局而不一定是連五獲勝,因為連五一方有可能違反長連禁手而被判負)。這個特點產(chǎn)生的結果就是使很多著法絕對化,從而極大地縮減了棋局的變化空間。當別的棋類中的棋子在大多數(shù)時間里都可以在棋盤上自由馳騁時,五子棋的棋子卻經(jīng)常為了應付對方的沖四和活三而不得不疲于奔命。 </p><p> 計算機對不同棋類研究程度的對比很能說明問題;對中象和國象
19、的研究也足可匹敵人類中的頂尖高手;而對五子棋則動輒是“地毯終結”,以摧腐拉朽之勢把這片領域中的未知之處一個又一個無情碾碎。不可否認這也是很多人認為五子棋“簡單低級”的一個重要原因。面對這樣的窘境,有的人提出一種大膽的設想,認為既然“連五終局”是造成五子棋變化簡單的罪魁禍首,那么就應該將其摒棄,用其它的方法比如說看最后誰連五的數(shù)量更多來判定勝負。對于這樣的想法,我認為大家應該以一種開放的心態(tài)去看待,即使是持反對態(tài)度,也要理解提出此類想法的
20、人為了使五子棋更具活力,更加精彩而花費的心思,不要粗暴地給人家扣上一頂“荒誕不經(jīng)”的帽子完事。</p><p> 目前五子棋在規(guī)則方面遇到的困境不是簡單采用某種現(xiàn)行規(guī)則,甚至不是對現(xiàn)行規(guī)則進行一些枝節(jié)上的修改能解決得了的。必須要有大膽的、飛躍性的變革才能使奄奄一息的五子棋有脫胎換骨的變化。至于具體的變革方式,我這個五子棋的門外漢怕是給不出什么像樣的建議,還得靠你們這些內行來想辦法。要說實現(xiàn)這一目標的具體方案,最
21、好是能開一個全國乃至全世界范圍內的規(guī)則統(tǒng)一大會,列舉出幾種切實可行的全新規(guī)則并經(jīng)過充分討論后,以投票方式選出最終的統(tǒng)一規(guī)則。也許有人覺得這個方案離現(xiàn)實太過遙遠,不過我倒覺得此方案比統(tǒng)一于現(xiàn)有的有禁或無禁方案要現(xiàn)實可行的多,因為如果在目前某派所掌握的規(guī)則下實現(xiàn)統(tǒng)一,另一派會有嚴重的被欺壓和被掠奪感,從而在心理上產(chǎn)生強烈的抗拒。</p><p><b> 第二章 需求分析</b></p
22、><p><b> 2.1業(yè)務需求</b></p><p><b> 使用范圍要求</b></p><p> 該系統(tǒng)適于游戲愛好者。</p><p><b> 2. 功能要求</b></p><p> 該系統(tǒng)主要有以下功能:</p>
23、<p> ?。?)玩家能與電腦下子</p><p><b> (2)適于新手來玩</b></p><p><b> 2.2 性能需求</b></p><p> 雖然系統(tǒng)不大,但要滿足玩家的基本要求,電腦有一定的智能,能給于新手一定的幫助。</p><p> 2.3 系統(tǒng)平臺需求&l
24、t;/p><p><b> 1. 系統(tǒng)開發(fā)平臺</b></p><p> 操作系統(tǒng):Windows xp系列</p><p> 開發(fā)工具:Visual C++ 6.0</p><p><b> 2. 開發(fā)環(huán)境介紹</b></p><p> Visual C++是Micr
25、osoft C/C++ 7.0之后推出的新一代程序開發(fā)工具,它不僅繼承C++的特性,同時具備可視化程序語言(Visual Programming Language)及程序產(chǎn)生器的概念。既然是面向對象語言,當然會提供系統(tǒng)基礎類給程序員再使用(Reuse)。在Visual C++ 中,延襲Microsoft C/C++7.0的作法,將原有的SDK函數(shù)重新封裝在適當?shù)念愔?,構造了“基礎類函數(shù)庫(Microsoft Foundation Cla
26、ss Library,簡稱MFC)”,它提供了許多現(xiàn)成的框架對象,可供在使用Visual C++設計應用程序是使用。此外,還提供“ClassWizard”與“AppWizard”可幫助構造基本的程序框架,從軟件再使用的技術觀點而言,已由SDK函數(shù)庫方式經(jīng)過面向對象程序設計方式進展到自動產(chǎn)生模板相關類程序代碼方式(Framework)。</p><p> 面向對象的程序設計是一種新型的程序設計方法,計算機環(huán)境本身
27、就是一個對象的集合體,對象彼此之間通過消息相互作用,面向對象的程序設計提高了程序的模塊化和可維護性。面向對象的程序設計有幾個特點及優(yōu)點。首先,由于對象包含屬性和方法,因此支持模塊化程序設計,而模塊化程序設計支持開發(fā)的便利性及代碼的可維護性。</p><p> Visual C++ 6.0是Microsoft公司推出的功能最強大、最復雜的語言產(chǎn)品之一,它是目前為止在Windows環(huán)境下進行大型軟件開發(fā)的首選。其具
28、有如下特點:</p><p> (1)Visual C+ + 的語法符合ANSL C+ + 標準,并在此基礎上針對Windows操作系統(tǒng)增加了一些語句;</p><p> (2)集成了MFC(Microsoft Foundation Class)類庫,MFC封裝了Windows API函數(shù)和消息,使程序員可以使用MFC高效率地開發(fā)各種應用程序;</p><p>
29、 (3)提供了MFC AppWizard,可方便地生成程序框架;</p><p> (4)提供了基于MFC的ClassWizard,通過它可以輕松地完成對各種MFC類的使用與維護。</p><p> Visual C++ 6.0作為Visual Studio家族中的一員,是Microsoft公司以C++語言為基礎開發(fā)的可視化集成開發(fā)工具,與其他編程語言Visual Basic 6.0
30、、Visual ForPro等一起,成為廣大程序員喜愛的開發(fā)平臺。</p><p> 2.4 數(shù)據(jù)流圖及數(shù)據(jù)字典</p><p> 由于此系統(tǒng)沒有數(shù)據(jù)庫,故沒有數(shù)據(jù)流與數(shù)據(jù)字典。</p><p><b> 第三章 總體設計</b></p><p> 經(jīng)過分析,對五子棋流程進行整理,得出其使用過程如下:</
31、p><p> 進入系統(tǒng)之后。玩家按F1開始游戲,首先是玩家下子,接著電腦下子。一直循環(huán)。在電腦或是玩家下了一個子后,電腦就計算一下,是否電腦獲勝或玩家獲勝或是和棋。若有一種情況出現(xiàn),則暫停游戲顯示出相應的結果。若玩家還想玩,繼續(xù)按F1,若要退出則按F12。在游戲開始后,玩家可按F11進行智能提示。此按鈕適于新手或是“作弊”的群體。</p><p><b> 3.1 系統(tǒng)流程圖&l
32、t;/b></p><p> 程序流程圖如圖3-1所示。首先看到的界面是我們熟悉的棋盤。可看到下面有一行文字。當用戶按F1時,則游戲開始,這時用戶先下子。電腦此時先根據(jù)算法計算下,是否和棋,是否電腦獲勝,是否玩家獲勝,若有一種情況發(fā)生,則進入暫停階段,此時下子則無效,電腦顯示相應的結果,否則電腦就根據(jù)自己的得分算法,計算出最佳位置。把電腦的子下到最好位置上。電腦下子了后,則電腦繼續(xù)判斷是否和棋,是否電腦獲
33、勝,是否玩家獲勝,若有一種情況發(fā)生,同樣進入到暫停階段,顯示相應的結果。若用戶按了F12,則整個系統(tǒng)退出結束。若在開始后,又按了F11,則顯示提示功能。這對于新手來說是很好的功能。</p><p><b> 3.2系統(tǒng)分析</b></p><p> 在看別人下棋時,我們常說一句“當局者迷,旁觀者清”,但這句話對于AI所控制的計算機來說是不正確的。相反,計算機必須知
34、道每回合的情況,能夠知道有哪些獲勝的方式,并計算出下一步棋的位置,判斷當前的情況。</p><p> A:求得所有獲勝的組合</p><p> 首先,在一場五子棋的游戲中,計算機必須要知道有哪些獲勝的組合,因此必須求得獲勝的組合的總數(shù),而求出總數(shù)后便可建立一個數(shù)組??稍谟螒驁?zhí)行時判斷勝負,這個概念比較復雜,我們可以在后面的代碼中可看到。</p><p> 我要
35、做的是19X19的棋盤,獲勝總數(shù)有點多。下面一一來討論。(以表格作為棋盤,1表示為某一方的子,其中以(i,j)表示第i行第j列的格子,)</p><p> 計算水平方向的獲勝組合數(shù)</p><p> 1 2 3 …… 15 16 17 18 19</p><p> 可以看
36、到對于第一行中(1,1),(1,2),(1,3),(1,4),(1,5)這五個格可以是一個獲勝組合,而(1,2),(1,3),(1,4),(1,5),(1,6)這五個格子也可以組成一個獲勝組合。這樣一直到最后一種為(1,15),(1,16),(1,17),(1,18),(1,19)這五個格子組成一個獲勝組合。即第一行有15種獲勝的組合??偟挠?9行。可得,對于行中,我們有19X15=285種獲勝組合。</p><p&
37、gt; 計算垂直方向的獲勝組合數(shù)</p><p> 同理對于垂直的獲勝組合中第一種為第一列的1,2,3,4,5可組成一個獲勝組合??偟墨@勝組合也是19X15=285種。</p><p> 計算正斜方向的獲勝組合數(shù)</p><p> 1 2 3 4 5 …… 15 16 17 18
38、 19</p><p> 在第一行中,則可知(1,1),(2,2),(3,3),(4,4),(5,5)為一獲勝組合,而(1,3),(2,4),(3,5),(4,6),(5,7)也是一種獲勝組合。第一行中的最后一種為(1,15),(2,16),(3,17),(4,18),(5,19)??偟墨@勝組合有15種,而最后一行i只能到15。這樣我們可以計算得到正斜有15X15=225種。</p><p
39、> 計算反斜方向的獲勝組合數(shù)</p><p> 依據(jù)上一種正斜,同理可推知反斜也有15X15=225種。</p><p> 由前面的討論中,我們可計算出19X19表格中五子棋的獲勝種數(shù)。一共有285+285+225+225=1020種獲勝方式。</p><p> B:建立一些相應的變量</p><p> 對此我建立了一個數(shù)組,
40、如下:</p><p> BOOL cmp[19][19][1020]; //電腦的每一顆棋子是否在各個獲勝組合中</p><p> BOOL ply[19][19][1020]; //電腦的每一顆棋子是否在各個獲勝組合中</p><p> int wcount[2][1020]; //電腦與玩家在各個組合中的棋子個數(shù)</p>
41、<p> (三個變量的簡寫來源cmp:computer ply:player wcount:win count)</p><p> 如上述討論可知,對于電腦,若為正斜中的第一種情況,并假定為1020種獲勝組合中的第570種獲勝組合。則其數(shù)組元素值設定如下:</p><p> cmp[0][0][570]=true;</p><p> cmp[0][
42、1][570]=flase;</p><p> cmp[0][2][570]=false;</p><p><b> ……</b></p><p> cmp[1][0][570]=false;</p><p> cmp[1][1][570]=true;</p><p> cmp[1][2
43、][570]=false;</p><p><b> ……</b></p><p> cmp[2][2][570]=true;</p><p><b> ……</b></p><p> cmp[3][3][570]=true;</p><p><b> …
44、…</b></p><p> cmp[4][4][570]=true;</p><p> ply[][][]數(shù)組元素的初始化與cmp[][][]是相同的,但若在程序執(zhí)行時,若玩家的棋占了(0,0)的位置,那么電腦在cmp[0][0][570]元素就會置為false,因為計算機就不可能再下到(0,0)上,因此第570種方法中對電腦來說是不可能的情況了。同理,對于若是電腦占了(
45、0,0)的位置,則玩家中此獲勝組合中也置為不可能。</p><p> wcount[2][1020]用來記錄玩家或計算機在各自的獲勝組合中棋子的個數(shù)。其中wcount[0][]來計算電腦的個數(shù),wcount[1][]用來計算玩家的個數(shù)。假如在第570種獲勝組合中填入了3個電腦的子,則此時則有wcount[0][570]=3。若在某一時刻有wcount[][]=5,則此時即可判定某一方獲勝了。</p>
46、<p><b> C:分數(shù)的設定</b></p><p> 組在游戲中,為了讓電腦找到最佳的走法,必須計算出電腦下到棋盤中任一格的分數(shù),其中最高分即是電腦下的位置。</p><p> 如下表所示,為了討論方便,我只畫了一個10X10的表格(其中C表示電腦的子,P表示玩家的子)</p><p> 1 2 3
47、4 5 6 7 8 9 10</p><p> 如上表所示,為什么會出現(xiàn)在C左邊為0而下面卻為20分呢。</p><p> 我們看下上面的表格就可知,C的左邊有三個格,要想獲勝,則必須再加上左右邊的一個格了,而右邊的一個格子被電腦占了,因此,此獲勝組合中置為不可能,得分為0。而對于C下面的格子有四個獲勝的組合,且每一種組合都可能獲勝,因此每種組合的分數(shù)累
48、加,可以得出其分數(shù)為20。因此在此棋盤中,最佳位置有四個。</p><p> 以上是按每一種獲勝組合為5分的來計算的。在每一次運行中,電腦都按些種算法,則電腦可以找到最佳的位置。</p><p><b> D:攻擊與防守</b></p><p> 經(jīng)上述討論可知,電腦一直在找自己一方的最佳位置。若玩家在某個時刻獲勝了,電腦也在尋找自己的位
49、置。如何才能解決這個問題呢?想想其實也不難。在下子的過程中,電腦還必須記下玩家的分數(shù)情況,并且計分方式要一樣。每一次下完之后,電腦便計分,若是電腦的分數(shù)高,則下在已方,反之下在玩家的最佳位置。這樣一來,電腦也就有了智能了。</p><p><b> 第四章 系統(tǒng)實現(xiàn)</b></p><p> 系統(tǒng)經(jīng)過分析并加以設計,就可以著手進行實現(xiàn)了,本系統(tǒng)主要分為界面實現(xiàn)和算
50、法實現(xiàn)。</p><p> 4.1 界面的實現(xiàn) </p><p> 本系統(tǒng)首先印入眼簾的是五子棋的界面。本系統(tǒng)的啟動界面窗口如圖4-1所示。</p><p><b> 圖4-1</b></p><p> 利用MFC建立一個MFC工程。在mainFrame的析構函數(shù)中,插入下一句代碼:</p>&l
51、t;p> Create(NULL,"五子棋",WS_OVERLAPPEDWINDOW&~WS_SIZEBOX&~WS_MAXIMIZEBOX,CRect(0,0,700,700),NULL,NULL,0,NULL);</p><p> 則此窗口生成的標題為“五子棋”,當加入了WS_SIZEBOX與WS_MAXIMIZEBOX后,此窗口就不能最大化顯示且不能調整邊框大小
52、,即一創(chuàng)建的框架為不可改變的大小,另一個為CRect(0,0,700,700)。此框架的大小為700X700。</p><p> 窗口創(chuàng)建后就是導入圖片。為此首先導入圖片到工程中,命名為IDB_BJ。要導入一張圖片需要三個步驟。先要取得設備的DC。這個程序是用CClient dc(this)來取的。為了防止閃爍,我加了一個標記變量flagbj。初始值為0,加載背景之后就置為1。則可知,背景只顯示一次。其代碼如下
53、:</p><p> CBitmap bj;//存放背景圖</p><p> CDC membj; //內存變量背景</p><p> membj.CreateCompatibleDC(&dc);//創(chuàng)建相容的內存變量</p><p> bj.LoadBitmap(IDB_BJ); //加載背景
54、圖</p><p> membj.SelectObject(&bj); //選擇背景圖</p><p> //初始時只需顯示一次背景就可</p><p> if(0==flagbj) {</p><p> //若是左鍵單擊了之后才可重新繪圖,目的是白子只重新繪制一次</p><p> i
55、f(1==flaglb) {</p><p> dc.BitBlt(0,0,700,700,&membj,0,0,SRCCOPY);</p><p><b> }</b></p><p> //置為1表示不再顯示背景</p><p><b> flagbj=1;</b></p&
56、gt;<p><b> }</b></p><p> 4.2 智能算法實現(xiàn)</p><p> 為了計算得分,在討論之前要聲明幾個變量和幾個函數(shù)。</p><p> int borad[19][19];//五子棋盤的狀態(tài)。0表示無棋,1表示為電腦的棋子,2表示為玩家的棋子(borad)</p><p&
57、gt; BOOL cmp[19][19][1020];//電腦的獲勝組合情況(computer)</p><p> BOOL ply[19][19][1020];//玩家的獲勝組合情況(player)</p><p> int wcount[2][1020];//雙方的組合情況中子的個數(shù),wcount[0][1020]為電腦,wcount[1][1020]為玩家(win
58、count)</p><p> int pscore[19][19];//電腦的得分(player score)</p><p> int cscore[19][19];//玩家的得分(computer score)</p><p> BOOL bcmp;//是否輪到電腦下棋(bool computer)</p><p>
59、 BOOL bply;//是否輪到玩家下棋(bool computer)</p><p> BOOL start;//游戲是否開始(start)</p><p> BOOL pwin;//電腦是否獲勝(player win)</p><p> BOOL cwin;//玩家是否獲勝(computer win)</p>&l
60、t;p> BOOL tie;//是否和棋(tie)</p><p> BOOL tishi;//是否有智能提示(tishi)</p><p> void initGame();//初始化棋盤(initalite game)</p><p> void countScore();//計分函數(shù)(count score)</p>
61、;<p> void cmpTurn();//電腦下子算法(computer turn)</p><p> BOOL plyGame();//是否玩家獲勝(player game win)</p><p> BOOL cmpGame();//是否電腦獲勝(computer game win)</p><p> BOOL tie
62、Game();//是否為和棋(tie game)</p><p> int topScore();//查找最高分;返回最高分數(shù)(top score) //尋找電腦的隨機位置并保存在mc,nc中(search count) void searchCount(int top,int countTep,int *mc,int *nc);</p><p> int countT
63、op(int top);//返回最高分的個數(shù)(count top score)</p><p> 首先要進行初始化。先對棋盤及分數(shù)進行初始化。</p><p> //0表示無棋子,1表示為電腦的棋子,2表示為玩家的棋子</p><p> for(i=0;i<19;i++){</p><p> for(j=0;j<19;j
64、++){</p><p> pscore[i][j]=0;//玩家各得分為0</p><p> cscore[i][j]=0;//電腦各得分為0</p><p> borad[i][j]=0;//各空格置為無子 </p><p><b> }</b></p><p><b
65、> }</b></p><p> //各獲勝組合中的棋子數(shù)為0</p><p> for(k=0;k<1020;k++){</p><p> wcount[0][k]=0;//電腦獲勝組合數(shù)的個數(shù)</p><p> wcount[1][k]=0;//玩家獲勝組合數(shù)的個數(shù)</p><
66、p><b> }</b></p><p> 然后要對獲勝組合進行初始化。</p><p> //初始時各種獲勝組合中的值都為false</p><p> for(i=0;i<19;i++){</p><p> for(j=0;j<19;j++){</p><p> f
67、or(k=0;k<1020;k++){</p><p> cmp[i][j][k]=false;</p><p> ply[i][j][k]=false;</p><p><b> }</b></p><p><b> }</b></p><p><b
68、> }</b></p><p> //行的組合情況,count的初始值為0</p><p> for(i=0;i<19;i++){</p><p> for(j=0;j<15;j++){</p><p> for(k=0;k<5;k++){</p><p> cmp[i]
69、[j+k][count]=true;</p><p> ply[i][j+k][count]=true;</p><p><b> }</b></p><p><b> count++;</b></p><p><b> }</b></p><p&g
70、t;<b> }</b></p><p><b> //列的組合情況</b></p><p> for(i=0;i<15;i++){</p><p> for(j=0;j<19;j++){</p><p> for(k=0;k<5;k++){</p><
71、;p> cmp[i+k][j][count]=true;</p><p> ply[i+k][j][count]=true;</p><p><b> }</b></p><p><b> count++;</b></p><p><b> }</b></
72、p><p><b> }</b></p><p><b> //正斜的組合情況</b></p><p> for(i=0;i<15;i++){</p><p> for(j=0;j<15;j++){</p><p> for(k=0;k<5;k++){
73、</p><p> cmp[i+k][j+k][count]=true;</p><p> ply[i+k][j+k][count]=true;</p><p><b> }</b></p><p><b> count++;</b></p><p><b>
74、; }</b></p><p><b> }</b></p><p><b> //反斜的組合情況</b></p><p> for(i=0;i<15;i++){</p><p> for(j=18;j>=4;j--){</p><p>
75、for(k=0;k<5;k++){</p><p> cmp[i+k][j-k][count]=true;</p><p> ply[i+k][j-k][count]=true;</p><p><b> }</b></p><p><b> count++;</b></p>
76、;<p><b> }</b></p><p><b> }</b></p><p> 進行初始化后,此時start、bply置為ture,bcmp置為false。即對每一種獲勝組合中的情況進行初始化。之后游戲開始,玩家可下子,電腦不可下子。先玩家下子,轉入到系統(tǒng)函數(shù)OnLButtonDown()。如下所示</p&g
77、t;<p> void mainFrame::OnLButtonDown(UINT nFlags, CPoint point) {</p><p> //玩家單擊時的動作</p><p> if(start&&bply){//若開始后且輪到玩家下子則進行判斷</p><p> if(point.x>=38&&
78、amp;point.y&&point.x<=602&&point.y<=602) {</p><p> mp=(int)floor((point.x-36)/30);</p><p> np=(int)floor((point.y-36)/30);</p><p><b> //空格才可下子</b&g
79、t;</p><p> if(0==borad[mp][np]) {</p><p><b> //置為玩家的子</b></p><p> borad[mp][np]=2;</p><p> for(k=0;k<1020;k++){</p><p><b> //玩家子個
80、數(shù)加1</b></p><p> if(-1!=wcount[1][k]&&ply[mp][np][k])</p><p> wcount[1][k]++;</p><p> //電腦置為不可能獲勝</p><p> if(cmp[mp][np][k]){</p><p> cmp
81、[mp][np][k]=false;</p><p> wcount[0][k]=-1;</p><p><b> }</b></p><p><b> }</b></p><p> flaglb=1;//玩家下子了可以貼白子 與tishi中的flaglb形成合作關系</p>
82、<p> bply=false;//玩家不可下子</p><p> bcmp=true;//電腦可以下子</p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p>&l
83、t;p> CFrameWnd::OnLButtonDown(nFlags, point);</p><p><b> }</b></p><p> 在此函數(shù)中,首先要判斷下子的位置是否在五子棋的棋盤區(qū)域中。即使其成立point.x>=38&&point.y&&point.x<=602&&point
84、.y<=602。若在區(qū)域中,就調用了系統(tǒng)中的函數(shù)floor(),用于對鍵單擊時的位置取整,來得到單擊進的位置。之后還要判斷所下了位置是否是空子,若是空子才可下子。若為空,則此格即為玩家的子,borad[][]的值置為2(2表示為玩家的子)。玩家下子后,電腦的布局就要改變。這時對1020種獲勝情況一一來進行討論。若是玩家的子且在此獲勝組合中有可能獲勝,則wcount[1][]中的個數(shù)加一,若是電腦的獲勝組合中也為true,則此時wc
85、ount[0][]置為-1,表示在此獲勝組合中不可能獲勝,并把對應的cmp[][][]的值置為false,表示電腦在此獲勝組合中不可能獲勝。玩家下完之后,此時就輪到電腦下子了。bply置為true,bcmp置為false,表示玩家下完之后是電腦下子。</p><p> 玩家下完之后,這時就是輪到電腦下子。但在下子前判斷下當前的狀況。先貼子。</p><p> //玩家下完之后就重新貼子
86、</p><p> for(i=0;i<19;i++){</p><p> for(j=0;j<19;j++){</p><p><b> //電腦為紅子</b></p><p> if(1==borad[i][j])</p><p> dc.BitBlt(i*30+36,j
87、*30+36,24,24,&memcs,0,0,SRCCOPY);</p><p><b> // 玩家為綠子</b></p><p> if(2==borad[i][j])</p><p> dc.BitBlt(i*30+36,j*30+36,24,24,&memps,0,0,SRCCOPY);</p>&
88、lt;p><b> }</b></p><p><b> }</b></p><p> 剛剛玩家下完之后,只是內部的置為玩家的子,但是用戶沒有看到。此時若顯示出來,則可了解到玩家的子確實下了。這時電腦就進入了計算階段。這也是此系統(tǒng)的核心代碼。此函數(shù)放置在OnTimer()中。如下所示:</p><p><
89、b> //是否和棋</b></p><p> tie=tieGame();</p><p> if(tie&&start)</p><p> {start=false;//游戲結束</p><p> bcmp=false;//電腦不可下子</p><p> bpl
90、y=false;//玩家不檔下子</p><p> MessageBox("朋友,水平不錯,竟能與電腦和棋哦……\n(按F1開始,F(xiàn)12退出!)");</p><p> flagbj=0;//重新顯示背景圖片</p><p><b> }</b></p><p><b>
91、//是否電腦獲勝</b></p><p> cwin=cmpGame();</p><p> if(cwin&&start)</p><p> { start=false;//游戲結束</p><p> bcmp=false;//電腦不可下子</p><p> bply=
92、false;//玩家不檔下子</p><p> MessageBox("朋友,失敗乃成功之母,請再接再勵!\n(按F1開始,F(xiàn)12退出!)");</p><p> flagbj=0;//重新顯示背景圖片</p><p><b> }</b></p><p><b> //是
93、否玩家獲勝</b></p><p> pwin=plyGame();</p><p> if(pwin&&start)</p><p> { start=false;//游戲結束</p><p> bcmp=false;//電腦不可下子</p><p> bply=fal
94、se;//玩家不檔下子</p><p> MessageBox("朋友,真牛!一下就贏了,要不收我作徒弟吧~~\n(按F1開始,F(xiàn)12退出!)");</p><p> flagbj=0;//重新顯示背景圖片</p><p><b> }</b></p><p> 先判斷是否是和棋,若
95、是則暫停程序。當然在此,判斷和棋,我是調用了和棋的函數(shù)tieGame()。其內容如下:</p><p> BOOL mainFrame::tieGame(){</p><p> //若有空格則不為和棋</p><p> for(i=0;i<19;i++){</p><p> for(j=0;j<19;j++){</p
96、><p> if(0==borad[i][j]) {</p><p> return false;</p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p&
97、gt; //若有一方勝也不為和棋</p><p> for(k=0;k<1020;k++){</p><p> if(5==wcount[0][k]||5==wcount[1][k]) {</p><p> return false;</p><p><b> }</b></p><p
98、><b> }</b></p><p><b> //否則為和棋</b></p><p> return true;</p><p><b> }</b></p><p> 要討論19X19格了中的每一個格子。若每一個格子都不為空,即borad[][]!=0,并
99、且在獲勝組合中沒有一方獲勝,則此時電腦即為和棋,返回true,否則都為false。這樣就可實現(xiàn)和棋的判斷了。若是和棋,則此時start置為flase,表示游戲暫時停止。并彈出對話框顯示和棋。</p><p> 若不為和棋,則判斷是否是電腦獲勝,其也調用判斷電腦獲勝的函數(shù)cmpGame(),其內容如下:</p><p><b> //是否玩家獲勝</b></p
100、><p> BOOL mainFrame::plyGame(){</p><p> for(k=0;k<1020;k++){</p><p> if(5==wcount[1][k])//有五子棋相連則獲勝</p><p> return true;</p><p><b> }</b&
101、gt;</p><p> return false;</p><p><b> }</b></p><p> 其實也挺容易的,只要看下wcount[1][]中是否有一種情況中的個數(shù)為5,若有此時就返回true,否則返回flase。若是電腦獲勝,則也彈出對話框顯示電腦獲勝。這之后便把start也置為false。</p><
102、;p> 若電腦不獲勝,則繼續(xù)判斷是否玩家獲勝,此時同樣調用函數(shù)cmpGame()來處理。如下所示:</p><p> BOOL mainFrame::cmpGame(){</p><p> for(k=0;k<1020;k++){</p><p> if(5==wcount[0][k])//有五子棋相連則獲勝</p><
103、p> return true;</p><p><b> }</b></p><p> return false;</p><p><b> }</b></p><p> 若在電腦的獲勝組合中有一個組合的個數(shù)為5,則電腦獲勝,這時就彈出對話框,顯示電腦獲勝,游戲時放暫停狀態(tài)。否則繼續(xù)
104、執(zhí)行。</p><p> 若玩家下子后沒有和棋、電腦獲勝或是玩家獲勝,則此時就輪到電腦下子了。</p><p> 首先統(tǒng)計下當前分數(shù),看下當前的得分情況。如下:</p><p> void mainFrame::countScore(){</p><p> for(i=0;i<19;i++){</p><p&
105、gt; for(j=0;j<19;j++){</p><p><b> //初始值為0</b></p><p> pscore[i][j]=0;</p><p> cscore[i][j]=0;</p><p> //若為空則計算分數(shù)</p><p> if(0==borad[i
106、][j]) {</p><p> //各種情況一一討論</p><p> for(k=0;k<1020;k++){</p><p><b> //若是玩家</b></p><p> if(ply[i][j][k]) {</p><p> switch(wcount[1][k]) {
107、</p><p> case 0://零個子情況</p><p> pscore[i][j]+=1;</p><p><b> break;</b></p><p> case 1: //一個子情況</p><p> pscore[i][j]+=5;
108、</p><p><b> break;</b></p><p> case 2: //二個子情況</p><p> pscore[i][j]+=10;</p><p><b> break;</b></p><p> case 3:
109、//三個子情況</p><p> pscore[i][j]+=30; break;</p><p> case 4: //四個子情況</p><p> pscore[i][j]+=120;</p><p><b> break;</b></p><p>
110、<b> }</b></p><p><b> }</b></p><p><b> //若是電腦</b></p><p> if(cmp[i][j][k]) {</p><p> switch(wcount[0][k]) {</p><p>
111、<b> case 0:</b></p><p> cscore[i][j]+=1;</p><p><b> break;</b></p><p><b> case 1:</b></p><p> cscore[i][j]+=2;</p><p
112、><b> break;</b></p><p><b> case 2:</b></p><p> cscore[i][j]+=8;</p><p><b> break;</b></p><p><b> case 3:</b><
113、/p><p> cscore[i][j]+=32;</p><p><b> break;</b></p><p><b> case 4:</b></p><p> cscore[i][j]+=128;</p><p><b> break;</b&g
114、t;</p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p><b> }</b><
115、;/p><p><b> }</b></p><p><b> }</b></p><p> 對于19X19的格子,一一討論。若格子為空,則進行統(tǒng)計,因為只有空格才可下子。對于空格,對獲勝的1020種情況一一討論,若存在電腦的獲勝組合為true,若組合中已有一個子,則在此格中的分數(shù)加2,若是已有二個子,則數(shù)加8,三個的加
116、32,四個的加128。在此依據(jù)獲勝組合中的棋子越多,則獲勝的機會越大,分數(shù)也就越高,計算機就按此分數(shù)來計算最佳位置。對于玩家的分數(shù)也用同樣的規(guī)則。</p><p> 統(tǒng)計完分之后,若是輪到電腦下子,游戲未結束,則電腦下子。</p><p> //是否輪到電腦下子</p><p> if(bcmp&start)</p><p>
117、 cmpTurn();</p><p> 在此也調用了函數(shù)來處理電腦下子的算法。對于cmpTurn()的代碼如下:</p><p> void mainFrame::cmpTurn(){</p><p> //以下用于找到最高分</p><p> //最高分為0,tc為電腦的最高分,tp為玩家的最高分</p><p
118、><b> tc=tp=0;</b></p><p> //標記位,0為沒找到位置,1為有電腦下子的位置</p><p> int flag=0;</p><p> for(i=0;i<19;i++){</p><p> for(j=0;j<19;j++){</p><p&
119、gt; //若是空格則統(tǒng)計分數(shù)</p><p> if(0==borad[i][j]) {</p><p> if(pscore[i][j]>=tp) {</p><p><b> mp=i;</b></p><p><b> np=j;</b></p><p&g
120、t; tp=pscore[i][j];</p><p><b> flag=1;</b></p><p><b> }</b></p><p> if(cscore[i][j]>=tc) {</p><p><b> mc=i;</b></p>&
121、lt;p><b> nc=j;</b></p><p> tc=cscore[i][j];</p><p><b> flag=1;</b></p><p><b> }</b></p><p><b> }</b></p>
122、<p><b> }</b></p><p><b> }</b></p><p> //以下是電腦下了的位置</p><p> if(1==flag) {//若有電腦下子的位置才可下子</p><p> //玩家分數(shù)高,則下在玩家的最高分位置,否則下在電腦的最高分位置<
123、;/p><p> if(tc<tp) {</p><p><b> mc=mp;</b></p><p><b> nc=np;</b></p><p><b> }</b></p><p><b> //置為電腦的子</b&
124、gt;</p><p> borad[mc][nc]=1;</p><p> //將1020種情況一一討論</p><p> for(k=0;k<1020;k++){</p><p> //電腦可以獲勝且在此位置有獲勝組合,則此組合個數(shù)加1</p><p> if(-1!=wcount[0][k]&am
125、p;&cmp[mc][nc][k])</p><p> wcount[0][k]++;</p><p> //電腦可獲勝,則置玩家不可能獲勝</p><p> if(ply[mc][nc][k]) {</p><p> ply[mc][nc][k]=false;</p><p> wcount[1][
126、k]=-1;</p><p><b> }</b></p><p><b> }</b></p><p> //電腦下完后是玩家下子</p><p> bcmp=false;</p><p> bply=true;</p><p><
127、b> }</b></p><p><b> }</b></p><p> 此函數(shù)先對于玩家與電腦的分數(shù)pscore[][],cscroe[][]進行統(tǒng)計,分別找出電腦和玩家的最高分,若找到了,則置flag為1,表示電腦有可下的子。若有可下的子,則進行討論。由于前面已得到了電腦與玩家的最高分,并且分別保留了電腦與玩家的最高分的位置,若是玩家的分
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 畢業(yè)設計--五子棋人機對弈
- 人機對弈五子棋游戲畢業(yè)設計
- java課程設計--人機對弈五子棋
- 五子棋對弈系統(tǒng)設計畢業(yè)設計
- 五子棋畢業(yè)論文
- 五子棋畢業(yè)論文-html開發(fā)五子棋的原型設計
- java五子棋畢業(yè)設計--java五子棋對弈程序的設計與實現(xiàn)
- 五子棋游戲設計畢業(yè)論文
- java五子棋游戲畢業(yè)論文
- 畢業(yè)論文——五子棋游戲設計
- 軟件工程畢業(yè)論文-基于vc++的五子棋程序設計與實現(xiàn)
- 基于vc++的五子棋程序設計與實現(xiàn)
- 基于vc的五子棋游戲設計與實現(xiàn)【畢業(yè)論文】
- 五子棋人機對戰(zhàn)系統(tǒng)設計.pdf
- 畢業(yè)論文---網(wǎng)絡五子棋游戲設計
- 基于vc++的五子棋游戲設計與實現(xiàn)【開題報告】
- 畢業(yè)論文 基于android的五子棋設計
- 五子棋畢業(yè)論文--人工智能課題
- 網(wǎng)絡五子棋五子棋設計與實現(xiàn).doc
- qt網(wǎng)絡五子棋五子棋設計與實現(xiàn)
評論
0/150
提交評論