




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
基于Python的中國(guó)象棋軟件開發(fā)設(shè)計(jì)1緒論 【內(nèi)容摘要】中國(guó)象棋程序的實(shí)現(xiàn)主要分為兩大部分,分別是人工智能與輔助功能。其中人工智能部分體現(xiàn)在計(jì)算機(jī)下棋的計(jì)算思路,包括搜索算法搜索著法,評(píng)估函數(shù)對(duì)各種著法進(jìn)行價(jià)值評(píng)估,最終選擇最佳的一步;而輔助功能主要是通過算法,為人機(jī)對(duì)戰(zhàn)添加多種功能,增添用戶下棋的樂趣。本文首先研究了計(jì)算機(jī)編程在中國(guó)象棋方面的現(xiàn)狀與前景。在研究計(jì)算機(jī)博弈論的極大值極小值搜索的基礎(chǔ)上,通過Alpha-beta剪枝算法,利用python語(yǔ)言與pycharm開發(fā)工具實(shí)現(xiàn)具有普通人棋力的中國(guó)象棋程序。【關(guān)鍵詞】python;中國(guó)象棋;Alpha-beta剪枝算法1緒論1.1研究背景及意義伴隨著時(shí)代的發(fā)展與科技的進(jìn)步,人們的娛樂項(xiàng)目也逐漸豐富,在二十一世紀(jì)的生活里,玩游戲已經(jīng)成為了人們?cè)诓栌囡埡蟾訕芬膺x擇的一種放松方式。計(jì)算機(jī)發(fā)明以后,游戲便又多了一個(gè)新的載體。隨著計(jì)算機(jī)的發(fā)展,電腦游戲也在逐步進(jìn)化成熟。在技術(shù)發(fā)展迅速的今天,對(duì)于有能力進(jìn)行程序編輯的人來說,開發(fā)多功能游戲已經(jīng)是一件很容易的事情了。其中棋牌類游戲因其操作簡(jiǎn)單、方便、快捷等多種優(yōu)勢(shì)在眾多游戲中脫穎而出,除了上手快、游戲時(shí)間短暫、隨時(shí)隨地都可以玩的優(yōu)點(diǎn)之外,棋牌類的游戲最大的特點(diǎn)就是不以追求盈利為主,更加專注于開發(fā)人們的智力,使人們?cè)谟螒虻倪^程中獲得新鮮感的同時(shí)得到智力上的開發(fā),深受廣大人民群眾的喜愛和追捧。中國(guó)象棋起源于中國(guó),以二人之間相互對(duì)抗競(jìng)爭(zhēng)為游戲規(guī)則,在我國(guó)擁有著悠久的歷史,是最能夠代表中華民族優(yōu)秀文化的標(biāo)志之一。中國(guó)象棋規(guī)則易懂,卻具有極強(qiáng)的趣味性與思考性。能夠起到很好的鍛煉人們的邏輯思維能力的作用。中國(guó)象棋在計(jì)算機(jī)博弈中有著很高的復(fù)雜度,也很少有人參與研究,因此在網(wǎng)絡(luò)上參考的資料相對(duì)而言是比較少的。計(jì)算機(jī)技術(shù)的發(fā)展讓人不由得去想:計(jì)算機(jī)計(jì)算是否有能力戰(zhàn)勝人類大腦?象棋大師敗于與計(jì)算機(jī)的對(duì)戰(zhàn)是否證明了計(jì)算機(jī)已經(jīng)超越了人類?這些問題都牽扯到了人工智能的概念。而人工智能就是以研究如何使計(jì)算機(jī)通過計(jì)算去完成傳統(tǒng)認(rèn)知中只有靠人類大腦才能完成的工作。基于科技發(fā)展的大背景之下,人工智能技術(shù)的研究成了游戲開發(fā)過程中一個(gè)熱門方向。[1][2]1.2課題發(fā)展概況從最初功能單一的電子棋盤到如今的豐富多彩的電腦端游戲,象棋軟件的發(fā)展也是十分迅速的。早期的象棋軟件計(jì)算時(shí)間長(zhǎng),計(jì)算效果差,人們往往在下棋的過程中就敗于缺乏耐性等待電腦計(jì)算。慢慢地,一些相對(duì)智能的中國(guó)象棋軟件也漸漸出現(xiàn)在網(wǎng)絡(luò)上,最突出的代表有:《棋癮》等,雖然改善了計(jì)算時(shí)長(zhǎng)方面的缺點(diǎn),但同樣存在著共同性的缺陷,那就是在進(jìn)行對(duì)弈時(shí)智力與人腦還是存在明顯的差異。自2016年阿爾法圍棋與職業(yè)棋手李世石進(jìn)行人機(jī)之間的較量之后并且以微弱的優(yōu)勢(shì)戰(zhàn)勝計(jì)算機(jī)之后,越來越多的人們開始注意到人工智能的概念。它打破了傳統(tǒng)觀念中棋局對(duì)戰(zhàn)必須雙人參與的觀點(diǎn),首次正式提出了以計(jì)算機(jī)計(jì)算代替人類大腦計(jì)算的大膽想法。2017年,谷歌公司旗下子公司在國(guó)際學(xué)術(shù)期刊《Nature》上發(fā)布了關(guān)于人工智能自訓(xùn)練的兩篇學(xué)術(shù)文章'MasteringthegameofGowithouthumanknowledge'以及'MasteringChessbySelf-PlaywithaGeneralReinforcementLearning',為后人實(shí)現(xiàn)中國(guó)象棋軟件開發(fā)提供了清晰明了的思路及原理。在韓繼凱碩士的論文《遠(yuǎn)程遙控中國(guó)象棋對(duì)弈機(jī)器人系統(tǒng)研制》中,對(duì)中國(guó)象棋機(jī)器人的研究意義做出了詳細(xì)的介紹。[3]直到2020年,人們還是沒有停止對(duì)中國(guó)象棋軟件的研究,孔德帥碩士的論文《中國(guó)象棋人機(jī)博弈系統(tǒng)的研究與實(shí)現(xiàn)》又對(duì)人機(jī)博弈的理論提供了更加科學(xué)的理論依據(jù)及實(shí)踐經(jīng)驗(yàn)。[4]從這一系列發(fā)展來看,中國(guó)象棋軟件的研究也逐步出現(xiàn)了上升的趨勢(shì)。1.3主要研究?jī)?nèi)容作為當(dāng)今三大極端技術(shù)之一,人工智能賦予了計(jì)算機(jī)一個(gè)“思考”的過程,使其智能化,做到能夠代替人類完成某些工作。將人工智能與游戲相結(jié)合,以提高游戲過程中的趣味性成為了近些年來人們不斷探索研究的重點(diǎn)。在本次軟件設(shè)計(jì)與開發(fā)的過程中,主要運(yùn)用到Python中的庫(kù),并綜合運(yùn)用了人工智能的相關(guān)搜索算法來實(shí)現(xiàn)著法的生成,完善整個(gè)游戲軟件的實(shí)用性與趣味性。本此設(shè)計(jì)將著重將人工智能與中國(guó)象棋游戲結(jié)合起來,通過剪枝算法實(shí)現(xiàn)人機(jī)對(duì)弈的基本操作,因此,如何設(shè)計(jì)算法,優(yōu)化代碼成為了本次設(shè)計(jì)的重難點(diǎn)所在。本文完成一下的工作:第一部分緒論介紹了課題研究的背景及其意義、課題的發(fā)展概況與研究?jī)?nèi)容;第二部分系統(tǒng)技術(shù)分析,主要介紹了本次設(shè)計(jì)開發(fā)的技術(shù)支持,包括開發(fā)環(huán)境、開發(fā)語(yǔ)言以及開發(fā)工具;第三部分軟件功能描述,從大體上介紹了中國(guó)象棋軟件在當(dāng)今社會(huì)的需求,提出本次設(shè)計(jì)開發(fā)的所要實(shí)現(xiàn)的功能;第四部分軟件設(shè)計(jì)與實(shí)現(xiàn),主要介紹了軟件設(shè)計(jì)的整體思路以及其中的技術(shù)分析,詳細(xì)描述了本次軟件設(shè)計(jì)開發(fā)的過程;第五部分軟件測(cè)試,主要對(duì)本次設(shè)計(jì)運(yùn)行的結(jié)果進(jìn)行了分析;第六部分總結(jié),總結(jié)了本次設(shè)計(jì)所取得的成績(jī)、指出存在的不足,提出對(duì)未來的展望。2系統(tǒng)技術(shù)分析本軟件是為一個(gè)小型的基于Python語(yǔ)言編寫的中國(guó)象棋軟件,是實(shí)現(xiàn)人機(jī)對(duì)戰(zhàn)的單機(jī)游戲,所耗費(fèi)的資源非常的小。系統(tǒng)的界面友好,完全是可視化,基于Windows窗口方便了各種類型用戶使用。本軟件的開發(fā)工具是PyCharm2020.1版本,使用的語(yǔ)言為Python3.7版本。主要導(dǎo)入了Pygame、Numpy等庫(kù),共同完成了算法的設(shè)計(jì)。利用自帶的功能庫(kù)Pygame來進(jìn)行頁(yè)面布局,完成了整個(gè)軟件操作界面的設(shè)計(jì)。只要啟動(dòng)程序的運(yùn)行,即可打開界面開啟游戲。2.1Pycharm概述Pycharm是python語(yǔ)言開發(fā)最普遍、常見的開發(fā)工具,具有跨平臺(tái)的特型,主流的三大平臺(tái)是Windows、MacOSX和Linux。其自帶調(diào)試、工程管理、智能提示等等工具,能夠幫助程序員在編程的過程中提高開發(fā)效率。除此之外,Pycharm還為用戶提供了一些更加高級(jí)的功能,例如支持Django框架下的專業(yè)Web開發(fā)、支持GoogleAppEngine、IronPython等,種種功能在軟件開發(fā)中發(fā)揮了重要的作用,使得Pycharm成為了Python語(yǔ)言開發(fā)最有力的工具。本次軟件開發(fā)選擇的版本為2020.1版本,能夠調(diào)用現(xiàn)成的庫(kù)來設(shè)計(jì)開發(fā),能夠?qū)崿F(xiàn)軟件的開發(fā)。2.2Python概述Python是近幾年來逐漸流行的具有極強(qiáng)擴(kuò)展性的一門編程語(yǔ)言。具有強(qiáng)大的功能價(jià)值,能夠?qū)崿F(xiàn)將各種不同的編程語(yǔ)言制作的模塊綜合聯(lián)結(jié)應(yīng)用。與Pycharm一樣,Python也是能夠跨平臺(tái)利用的,能夠在Windows,MacOS或者是linux上實(shí)現(xiàn)運(yùn)行。在本次設(shè)計(jì)中使用的編程語(yǔ)言即為Python,版本為3.7,其具有的功能庫(kù)能夠滿足我對(duì)于本次軟件開發(fā)的要求。3軟件需求與功能描述3.1需求描述由于現(xiàn)代技術(shù)的日益精進(jìn),人們?cè)谏钌系囊笤絹碓礁?,開始將大部分注意力放在了享受生活上?;诂F(xiàn)代人的心理需要,大量的娛樂游戲軟件開始涌現(xiàn),以供人們消遣閑暇的時(shí)間?;赑ython的中國(guó)象棋軟件將服務(wù)于所有年齡段的用戶,以廣大象棋愛好者為受眾群體,滿足象棋愛好者們下棋的需要,感受人工智能的魅力,這就是開發(fā)這么一款象棋軟件的初衷。3.2功能描述基于Python的中國(guó)象棋軟件主要是服務(wù)于電腦端的用戶,增加業(yè)余時(shí)間的趣味性。本軟件具備有人機(jī)對(duì)戰(zhàn)、開啟、關(guān)閉背景音、悔棋、重新開局、退出游戲等功能。人機(jī)對(duì)戰(zhàn),打開軟件,用戶為先手紅棋子,電腦為后手黑棋子,用戶先點(diǎn)擊所要移動(dòng)的棋子,再點(diǎn)擊想要移動(dòng)到的位置,就完成了的我方用戶棋子移動(dòng)。電腦通過Alpha-beta剪枝算法的計(jì)算,再以歷史啟發(fā)算法的優(yōu)化,通過評(píng)估函數(shù)評(píng)估出每步棋勝利的概率,最后會(huì)將棋子自動(dòng)移動(dòng)到勝率最高的位置,完成電腦方的下棋。兩個(gè)功能相互結(jié)合,即完成了人機(jī)對(duì)戰(zhàn)的功能。開啟、關(guān)閉背景音樂。打開軟件,點(diǎn)擊“音效控制”的按鍵,音樂的自動(dòng)初始化和加載,實(shí)現(xiàn)自動(dòng)播放背景音樂的作用,此時(shí)再次通過點(diǎn)擊“音效控制”的按鍵,阻止音樂播放事件的發(fā)生。同理,如果再想打開音樂可以再次點(diǎn)擊“音效控制”按鈕,音樂又會(huì)重新加載播放。悔棋。打開軟件,在對(duì)戰(zhàn)的過程中可以隨時(shí)點(diǎn)擊“悔棋”按鍵,即可返回上一步的棋局,又可重新選擇棋子完成棋局。重新開局。在對(duì)戰(zhàn)的過程中可以隨時(shí)點(diǎn)擊“重新開局”按鍵,即可完成重新開局的操作。退出游戲。打開軟件,點(diǎn)擊退出游戲的按鍵區(qū)域,即可完成軟件的退出。4軟件設(shè)計(jì)與實(shí)現(xiàn)4.1軟件設(shè)計(jì)原理本軟件實(shí)現(xiàn)的目標(biāo)是能進(jìn)行人機(jī)對(duì)戰(zhàn)的一款中國(guó)象棋軟件,主要包括了人工智能的算法的實(shí)現(xiàn)以及輔助功能的實(shí)現(xiàn),由Python語(yǔ)言進(jìn)行開發(fā),主要運(yùn)用到Pygame等庫(kù),方便游戲的開發(fā)。主程序文件Chinachese.py統(tǒng)籌實(shí)現(xiàn)所有功能,運(yùn)行主程序即可以對(duì)象棋游戲進(jìn)行操作。軟件主要包括了以下四個(gè)模塊:頁(yè)面布局的設(shè)置棋局與棋子的表示博弈程序的實(shí)現(xiàn)各項(xiàng)輔助功能整個(gè)軟件的運(yùn)行也是四個(gè)模塊運(yùn)行的共同結(jié)果,其中博弈程序的實(shí)現(xiàn)是整個(gè)軟件的重難點(diǎn)。利用Python語(yǔ)言的卓越的通用性、高效性、靈活性與安全性實(shí)現(xiàn)軟件各項(xiàng)功能的正常運(yùn)行。這樣開發(fā)的軟件不僅在操作界面上能達(dá)到整潔美觀的要求,而且也可以在Windows系統(tǒng)平臺(tái)上穩(wěn)定運(yùn)行。設(shè)計(jì)的思路按照普通棋局對(duì)戰(zhàn)思路來進(jìn)行設(shè)計(jì),如圖4-1所示:圖4-SEQ圖表\*ARABIC\s11軟件實(shí)現(xiàn)流程圖4.2頁(yè)面布局設(shè)計(jì)點(diǎn)擊運(yùn)行程序即可運(yùn)行軟件進(jìn)入到象棋操作界面,操作界面是主程序Chinesschess.py文件中比較基礎(chǔ)的部分,創(chuàng)建了一個(gè)900px*650px的游戲窗口,并通過Pygame庫(kù)在窗口上進(jìn)行其他樣式的設(shè)置。圖4-SEQ圖表\*ARABIC\s12軟件操作界面圖簡(jiǎn)潔明了是UI設(shè)計(jì)上最大的要求。首先棋盤棋子界面,在主頁(yè)面的左側(cè)。用戶可以以點(diǎn)擊棋子的方式實(shí)現(xiàn)棋子的移動(dòng),便于操作。主頁(yè)面的右上側(cè)是提示區(qū)域,主要作用是顯示當(dāng)前用戶的文檔信息。右下角是工具欄,設(shè)置了四個(gè)按鍵:重新開局、悔棋、開啟(關(guān)閉)音樂、退出游戲。當(dāng)鼠標(biāo)移動(dòng)到該按鍵的區(qū)域時(shí),字體顏色會(huì)由黑色變成紅色,展現(xiàn)一個(gè)懸停的效果。用戶可以通過點(diǎn)擊按鍵的方式觸發(fā)相應(yīng)的函數(shù)實(shí)現(xiàn)各種各樣的功能。完成的整個(gè)界面如圖圖4-SEQ圖表\*ARABIC\s12軟件操作界面圖4.3棋局與棋子表示4.3.1棋局的表示整個(gè)棋局表示采用的是傳統(tǒng)、簡(jiǎn)單的“棋盤列表”,即生成一個(gè)9*10的二維數(shù)據(jù)列表記錄儲(chǔ)存每個(gè)棋子的位置信息,數(shù)據(jù)列表里的元素相對(duì)應(yīng)的就是棋盤上的位置點(diǎn)是否存在棋子、存在哪種類型的棋子。初始棋局的表示需要將原始棋子的位置點(diǎn)信息添加到該數(shù)據(jù)列表里,完成數(shù)據(jù)的初始化。通過棋局的表示方便博弈程序中對(duì)當(dāng)前棋局狀況的識(shí)別與辨認(rèn)。4.3.2棋子的表示如果將每一個(gè)棋子看成是數(shù)據(jù)點(diǎn),將棋盤看作是一個(gè)平面坐標(biāo)系,具備儲(chǔ)存數(shù)據(jù)點(diǎn)的功能,就可以將每個(gè)棋子的位置信息固定在橫坐標(biāo)X的范圍在0到10之間,縱坐標(biāo)Y的范圍在0到11之間。有了坐標(biāo)范圍的限制,就可以通過坐標(biāo)點(diǎn)的加減來控制著法,即以想要移動(dòng)到的位置的坐標(biāo)點(diǎn)的值減去棋子本身坐標(biāo)點(diǎn)的值,若是符合要求則移動(dòng),若不符合就返回錯(cuò)誤值。若是移動(dòng)棋子,則修改其中的坐標(biāo)值即可。至于在中國(guó)象棋里獨(dú)有的“吃子”規(guī)則,也是通過坐標(biāo)點(diǎn)的計(jì)算來限制。被吃掉的棋子用超越范圍的數(shù)來表示。在這其中可以用一個(gè)字節(jié)為32的一維數(shù)組piecesList來表示每一個(gè)棋子的位置,其中每個(gè)字節(jié)的高4位表示棋子的橫坐標(biāo),低4位表示縱坐標(biāo)。有了局面與棋子的表示,就完成了整個(gè)程序的基礎(chǔ)部分,相當(dāng)于建立好了地基,之后的電腦搜索與功能實(shí)現(xiàn)都將建立在此基礎(chǔ)之上。4.4博弈程序的實(shí)現(xiàn)4.4.1著法生成著法即是棋子下棋的走法。著法生成的基本思路是:讀取當(dāng)前現(xiàn)有的棋盤,將棋盤上每一個(gè)棋子的位置數(shù)據(jù)都搜索查看一遍,根據(jù)棋子的類型返回所有的可行著法,最后通過價(jià)值評(píng)估判斷出對(duì)自己最有利的棋子著法儲(chǔ)存到著法隊(duì)列中,并將該著法隊(duì)列返回到棋局?jǐn)?shù)據(jù)列表中。著法的生成是為了方便進(jìn)行搜索,因?yàn)檫^多層數(shù)的搜索會(huì)導(dǎo)致搜索時(shí)間過長(zhǎng)的情況,所以為了避免搜所效果不理想的情況,在本次設(shè)計(jì)中設(shè)定搜索的層數(shù)為4層。這樣不僅保證了搜索時(shí)的效率,同時(shí)還保證了搜索的質(zhì)量,表現(xiàn)在電腦的下棋水平會(huì)相對(duì)較高。4.4.2博弈樹概念機(jī)器博弈在電腦游戲中十分普遍,在中國(guó)象棋的實(shí)踐中也需要用到博弈的概念。通常以博弈樹的結(jié)構(gòu)來解決機(jī)器博弈的一系列問題。圖4-SEQ圖表\*ARABIC\s13圖4-SEQ圖表\*ARABIC\s13博弈樹結(jié)構(gòu)圖在這棵博弈樹的結(jié)構(gòu)里,每一層代表其中一方走子,結(jié)點(diǎn)代表不同的走子方式產(chǎn)生的不同局面,從每一個(gè)結(jié)點(diǎn)衍生出來的又是另外與之相對(duì)抗的結(jié)點(diǎn)。反反復(fù)復(fù),直到到達(dá)葉子結(jié)點(diǎn),即出現(xiàn)沒有其他走法、棋局結(jié)束的局面,博弈樹才停止。在該博弈樹的結(jié)構(gòu)里,一共出現(xiàn)了三種類型的結(jié)點(diǎn):奇數(shù)層結(jié)點(diǎn)(包括根節(jié)點(diǎn)),表示紅方走棋;偶數(shù)層結(jié)點(diǎn),表示黑方走棋;葉子結(jié)點(diǎn),表示棋局結(jié)束。計(jì)算機(jī)下棋的思路,就是將博弈樹全部查看過一遍,試走每一種可能性,并在眾多的可能性之中相互比較并選出唯一一種對(duì)自己最有利的走法,以此來幫助自己獲得勝利。那么判斷可能性的成功值成了博弈樹關(guān)鍵所在,若給每一個(gè)結(jié)點(diǎn)都打上相應(yīng)的分值,通過比較分值的大小來間接反映局面的優(yōu)劣,那么就能夠?qū)崿F(xiàn)判斷判斷最優(yōu)走法。還是假定甲乙兩方下棋,甲方勝利的局面標(biāo)記為一個(gè)極大值α(一個(gè)極大的正數(shù)),對(duì)手方乙方勝利的局面標(biāo)記為一個(gè)極小值β(極大值的負(fù)數(shù)),和棋的局面標(biāo)記為零或是接近于零的值。在博弈的過程中,甲方會(huì)盡可能地使局面分值處于較大的值,從而執(zhí)行奇數(shù)層上分值最大的結(jié)點(diǎn),而乙方則會(huì)采取措施使局面分值盡可能的小,從而執(zhí)行偶數(shù)層上分值最小的結(jié)點(diǎn)。這就是“最小-最大”思想。博弈樹在中國(guó)象棋的應(yīng)用里是存在缺陷的,即在下棋的過程中,平均著法大概有40種左右,那么搜索4層的博弈樹將需要檢查大約250萬(wàn)條路線,不僅工程量會(huì)成指數(shù)增長(zhǎng),而且還特別費(fèi)時(shí)。[5]4.4.2Alpha-beta剪枝算法Alpha-beta剪枝,能夠做到在不影響搜索精度的條件下減少搜索的工作量,它的核心思想就是在進(jìn)行搜索的過程中利用上當(dāng)前局面的信息來進(jìn)行剪枝的方法。它的實(shí)現(xiàn)基于一種想法:如果存在某一種選擇會(huì)比眼前的選擇更加適合,那么就可以證明眼前的選擇并不是最佳,便可以進(jìn)行剪枝處理,在后面搜索的過程中將不需要對(duì)眼前的選擇進(jìn)行考慮。Alpha-beta剪枝算法在進(jìn)行搜索時(shí),將始終記錄節(jié)點(diǎn)的α值和β值。通過比較不同節(jié)點(diǎn)之間的α、β值來進(jìn)行剪枝。α的初始值為負(fù)無窮,代表的是MAX方的最優(yōu)值,β初始值為正無窮,代表的是MIN方的最優(yōu)值。在MAX方搜索時(shí),只改變?chǔ)林?,將其?shù)值改變成max(自身,下一層α,下一層β);同樣的,在MIN方搜索時(shí),只改變?chǔ)轮担瑢⑵鋽?shù)值改變成min(自身,下一層α,下一層β)。α與β的傳遞順序?yàn)橄缺闅v左子樹,返回至父結(jié)點(diǎn)之后再遍歷右子樹。剪枝的實(shí)質(zhì)就是當(dāng)某個(gè)結(jié)點(diǎn)的分?jǐn)?shù)值存在α≥β時(shí),將該支路進(jìn)行裁剪。剪枝算法模型如圖4-4所示:圖4-SEQ圖表\*ARABIC\s14Alpha-Beta剪枝算法模型圖在圖示中,A為根節(jié)點(diǎn),屬于MAX方,其α=-∞,β=+∞,其數(shù)值將依次傳遞至以下結(jié)點(diǎn),成為各節(jié)點(diǎn)的初始值。對(duì)于結(jié)點(diǎn)E而言,屬于MIN方,改變其β值為最小值,這里取10,改變之后E結(jié)點(diǎn)的數(shù)值就為α=-∞,β=10。在按照順序遍歷右子樹,再次改變?chǔ)轮禐?。對(duì)于C點(diǎn)而言,屬于MAX方,只改變其α值為最大值。由于-∞<5,因此,C節(jié)點(diǎn)的數(shù)值為α=5,β=+∞。當(dāng)搜索到B節(jié)點(diǎn)時(shí),再將該數(shù)值向另一分支往下傳遞,重新依次按照方法對(duì)D、G和H節(jié)點(diǎn)進(jìn)行遍歷。最后發(fā)現(xiàn)在搜索到“D-G”這條分支時(shí),D節(jié)點(diǎn)的數(shù)值改變?yōu)棣?7,β=7,出現(xiàn)了α≥β的情況,因此將該分支進(jìn)行剪枝處理。在最理想的情況下,通過Alpha-Beta剪枝算法處理的博弈樹是初始的極大極小值算法的平方根級(jí)。因此,該算法成為博弈程序中改進(jìn)的基礎(chǔ)算法,而且生成博弈樹中的節(jié)點(diǎn)排列順序?qū)糁πЧ灿泻艽蟮挠绊?。在本軟件中,Alpha-Beta代碼的實(shí)現(xiàn)主要是在my_game.py文件中定義,具體代碼如下:defalpha_beta(self,depth,alpha,beta):#alpha-beta剪枝,alpha是大可能下界,beta是最小可能上界
who=(self.max_depth-depth)%2#那個(gè)玩家
ifself.is_game_over(who):#判斷是否游戲結(jié)束,如果結(jié)束了就不用搜了
returncc.min_val
ifdepth==1:#搜到指定深度了,也不用搜了
returnself.evaluate(who)
move_list=self.board.generate_move(who)#返回所有能走的方法
#利用歷史表0
foriinrange(len(move_list)):
move_list[i].score=self.history_table.get_history_score(who,move_list[i])#啟用歷史啟發(fā)法
move_list.sort()#為了讓更容易剪枝利用歷史表得分進(jìn)行排序
best_step=move_list[0]
score_list=[]
forstepinmove_list:#遍歷著法列表
temp=self.move_to(step)#執(zhí)行著法
score=-self.alpha_beta(depth-1,-beta,-alpha)#遞歸調(diào)用,因?yàn)槭且粚舆x最大一層選最小,所以利用取負(fù)號(hào)來實(shí)現(xiàn)
score_list.append(score)#返回分?jǐn)?shù)值
self.undo_move(step,temp)#撤銷著法
ifscore>alpha:#進(jìn)行搜索
alpha=score
ifdepth==self.max_depth:
self.best_move=step#返回最優(yōu)著法
best_step=step
ifalpha>=beta:#進(jìn)行裁剪
best_step=step
break
ifbest_step.from_x!=-1:#更新歷史表
self.history_table.add_history_score(who,best_step,depth)
returnalpha4.4.3歷史啟發(fā)算法根據(jù)Alpha-beta剪枝算法的思想來看,樹的結(jié)構(gòu)就在很大程度上對(duì)它的效率有影響。如果只有在分析了所有的可能性之后才實(shí)現(xiàn)剪枝,那么剪枝也就失去了原先的價(jià)值?;诖颂岢鲆环N方案,那就是如果能夠給計(jì)算機(jī)提供一個(gè)搜索輔助,將提早進(jìn)行剪枝,那工作量就會(huì)減少,也在一定程度上提高了搜索的效率?;诖讼敕?,在進(jìn)行Alpha-beta剪枝算法搜索的過程中,引入一個(gè)排序的思想,當(dāng)發(fā)現(xiàn)一個(gè)好的走法的時(shí)候,就給該走法累加一個(gè)增量以記錄其“歷史得分”,這樣一個(gè)被多次搜索并認(rèn)為是最佳的走法的“歷史得分”就會(huì)較高。得分的高低將影響搜索結(jié)點(diǎn)的排序,在搜索的過程中,得分高的結(jié)點(diǎn),也就是最優(yōu)的走法將會(huì)優(yōu)先進(jìn)行剪枝搜索。這樣Alpha-Beta搜索就可以實(shí)現(xiàn)盡可能早地進(jìn)行“裁剪”,從而保證了搜索的效率。具體代碼的實(shí)現(xiàn)主要是在history_heuristic.py文件中。4.4.4價(jià)值評(píng)估函數(shù)在進(jìn)行Alpha-beta剪枝搜索的同時(shí)要進(jìn)行的就是評(píng)價(jià)函數(shù)對(duì)當(dāng)前局面的評(píng)估。評(píng)價(jià)函數(shù)不僅僅要考慮到剪枝搜索的α值和β值,還要綜合考慮棋子的固定子力值、棋子的位置價(jià)值、以及棋子靈活度評(píng)估值和棋子威脅、保護(hù)評(píng)估值等。只有在能夠綜合考慮各種情況、因素的合理的評(píng)價(jià)函數(shù)的評(píng)估下才能夠?qū)Ξ?dāng)前局面做出最正確的判斷。棋子的固定棋力。每個(gè)棋子都具有其相應(yīng)的價(jià)值能量大小,這就是棋子的固定棋力。在棋局中,如果哪一方的棋子的固定棋力比較大,那么這一方在當(dāng)前棋局中就處于一個(gè)相對(duì)優(yōu)勢(shì)的局面。一般而言,將(帥)的棋力最大,而卒(兵)的棋力最小,其中排序依次為:將(帥)、車、馬、炮、士(仕)、象(相)、卒(兵)。在本軟件中棋子固定棋力的數(shù)據(jù)如表4-1所示。表4-1棋子固定棋力數(shù)據(jù)表棋子將士象馬車炮卒棋子固定棋力1000025025030050030080棋子的位置價(jià)值。在中國(guó)象棋中,同樣棋子在不一樣的位置點(diǎn)上存在著不一樣的價(jià)值,不同的棋子在同一位置點(diǎn)上也存在著不一樣的價(jià)值。例如,在初始狀態(tài)或者未進(jìn)入九宮之前,卒的棋力都比較小,對(duì)棋局的威脅力相對(duì)小。而當(dāng)卒進(jìn)入到九宮之后,由于走法沒有了限制,對(duì)對(duì)方的威脅就較大,故可以稱其為位置力較大。不同棋子的位置價(jià)值需要通過設(shè)計(jì)者自己設(shè)置,以9*10的數(shù)組列表記錄每一個(gè)棋子不同位置的價(jià)值。棋子的靈活程度值。每個(gè)棋子都有其自身的走法規(guī)則限制,例如馬走日,象走田等規(guī)則,這就影響了棋子的靈活程度。靈活度較高的棋子可以在棋局中自由移動(dòng),因此其靈活程度值就比較高。相反的,那些有條件限制的棋子靈活程度值就比較低。一般來說,在中國(guó)象棋的棋盤里,兵(卒)靈活程度值最高,靈活程度值最差的是將和炮。[6]在本軟件中設(shè)置棋子靈活程度值的數(shù)據(jù)如表4-2所示。表4-2棋子靈活程度數(shù)據(jù)表棋子將士象馬車炮卒靈活程度值011126615棋子狀態(tài)評(píng)估值。在棋局中,棋子可能處于兩種狀態(tài),一種是處于被對(duì)方棋子威脅的狀態(tài),另一種是被自己的棋子保護(hù)的狀態(tài)。無論是哪種狀態(tài)都影響棋子的安全系數(shù),影響對(duì)當(dāng)前棋局的判斷。因此,在編寫評(píng)價(jià)函數(shù)時(shí)也要將棋子的狀態(tài)值考慮進(jìn)去。當(dāng)棋子處于被其他棋子保護(hù)、相對(duì)安全的狀態(tài)下時(shí)則提高其評(píng)估值,而當(dāng)處于威脅狀態(tài)時(shí),減低其評(píng)估值。在實(shí)際代碼的應(yīng)用中,以num_guarded來記錄棋子受到保護(hù)的值,以num_attacked來記錄棋子受到威脅的值。在價(jià)值評(píng)估的函數(shù)里,主要涉及到的數(shù)據(jù)量有relation_list=self.init_relation_list()#記錄、儲(chǔ)存關(guān)系信息base_val=[0,0]#基礎(chǔ)價(jià)值,固定棋力
pos_val=[0,0]#位置價(jià)值
mobile_val=[0,0]#棋子靈活程度價(jià)值
relation_val=[0,0]#棋子狀態(tài)評(píng)估價(jià)值最后計(jì)算機(jī)計(jì)算出來的價(jià)值量就是各個(gè)價(jià)值之和,最后合計(jì)為最大價(jià)值量my_max_val與最小價(jià)值量my_min_val。價(jià)值函數(shù)返回值就是最大價(jià)值量與最小價(jià)值量之差。ifwho==0:#判斷當(dāng)前用戶為要求最大值的玩家
returnmy_max_val-my_min_val
else:
returnmy_min_val-my_max_val綜合剪枝搜索算法,價(jià)值評(píng)估函數(shù)之后產(chǎn)生的最優(yōu)結(jié)果最后會(huì)返回到當(dāng)前棋局中實(shí)現(xiàn)棋子的移動(dòng)。整個(gè)博弈程序的實(shí)現(xiàn)流程如圖4-5所示圖4-SEQ圖表\*ARABIC\s15博弈程序?qū)崿F(xiàn)流程圖圖4-SEQ圖表\*ARABIC\s15博弈程序?qū)崿F(xiàn)流程圖5.1悔棋悔棋是棋類軟件中最基本的功能。為了完成悔棋的功能,主要完成以下任務(wù):提取所要還原的棋子信息;改變棋子的坐標(biāo)值,恢復(fù)上一步數(shù)據(jù)值;將數(shù)據(jù)在記錄走法的數(shù)據(jù)數(shù)組列表里刪除。首先就是需要記錄好每一步的走棋信息,根據(jù)走棋的信息來完成撤銷著法的操作,在本次軟件設(shè)計(jì)中,走棋的信息用數(shù)組move_pieces_history[]來記錄,在該數(shù)組中,用戶棋子操作與計(jì)算機(jī)棋子操作為一個(gè)元素,每一個(gè)元素里又存在數(shù)組專門記錄了棋子類型、未移動(dòng)位置時(shí)的X值以及未移動(dòng)位置時(shí)的Y值。詳細(xì)的記錄是為了確保數(shù)據(jù)信息的完整,在執(zhí)行悔棋操作時(shí)不容易出錯(cuò)。提取走棋信息數(shù)組的最后一個(gè)元素,將其未改變之前的坐標(biāo)值反賦值到棋子的坐標(biāo)值數(shù)據(jù)里,實(shí)現(xiàn)當(dāng)前棋子的坐標(biāo)值與未移動(dòng)之前的坐標(biāo)值相一致。最后一步就是將存儲(chǔ)在走棋信息數(shù)組里的信息刪除。defrepentance(self):
iflen(self.move_pieces_history)==0:#判斷是否有棋子發(fā)生了移動(dòng)
return
else:
temp_moved_pieces_infos=self.move_pieces_history[-1]#獲取列表最后一個(gè)元素
foriteminself.piecesList:#將元素返回前一個(gè)元素的位置,主要是x,y的值的還原
ifitem.x==temp_moved_pieces_infos[1][0].xanditem.y==temp_moved_pieces_infos[1][0].y:#還原用戶棋子
item.x=temp_moved_pieces_infos[1][1]
item.y=temp_moved_pieces_infos[1][2]
ifitem.x==temp_moved_pieces_infos[0][0].xanditem.y==temp_moved_pieces_infos[0][0].y:#還原計(jì)算機(jī)棋子
item.x=temp_moved_pieces_infos[0][1]
item.y=temp_moved_pieces_infos[0][2]
self.move_pieces_history.pop(-1)#移除歷史列表中最后的一個(gè)元素,即最后一步操作步驟5.2重新開局重新開局的功能的實(shí)現(xiàn)需要提前定義一個(gè)變量,在本次軟件設(shè)計(jì)中,將該變量定義命名為:isrestart_flag,判斷0或是1。若是0,則表示繼續(xù)當(dāng)前棋局,若是1,則對(duì)當(dāng)前繪制的游戲窗口進(jìn)行重新執(zhí)行的操作,以此來完成重新開局的操作。5.3音效控制音效控制的實(shí)現(xiàn)方式與重新開局方式一致,同樣為定義變量,通過變量的轉(zhuǎn)換來實(shí)現(xiàn)背景音樂開關(guān)的功能。在本次軟件設(shè)計(jì)中,將控制音效的變量名稱定義為:is_mute_flag,為了區(qū)別于重新開局的變量,將控制音效的判斷設(shè)置為Ture與Flase。若是Ture,則音樂暫停,若為Flase,則音樂播放。6軟件測(cè)試軟件測(cè)試的作用主要是為了查看驗(yàn)證預(yù)定功能是否得到實(shí)現(xiàn)。如果代碼無錯(cuò)誤,并且功能都得到了實(shí)現(xiàn),那么則說明軟件設(shè)計(jì)與開發(fā)是符合要求的。根據(jù)預(yù)期的要求,軟件測(cè)試將分為人機(jī)對(duì)弈、重新開局、悔棋操作、開啟(關(guān)閉)背景音樂以及退出游戲五個(gè)部分來進(jìn)行測(cè)試,測(cè)試結(jié)果如下。6.1人機(jī)對(duì)弈打開中國(guó)象棋文件Chinahess,運(yùn)行主程序Chinachess.py,出現(xiàn)游戲的操作界面:棋盤界面、提示框部分界面以及功能鍵界面。提示框顯示當(dāng)前用戶為紅色,即需要用戶先點(diǎn)擊想要移動(dòng)的紅色棋子,再點(diǎn)擊想要棋子移動(dòng)到的交叉點(diǎn)上。點(diǎn)擊紅色“兵”棋,再次點(diǎn)擊正上方的棋盤交叉點(diǎn),提示框顯示當(dāng)前用戶為黑色,即棋子已經(jīng)實(shí)現(xiàn)了移動(dòng),等待黑棋子走下一步。當(dāng)黑棋走了下一步,提示框?qū)⒆詣?dòng)跳轉(zhuǎn)提示用戶下棋。假如點(diǎn)擊之后提示框始終提示當(dāng)前用戶為紅棋子,那么則說明點(diǎn)擊想要去的坐標(biāo)點(diǎn)不符合象棋游戲規(guī)則,需要重新點(diǎn)擊符合規(guī)則的交叉點(diǎn)。若某一方的棋子想要到達(dá)的交叉點(diǎn)上存在著對(duì)方的棋子,在符合游戲規(guī)則的前提下,對(duì)方的棋子將會(huì)被撤掉,換上我方的棋子,如此則完成吃棋的操作。當(dāng)某一方的將(帥)被對(duì)方棋子吃掉后,操作界面顯示“電腦(用戶)勝利!“字樣”,如圖5-1所示:圖5-SEQ圖表\*ARABIC\s11獲勝界面6.2重新開局當(dāng)游戲進(jìn)行到一半時(shí),點(diǎn)擊“重新開局”按鍵,所有的棋子回到原位,可以重新開始新的棋局。重新開局功能測(cè)試完成。6.3悔棋游戲進(jìn)行到一半時(shí),點(diǎn)擊“悔棋”按鍵,則黑棋與紅棋的同時(shí)返回上一步之前的位置。例如:在游戲開始后,點(diǎn)擊任意一個(gè)棋子移動(dòng),然后點(diǎn)擊“悔棋”按鍵,棋子退回到原先的狀態(tài)?;谄骞δ軠y(cè)試完成。6.4開啟(關(guān)閉)音樂打開軟件,彈出游戲界面。點(diǎn)擊“音效控制”按鍵,背景音自動(dòng)播放。再次點(diǎn)擊“音效控制”按鍵,音樂重新關(guān)閉。開啟(關(guān)閉)音樂功能測(cè)試完成。6.5退出游戲打開軟件,彈出游戲操作界面,點(diǎn)擊“退出游戲”按鍵,游戲界面關(guān)閉,程序強(qiáng)制退出。退出游戲功能測(cè)試完成。經(jīng)過測(cè)試可以驗(yàn)證預(yù)定的功能均已實(shí)現(xiàn),滿足了預(yù)期的要求,達(dá)到了開發(fā)設(shè)想,完成了設(shè)計(jì)與開發(fā)的任務(wù)。在系統(tǒng)的編碼上能夠?qū)⒏鱾€(gè)功能實(shí)現(xiàn)模塊化,編寫風(fēng)格規(guī)范化,提高了整個(gè)軟件系統(tǒng)的可讀性以及延展性。7總結(jié)本文針對(duì)計(jì)算機(jī)博弈與中國(guó)象棋游戲相結(jié)合進(jìn)行了深入的研究,在理解了象棋規(guī)則、計(jì)算機(jī)博弈論的基礎(chǔ)上,實(shí)現(xiàn)了具有普通人棋力的中國(guó)象棋軟件。在這個(gè)過程中,我將大學(xué)四年來所學(xué)到的知識(shí)運(yùn)用上,感受到了知識(shí)的巨大用途。能夠?qū)⒅R(shí)運(yùn)用到實(shí)踐中,我覺得四年的時(shí)間沒有白白浪費(fèi)。然而,我的水平還不是很高,在程序設(shè)計(jì)方面也存在著一些不足。例如對(duì)人工智能的算法不夠熟悉,在理解搜索原理時(shí)花費(fèi)了大量的實(shí)踐與精力,導(dǎo)致整個(gè)設(shè)計(jì)的進(jìn)程速度慢。再比如,軟件程序雖然實(shí)現(xiàn)了悔棋、重新開局等功能,卻在使用上具有局限性,偶爾會(huì)出現(xiàn)代碼沖突的問題。雖然這次設(shè)計(jì)開發(fā)算不上是完美的,卻也花費(fèi)了我許多的精力去深入研究學(xué)習(xí)。學(xué)習(xí)是沒有邊際的,我會(huì)在以后的時(shí)間里繼續(xù)深入學(xué)習(xí),努力將軟件開發(fā)實(shí)現(xiàn)得更加智能,靈敏。
參考文獻(xiàn)[1]劉丹奕.淺談人工智能在游戲開發(fā)中的應(yīng)用[J].黑龍江科技信息,2014,(36):128,69.[2]曹坤澤.人工智能及其在游戲領(lǐng)域中的應(yīng)用[J].科技傳播,2020,12(08):143-144.[3]韓繼凱.遠(yuǎn)程遙控中國(guó)象棋對(duì)弈機(jī)器人系統(tǒng)研制[R].南京:南昌大學(xué),2019:3-5.[4]孔德帥.中國(guó)象棋人機(jī)博弈系統(tǒng)的研究與實(shí)現(xiàn)[R].山東:青島大學(xué),2020:1-3,27-29.[5]黎利輝.基于Alpha-Beta剪枝法的中國(guó)象棋博弈系統(tǒng)研究[J].福建電腦.2014,30(03):29-50.[6]湯云雄.中國(guó)象棋布局基本原則的重要性研究[J].現(xiàn)代鹽化工,2020,47(03):50-102.
英文摘要ThedesignanddevelopmentofChinesechesssoftwarebasedonPythonAbstract:TheimplementationofChinesechessprogramismainlydividedintotwoparts,namely,artificialintelligenceandauxiliaryfunctions.Thepartofartificialintelligenceisembodiedinthecalculationthinkingofcomputerplayingchess,includingsearchingalgorithmsearchingformoves,evaluationfunctionevaluatingthevalueofvariousmoves,andfinallychoosingthebestmove.Andtheauxiliaryfunctionismainlythroughthealgorithm,fortheman-machinewartoaddavarietyoffunctions,addthefunoftheuserplayingchess.Firstly,thispaperstudiesthecurrentsituationandprospectofcomputerprogramminginChinesechess.Onthebasisofstudyingthesearchofmaximumandminimumvaluesincomputergametheory,theChinesechessprogramwithordinarypeople'schessabilityisrealizedbyusingPythonlanguageandPyCharmdevelopmenttoolthroughalpha-betapruningalgorithm.Keywords:Python;Chinesechess;Alpha-betapruningalgorithm
附錄chinachess.pyimportpygame
importtime
importconstants
frombuttonimportButton
importpieces
importcomputer
importmy_gameasmg
classxiaoguo(object):
def__init__(self,text,color,x=None,y=None,**kwargs):
#font_addr=pygame.font.get_default_font()
#font=pygame.font.Font(font_addr,36)
font=pygame.font.SysFont('kaiti',36)
self.surface=font.render(text,True,color)
self.WIDTH=self.surface.get_width()
self.HEIGHT=self.surface.get_height()
if'centered_x'inkwargsandkwargs['centered_x']:
self.x=constants.SCREEN_WIDTH//1.3-self.WIDTH//2
else:
self.x=x
if'centered_y'inkwargsandkwargs['cenntered_y']:
self.y=constants.SCREEN_HEIGHT//2-self.HEIGHT//2
else:
self.y=y
defdisplay(self):
MainGame.window.blit(self.surface,(self.x,self.y))
defcheck_click(self,position):
x_match=position[0]>self.xandposition[0]<self.x+self.WIDTH
y_match=position[1]>self.yandposition[1]<self.y+self.HEIGHT
ifx_matchandy_match:
returnTrue
else:
returnFalse
classMainGame():
window=None
Start_X=constants.Start_X
Start_Y=constants.Start_Y
Line_Span=constants.Line_Span
Max_X=Start_X+8*Line_Span
Max_Y=Start_Y+9*Line_Span
from_x=0
from_y=0
to_x=0
to_y=0
clickx=-1
clicky=-1
mgInit=mg.my_game()
player1Color=constants.player1Color#用戶
player2Color=constants.player2Color#機(jī)器人
Putdownflag=player1Color
piecesSelected=None
button_go=None
piecesList=[]
isrestart_flag=1
is_end_flag=1
#代碼里所有flag=1的地方都打印dataerror的,所以是用來標(biāo)記異常的。flag初始為0,表示為正常狀態(tài)。只要flag值沒被改成1,就說明輸入正常,一直循環(huán)輸入;如果輸入錯(cuò)誤,即flag被改為1,那么就停止輸入,程序結(jié)束。
is_mute_flag=False#是否靜音True靜音False不靜音
move_pieces_history=[]
defstart_game(self):
MainGame.window=pygame.display.set_mode([constants.SCREEN_WIDTH,constants.SCREEN_HEIGHT])
pygame.display.set_caption("中國(guó)象棋")
MainGame.button_go=Button(MainGame.window,"重新開局",constants.SCREEN_WIDTH-260,300)#創(chuàng)建開始按鈕
MainGame.button_repentance=Button(MainGame.window,"悔棋",constants.SCREEN_WIDTH-260,350)#創(chuàng)建聲音按鈕
MainGame.button_exit=Button(MainGame.window,"退出游戲",constants.SCREEN_WIDTH-260,450)
play_button=xiaoguo('悔棋',(0,0,0),None,310,centered_x=True)
huiqi_button=xiaoguo('重新開局',(0,0,0),None,360,centered_x=True)
exit_button=xiaoguo('退出游戲',(0,0,0),None,410,centered_x=True)
music_button=xiaoguo('背景音樂',(0,0,0),None,460,centered_x=True)
pygame.mixer.init()
pygame.mixer.music.load("music/bg_music2.mp3")#加載背景音樂
self.piecesInit()
whileTrue:
time.sleep(0.1)
MainGame.window.blit(constants.BG_IMAGE,(0,0))#加載背景圖
#MainGame.window.fill((233,204,138))
self.drawChessboard()
ifplay_button.check_click(pygame.mouse.get_pos()):
play_button=xiaoguo('悔棋',(255,0,0),None,310,centered_x=True)
else:
play_button=xiaoguo('悔棋',(0,0,0),None,310,centered_x=True)
ifhuiqi_button.check_click(pygame.mouse.get_pos()):
huiqi_button=xiaoguo('重新開局',(255,0,0),None,360,centered_x=True)
else:
huiqi_button=xiaoguo('重新開局',(0,0,0),None,360,centered_x=True)
ifexit_button.check_click(pygame.mouse.get_pos()):
exit_button=xiaoguo('退出游戲',(255,0,0),None,410,centered_x=True)
else:
exit_button=xiaoguo('退出游戲',(0,0,0),None,410,centered_x=True)
ifmusic_button.check_click(pygame.mouse.get_pos()):
music_button=xiaoguo('音效控制',(255,0,0),None,460,centered_x=True)
else:
music_button=xiaoguo('音效控制',(0,0,0),None,460,centered_x=True)
play_button.display()
huiqi_button.display()
exit_button.display()
music_button.display()
self.piecesDisplay()
self.VictoryOrDefeat()
ifself.is_end_flag==1:#0:當(dāng)前局游戲已結(jié)束1:未結(jié)束
self.Computerplay()
#print("cccc")
self.isrestart_flag=self.getEvent()#0:重新開始1:不重新開始
#print("dddd")
ifself.isrestart_flag==0:
break
pygame.display.update()#顯示更新
pygame.display.flip()#顯示翻轉(zhuǎn)
ifself.isrestart_flag==0:
return
#MainGame().start_game()
defdrawChessboard(self):#繪畫棋盤界面
#pygame.draw.circle(MainGame.window,[255,0,0],[830,180],20,0)
outer_frame_color=(60,20,0)
pygame.draw.rect(MainGame.window,outer_frame_color,[45,45,491,550],5)
s_font=pygame.font.Font('C:\Windows\Fonts\ARIALUNI.ttf',40)
u_font=pygame.font.Font('C:\Windows\Fonts\ARIALUNI.ttf',30)
my_font=pygame.font.Font('C:\Windows\Fonts\ARIALUNI.ttf',50)
title_font=pygame.font.Font('C:\Windows\Fonts\ARIALUNI.ttf',55)
text4=my_font.render("楚河",True,(0,0,0))
text5=my_font.render("漢界",True,(0,0,0))
text6=title_font.render("中國(guó)象棋",True,(0,0,0))
text7=s_font.render("當(dāng)前用戶:",True,(0,0,0))
text8=u_font.render("玩家",True,(255,0,0))
MainGame.window.blit(text4,(120,285))
MainGame.window.blit(text5,(360,285))
MainGame.window.blit(text6,(600,50))
MainGame.window.blit(text7,(580,150))
MainGame.window.blit(text8,(780,160))
pygame.draw.line(MainGame.window,(0,0,0),(580,140),(860,140))
pygame.draw.line(MainGame.window,(0,0,0),(580,145),(860,145))
mid_end_y=MainGame.Start_Y+4*MainGame.Line_Span
min_start_y=MainGame.Start_Y+5*MainGame.Line_Span
foriinrange(0,9):#豎線設(shè)置
x=MainGame.Start_X+i*MainGame.Line_Span
ifi==0ori==8:
y=MainGame.Start_Y+i*MainGame.Line_Span
pygame.draw.line(MainGame.window,constants.BLACK,[x,MainGame.Start_Y],[x,MainGame.Max_Y],1)
else:
pygame.draw.line(MainGame.window,constants.BLACK,[x,MainGame.Start_Y],[x,mid_end_y],1)
pygame.draw.line(MainGame.window,constants.BLACK,[x,min_start_y],[x,MainGame.Max_Y],1)
foriinrange(0,10):#橫線設(shè)置
x=MainGame.Start_X+i*MainGame.Line_Span
y=MainGame.Start_Y+i*MainGame.Line_Span
pygame.draw.line(MainGame.window,constants.BLACK,[MainGame.Start_X,y],[MainGame.Max_X,y],1)
speed_dial_start_x=MainGame.Start_X+3*MainGame.Line_Span
speed_dial_end_x=MainGame.Start_X+5*MainGame.Line_Span
speed_dial_y1=MainGame.Start_Y+0*MainGame.Line_Span
speed_dial_y2=MainGame.Start_Y+2*MainGame.Line_Span
speed_dial_y3=MainGame.Start_Y+7*MainGame.Line_Span
speed_dial_y4=MainGame.Start_Y+9*MainGame.Line_Span
pygame.draw.line(MainGame.window,constants.BLACK,[speed_dial_start_x,speed_dial_y1],
[speed_dial_end_x,speed_dial_y2],1)
pygame.draw.line(MainGame.window,constants.BLACK,[speed_dial_start_x,speed_dial_y2],
[speed_dial_end_x,speed_dial_y1],1)
pygame.draw.line(MainGame.window,constants.BLACK,[speed_dial_start_x,speed_dial_y3],
[speed_dial_end_x,speed_dial_y4],1)
pygame.draw.line(MainGame.window,constants.BLACK,[speed_dial_start_x,speed_dial_y4],
[speed_dial_end_x,speed_dial_y3],1)
defpiecesInit(self):#后臺(tái)將棋子放在相應(yīng)的位置上,不可見
self.piecesList=[]
self.piecesList.append(pieces.Rooks(self.player2Color,0,0))#坐標(biāo)對(duì)應(yīng)棋子所在棋盤的坐標(biāo)
self.piecesList.append(pieces.Rooks(self.player2Color,8,0))
self.piecesList.append(pieces.Elephants(self.player2Color,2,0))
self.piecesList.append(pieces.Elephants(self.player2Color,6,0))
self.piecesList.append(pieces.King(self.player2Color,4,0))
self.piecesList.append(pieces.Knighs(self.player2Color,1,0))
self.piecesList.append(pieces.Knighs(self.player2Color,7,0))
self.piecesList.append(pieces.Cannons(self.player2Color,1,2))
self.piecesList.append(pieces.Cannons(self.player2Color,7,2))
self.piecesList.append(pieces.Mandarins(self.player2Color,3,0))
self.piecesList.append(pieces.Mandarins(self.player2Color,5,0))
self.piecesList.append(pieces.Pawns(self.player2Color,0,3))
self.piecesList.append(pieces.Pawns(self.player2Color,2,3))
self.piecesList.append(pieces.Pawns(self.player2Color,4,3))
self.piecesList.append(pieces.Pawns(self.player2Color,6,3))
self.piecesList.append(pieces.Pawns(self.player2Color,8,3))
self.piecesList.append(pieces.Rooks(self.player1Color,0,9))
self.piecesList.append(pieces.Rooks(self.player1Color,8,9))
self.piecesList.append(pieces.Elephants(self.player1Color,2,9))
self.piecesList.append(pieces.Elephants(self.player1Color,6,9))
self.piecesList.append(pieces.King(self.player1Color,4,9))
self.piecesList.append(pieces.Knighs(self.player1Color,1,9))
self.piecesList.append(pieces.Knighs(self.player1Color,7,9))
self.piecesList.append(pieces.Cannons(self.player1Color,1,7))
self.piecesList.append(pieces.Cannons(self.player1Color,7,7))
self.piecesList.append(pieces.Mandarins(self.player1Color,3,9))
self.piecesList.append(pieces.Mandarins(self.player1Color,5,9))
self.piecesList.append(pieces.Pawns(self.player1Color,0,6))
self.piecesList.append(pieces.Pawns(self.player1Color,2,6))
self.piecesList.append(pieces.Pawns(self.player1Color,4,6))
self.piecesList.append(pieces.Pawns(self.player1Color,6,6))
self.piecesList.append(pieces.Pawns(self.player1Color,8,6))
defpiecesDisplay(self):#將棋子顯示在主頁(yè)面上
foriteminself.piecesList:#循環(huán)列表
item.displaypieces(MainGame.window)
#MainGame.window.blit(item.image,item.rect)
defgetEvent(self):
#獲取所有的事件
eventList=pygame.event.get()
foreventineventList:
ifevent.type==pygame.QUIT:
self.endGame()
elifevent.type==pygame.MOUSEBUTTONDOWN:
pos=pygame.mouse.get_pos()
mouse_x=pos[0]
mouse_y=pos[1]
#print("aaaaa")
if(
mouse_x>MainGame.Start_X-MainGame.Line_Span/2andmouse_x<MainGame.Max_X+MainGame.Line_Span/2)and(
mouse_y>MainGame.Start_Y-MainGame.Line_Span/2andmouse_y<MainGame.Max_Y+MainGame.Line_Span/2):
ifself.Putdownflag!=MainGame.player1Color:
return
click_x=round((mouse_x-MainGame.Start_X)/MainGame.Line_Span)
click_y=round((mouse_y-MainGame.Start_Y)/MainGame.Line_Span)
click_mod_x=(mouse_x-MainGame.Start_X)%MainGame.Line_Span
click_mod_y=(mouse_y-MainGame.Start_Y)%MainGame.Line_Span
print("")
ifabs(click_mod_x-MainGame.Line_Span/2)>=5andabs(
click_mod_y-MainGame.Line_Span/2)>=5:
#print("有效點(diǎn):x="+str(click_x)+"y="+str(click_y))
#有效點(diǎn)擊點(diǎn)
self.from_x=MainGame.clickx
self.from_y=MainGame.clicky
self.to_x=click_x
self.to_y=click_y
#print(self.from_x)
#print(self.from_y)
MainGame.clickx=click_x
MainGame.clicky=click_y
self.PutdownPieces(MainGame.player1Color,click_x,click_y)#用戶棋子移動(dòng)
else:
if625<mouse_x<765and460<mouse_y<495:#音效控制
print("xxxxxxxx")
#pygame.mixer_music.stop()
ifMainGame.is_mute_flag==False:
print("nnnnnnnnnn")
pygame.mixer.music.play()
else:
print("666666666")
pygame.mixer.music.stop()
MainGame.is_mute_flag=notMainGame.is_mute_flag
if615<mouse_x<755and410<mouse_y<445:#退出游戲
print("zzzzzz")
self.endGame()
#pygame.quit()
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 遼陽(yáng)古建施工方案審批
- 2024年三季度報(bào)湖南地區(qū)A股銷售凈利率排名前十大上市公司
- 快船新球館施工方案
- (教研室)福建省寧德市2024-2025學(xué)年高二上學(xué)期期末考試語(yǔ)文試題
- 揚(yáng)塵施工方案
- 預(yù)制濾板施工方案
- 2025年柳工營(yíng)銷面試題及答案
- 6年級(jí)上冊(cè)20課青山不老課堂筆記
- 教育教學(xué)評(píng)價(jià)表
- 低空經(jīng)濟(jì)產(chǎn)業(yè)專項(xiàng)引導(dǎo)基金
- 《流程基本知識(shí)》考核試題(答案)
- 【知識(shí)解析】南昌起義主題圖集
- 中班安全活動(dòng) 保護(hù)鼻子
- 板卡錯(cuò)誤代碼對(duì)應(yīng)的錯(cuò)誤信息及解決方案
- 重大事故后果分析
- 武漢理工大學(xué)計(jì)算機(jī)網(wǎng)絡(luò)試題及答案
- 先學(xué)后教當(dāng)堂訓(xùn)練簡(jiǎn)介
- “順豐杯”第三屆全國(guó)大學(xué)生物流設(shè)計(jì)大賽案例
- 灌區(qū)工程施工方案與技術(shù)措施
- 幼兒園繪本:《小蛇散步》 課件
- 華中師大版七年級(jí)心理 2走近老師 課件(共15張PPT)
評(píng)論
0/150
提交評(píng)論