中國(guó)象棋游戲開(kāi)發(fā)設(shè)計(jì)報(bào)告計(jì)劃_第1頁(yè)
中國(guó)象棋游戲開(kāi)發(fā)設(shè)計(jì)報(bào)告計(jì)劃_第2頁(yè)
中國(guó)象棋游戲開(kāi)發(fā)設(shè)計(jì)報(bào)告計(jì)劃_第3頁(yè)
中國(guó)象棋游戲開(kāi)發(fā)設(shè)計(jì)報(bào)告計(jì)劃_第4頁(yè)
中國(guó)象棋游戲開(kāi)發(fā)設(shè)計(jì)報(bào)告計(jì)劃_第5頁(yè)
已閱讀5頁(yè),還剩13頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、優(yōu)選文檔中國(guó)象棋游戲開(kāi)發(fā)設(shè)計(jì)報(bào)告班級(jí):小組編號(hào):小組成員:指導(dǎo)老師:.優(yōu)選文檔一、開(kāi)發(fā)的目的和意義面向?qū)ο蟪绦蛟O(shè)計(jì)作為一門(mén)軟件設(shè)計(jì)的課程,擁有極強(qiáng)的實(shí)踐性,要修業(yè)生具備靈便應(yīng)用理論知識(shí)的能力及面向?qū)ο蟪绦蛟O(shè)計(jì)技術(shù)的基礎(chǔ)。經(jīng)過(guò)游戲開(kāi)發(fā),學(xué)生能認(rèn)識(shí)C+面向?qū)ο蟮脑O(shè)計(jì)方法與技巧,有效地、深刻地理解課程內(nèi)容,領(lǐng)悟理論、方法和設(shè)計(jì)原則,培養(yǎng)解析實(shí)責(zé)問(wèn)題和解決問(wèn)題的能力,具備使用面向?qū)ο蟪绦蛟O(shè)計(jì)開(kāi)發(fā)工具設(shè)計(jì)實(shí)質(zhì)系統(tǒng)的能力。還能夠夠認(rèn)識(shí)并經(jīng)過(guò)使用MFC,掌握一種可視化編程的方法,并經(jīng)過(guò)游戲的開(kāi)發(fā)加深對(duì)可視化編程的理解。同時(shí),能夠提高運(yùn)用C+編程語(yǔ)言解決實(shí)責(zé)問(wèn)題的能力。棋牌游戲?qū)儆谛蓍e類游戲,擁有上手快、游戲

2、時(shí)間短的特點(diǎn),更利于用戶進(jìn)行放松休閑,為人們所喜歡,特別是棋類游戲,方便、快捷、操作簡(jiǎn)單,在休閑娛樂(lè)中占主要地址。中國(guó)象棋作為中國(guó)自古以來(lái)的經(jīng)典棋牌游戲之一,素來(lái)都是人之間的較量,將中國(guó)象棋制作成游戲,能夠?qū)崿F(xiàn)人與計(jì)算機(jī)之間的棋戰(zhàn)。而且人工智能是綜合性很強(qiáng)的一門(mén)邊緣學(xué)科,它的中心任務(wù)是研究如何使計(jì)算機(jī)去做那些過(guò)去只能靠人的智力才能做的工作。開(kāi)發(fā)出了計(jì)算機(jī)象棋游戲,今后不能是能夠進(jìn)行休閑游戲,還能夠鍛煉自己的智力和象棋技術(shù),更加方便了人們的平時(shí)生活。二、功能描述和解析(用戶需求解析)2.1開(kāi)發(fā)背景我們周圍有好多同學(xué)喜歡下象棋,特別是男同學(xué),希望能有人能夠和自己下象棋,但這種意愿常由于碰到條件的限

3、制而難以如愿,比方說(shuō)需要身邊恰巧有現(xiàn)成的棋盤(pán)棋子,比方說(shuō)需若是同樣懂得中國(guó)象棋的對(duì)手,但是大家都知道我們這所大學(xué)男性同學(xué)占少許,即即是條件都滿足了,還要考慮這位對(duì)手可否有何自己下棋的心情。這時(shí),若是有一臺(tái)計(jì)算機(jī),一個(gè)能夠支持人機(jī)棋戰(zhàn)的程序,上面的問(wèn)題瓜熟蒂落。而我們小組的這個(gè)想起游戲設(shè)計(jì),正是希望能夠做出一款擁有優(yōu)異性能,優(yōu)異的智能,能夠滿足大多數(shù)愛(ài)好象棋的同學(xué)的需求中國(guó)象棋人機(jī)棋戰(zhàn)程序。2.2用戶需求解析一款能夠與用戶棋戰(zhàn),滿足用戶需求的中國(guó)象棋程序,需要有棋盤(pán)棋子的場(chǎng)面、鼠標(biāo)響應(yīng)控制棋子搬動(dòng)、棋子的走法規(guī)則、人機(jī)棋戰(zhàn)的找尋算法、防備異常引入的多線程、勝敗判斷,詳盡解析以下:棋盤(pán)棋子的場(chǎng)面作

4、為中國(guó)象棋的這項(xiàng)游戲,其必不能少的是就是棋子和棋盤(pán),沒(méi)有這兩個(gè)部分,想起功能無(wú)法實(shí)現(xiàn),不能是這樣,若是,可是有棋子和棋盤(pán),而沒(méi)有將兩者結(jié)合起來(lái),那么,也將無(wú)法實(shí)現(xiàn)中國(guó)象棋的游戲功能,所以,棋子和棋盤(pán).優(yōu)選文檔的設(shè)計(jì)在這個(gè)游戲設(shè)計(jì)中至關(guān)重要。鼠標(biāo)響應(yīng)在棋戰(zhàn)中,棋子是必定能夠搬動(dòng)的,不然游戲無(wú)法進(jìn)行。所以,鼠標(biāo)左鍵點(diǎn)擊是必不能少的一部分。棋子的功能解析:中國(guó)象棋中各色的象棋棋子的功能使象棋擁有了真切的興趣性,中國(guó)象棋的棋子的種類大體分為:帥(將)、士、象、馬、車、炮、兵(卒)等幾個(gè)種類。帥(將):紅方中的帥和黑方中的將的功能同樣,都是只幸虧九宮格中進(jìn)行橫向和豎向的搬動(dòng),每次搬動(dòng)一格,而且不能夠搬動(dòng)

5、超出九宮格,帥和將不能夠見(jiàn)面。士:士在整片棋盤(pán)中,和帥的搬動(dòng)范圍近似,也是只幸虧九宮格中搬動(dòng),但是士的搬動(dòng)方向是對(duì)角線,而且每次只幸虧一個(gè)格子中搬動(dòng)。象:象的走法依照“象走田”的原則,不能夠絆象腿。馬:馬的走法依照“馬走日”的原則,不能夠絆馬腿。車:在整塊棋盤(pán)中,車能夠橫向或縱向3搬動(dòng)任意格。炮:每次搬動(dòng)和車的近似,但是在吃對(duì)方棋子的時(shí)候必定中間有且只能有一個(gè)棋子的間隔。兵(卒):紅方的兵和黑方的卒的功能同樣,特點(diǎn)是只能向?qū)Ψ角斑M(jìn),而不能夠退后,過(guò)河從前不能夠橫向搬動(dòng),過(guò)河此后能夠橫向搬動(dòng),無(wú)論是前進(jìn)還是橫向搬動(dòng),每次都只能搬動(dòng)一格。優(yōu)異的人機(jī)棋戰(zhàn)要實(shí)現(xiàn)人機(jī)的棋戰(zhàn),找尋算法是很重要的一部分。關(guān)

6、于棋類棋戰(zhàn)程序中的找尋算法,已有成熟的Alpha-Beta找尋算法。我們?cè)诔绦蛑兄苯咏梃b了Alpha-Beta找尋算法并輔以歷史啟示。Alpha-Beta找尋算法:在中國(guó)象棋里,兩方棋手獲得同樣的棋盤(pán)信息。他們輪流走棋,目的就是吃掉對(duì)方的將或帥,也許防備自己的將或帥被吃。找尋算法的找尋過(guò)程很漫長(zhǎng),所以對(duì)找尋算法進(jìn)行簡(jiǎn)化是有必要的。多線程的必要性由于程序在進(jìn)行找尋時(shí)會(huì)占用大量的CPU時(shí)間,所以擁塞了位于同一線程內(nèi)的其他指令,使之無(wú)法正常工作,所以引入了多線程的思想別的開(kāi)一個(gè)線程,讓各程序分開(kāi)于多個(gè)線程。就可以解決程序異常的問(wèn)題了,所以,多線程思想的引入是有必要的。判斷勝敗游戲需要判斷最后由誰(shuí)勝出

7、.優(yōu)選文檔三、采用的開(kāi)發(fā)工具和技術(shù),開(kāi)發(fā)環(huán)境,適用環(huán)境開(kāi)發(fā)工具:VisualC+MFC工程;開(kāi)發(fā)環(huán)境:win7;適用環(huán)境:windows系統(tǒng);四、小組成員分工初始化、場(chǎng)面設(shè)計(jì)部分(賀景);判斷勝敗、棋子走法部分(鄒京甫);鼠標(biāo)響應(yīng)、繪圖部分(吳鑫);找尋引擎部分等由組員共同達(dá)成。五、詳盡開(kāi)發(fā)方法和過(guò)程5.1初始化部分OnInitDialog()負(fù)責(zé)的是對(duì)話框的初始化。能夠把有關(guān)中國(guó)象棋的棋局初始化狀況也放在了這里面。初始化的內(nèi)容包括:對(duì)引擎部分所用到的變量的初始化。包括對(duì)棋盤(pán)上的棋子地址進(jìn)行初始化(棋盤(pán)數(shù)組的初始化),對(duì)找尋深度、當(dāng)前走棋方標(biāo)志、棋局可否結(jié)束標(biāo)志等的初始化;對(duì)棋盤(pán)、棋子的貼圖地

8、址(即棋盤(pán)、棋子在程序中實(shí)質(zhì)顯示地址)的初始化;對(duì)程序協(xié)助部分所用到的一些變量的初始化。棋盤(pán)、棋子樣式的默認(rèn)形式,以及著法名稱列表的初始化等。1.對(duì)棋盤(pán)的初始化memcpy(m_byChessBoard,InitChessBoard,90);2.對(duì)棋盤(pán)、棋子的貼圖地址(即棋盤(pán)、棋子在程序中實(shí)質(zhì)顯示地址)的初始化;MemDC.SelectObject(&pOldBmp);/恢復(fù)內(nèi)存Dc的原位圖3.對(duì)程序協(xié)助部分所用到的一些變量的初始化棋盤(pán)、棋子樣式的默認(rèn)形式,下棋模式的默認(rèn)選擇,以及著法名稱列表的初始化等。初始化部分的代碼以下:BOOLCChessDlg:OnInitDialog()CDialo

9、g:OnInitDialog();AddAbout.menuitemtosystemmenu.IDM_ABOUTBOXmustbeinthesystemcommandrange.優(yōu)選文檔ASSERT(IDM_ABOUTBOX&0 xFFF0)=IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOXAppendMenu(MF_SEPARATOR);pSysMenu-AppendMenu(MF_STRING,IDM_ABOUTBOX,strAboutMenu);SetIcon(m_hIcon,TRUE);/SetbigiconSetIcon(m_hIcon,FALSE);/Setsma

10、llicon/彩色進(jìn)度條設(shè)置m_progressThink.SetStartColor(RGB(0 xFF,0 xFF,0 x00);/黃色m_progressThink.SetEndColor(RGB(0 x00,0 x93,0 x00);/綠色m_progressThink.SetBkColor(RGB(0 xE6,0 xE6,0 xFA);/淡紫色m_progressThink.SetTextColor(RGB(0,0,255);m_progressThink.ShowPercent(1);m_tooltip.Create(this);m_tooltip.Activate(1);m_Ch

11、essman.Create(IDB_CHESSMAN,36,14,RGB(0,255,0);/創(chuàng)辦含有棋子圖形的ImgList,用于繪制棋子/下面這段代碼取棋盤(pán)圖形的寬,高BITMAPBitMap;m_BoardBmp.LoadBitmap(IDB_CHESSBOARD);m_BoardBmp.GetBitmap(&BitMap);/取BitMap對(duì)象m_nBoardWidth=BitMap.bmWidth;/棋盤(pán)寬度m_nBoardHeight=BitMap.bmHeight;/棋盤(pán)高度m_BoardBmp.DeleteObject();memcpy(m_byChessBoard,InitC

12、hessBoard,90);/初始化棋盤(pán)memcpy(m_byShowChessBoard,InitChessBoard,90);memcpy(m_byBackupChessBoard,InitChessBoard,90);m_pSE-SetSearchDepth(3);/設(shè)定找尋層數(shù)為3m_pSE-SetMoveGenerator(m_pMG);/給找尋引擎設(shè)定走法產(chǎn)生器m_pSE-SetEveluator(m_pEvel);/給找尋引擎設(shè)定估值核心m_pSE-SetUserChessColor(m_nUserChessColor);/設(shè)定用戶為黑方或紅方.優(yōu)選文檔m_pSE-SetThin

13、kProgress(&m_progressThink);/設(shè)定進(jìn)度條m_MoveChess.nChessID=NOCHESS;/將搬動(dòng)的棋子清空returnTRUE;/returnTRUEunlessyousetthefocustoacontrol5.2場(chǎng)面設(shè)計(jì)游戲設(shè)計(jì)中,我們的象棋棋盤(pán)采用的是直接加載位圖生成棋盤(pán),圖片的大小是寬度377*高度417,棋盤(pán)上每個(gè)格子的大?。?9*39,圖片格式為:BMP。棋子部分是經(jīng)過(guò)加載位圖實(shí)現(xiàn)的,圖片的大小是:寬度32*高度32,圖片的格式也是BMP。我們用一個(gè)10*9的數(shù)組來(lái)儲(chǔ)藏棋盤(pán)上的信息,數(shù)組的每個(gè)元素儲(chǔ)藏棋盤(pán)上可否有棋子。棋盤(pán)的初始狀況以下所示(圖

14、1是整個(gè)棋盤(pán)與棋子的場(chǎng)面圖):constBYTEInitChessBoard109=B_CAR,B_HORSE,B_ELEPHANT,B_BISHOP,B_KING,B_BISHOP,B_ELEPHANT,B_HORSE,B_CAR,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,B_CANON,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,B_CANON,NOCHESS,B_PAWN,NOCHESS,B_PAWN,NOCHESS,B_PAWN,NO

15、CHESS,B_PAWN,NOCHESS,B_PAWN,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,/楚河/漢界NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,R_PAWN,NOCHESS,R_PAWN,NOCHESS,R_PAWN,NOCHESS,R_PAWN,NOCHESS,R_PAWN,NOCHESS,R_CANON,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS

16、,R_CANON,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,R_CAR,R_HORSE,R_ELEPHANT,R_BISHOP,R_KING,R_BISHOP,R_ELEPHANT,R_HORSE,R_CAR;.優(yōu)選文檔圖1場(chǎng)面設(shè)計(jì)圖棋子的定義:#defineNOCHESS0/沒(méi)有棋子#defineB_KING1/黑帥#defineB_CAR2/黑車#defineB_HORSE3/黑馬#defineB_CANON4/黑炮#defineB_BISHOP5/黑士#defineB_E

17、LEPHANT6/黑象#defineB_PAWN7/黑卒#defineB_BEGINB_KING#defineB_ENDB_PAWN#defineR_KING8/紅將#defineR_CAR9/紅車#defineR_HORSE10/紅馬#defineR_CANON11/紅炮#defineR_BISHOP12/紅士#defineR_ELEPHANT13/紅相#defineR_PAWN14/紅兵#defineR_BEGINR_KING#defineR_ENDR_PAWN#defineIsBlack(x)(x=B_BEGIN&x=R_BEGIN&x=R_END)/判斷某個(gè)棋子可否是紅色。/判斷兩個(gè)棋

18、子可否是同色#defineIsSameSide(x,y)(IsBlack(x)&IsBlack(y)|(IsRed(x)&IsRed(y)/棋子地址typedefstructBYTEx;BYTEy;CHESSMANPOS;5.3繪圖部分關(guān)于繪圖部分,主要實(shí)現(xiàn)的是程序界面的繪圖所以我們?cè)谶@里將要達(dá)成棋盤(pán)、棋子的顯示走棋初步地址和目標(biāo)地址的提示框的顯示。而要實(shí)現(xiàn)這些我們必定經(jīng)過(guò)voidCChessDlg:OnPaint()這個(gè)函數(shù)實(shí)現(xiàn)voidCChessDlg:OnPaint()CPaintDCdc(this);CDCMemDC;inti,j;POINTpt;CBitmap*pOldBmp;Mem

19、DC.CreateCompatibleDC(&dc);m_BoardBmp.LoadBitmap(IDB_CHESSBOARD);pOldBmp=MemDC.SelectObject(&m_BoardBmp);/繪制棋盤(pán)上的棋子for(i=0;i10;i+)for(j=0;j9;j+)if(m_byShowChessBoardij=NOCHESS)continue;pt.x=j*GRILLEHEIGHT+14;pt.y=i*GRILLEWIDTH+15;m_Chessman.Draw(&MemDC,m_byShowChessBoardij-1,pt,ILD_TRANSPARENT);/繪制用戶

20、正在拖動(dòng)的棋子.優(yōu)選文檔if(m_MoveChess.nChessID!=NOCHESS)m_Chessman.Draw(&MemDC,m_MoveChess.nChessID-1,m_MoveChess.ptMovePoint,ILD_TRANSPARENT);dc.BitBlt(0,0,m_nBoardWidth,m_nBoardHeight,&MemDC,0,0,SRCCOPY);/將制的內(nèi)容刷新到屏幕MemDC.SelectObject(&pOldBmp);/恢復(fù)內(nèi)存Dc的原位MemDC.DeleteDC();/放內(nèi)存m_BoardBmp.DeleteObject();/除棋位象5.4

21、鼠響部分鼠響部分包括LButtonDown和LButtonUp兩個(gè)功能,LButtonDown的主要功能是拖棋子在棋上的移,他的重要性是,若是沒(méi)有個(gè)功能,將無(wú)法走棋,其函數(shù)通:voidCChessDlg:OnLButtonDown(UINTnFlags,CPointpoint)LButtonUp個(gè)函數(shù)主要的功能是:拖棋子完后放置到拖后的地址,行家放置的程中,需要使用一個(gè)Drop的放函數(shù)。函數(shù)通:voidCChessDlg:OnLButtonUp(UINTnFlags,CPointpoint)5.5棋子走法typedefstructshortnChessID;/表示是什么棋子CHESSMANPO

22、SFrom;/初步地址CHESSMANPOSTo;/走到什么地址intScore;/走法的分?jǐn)?shù)CHESSMOVE;在著法生成器中,采用的基本思想就是遍整個(gè)棋(一個(gè)接一個(gè)地看棋上的每個(gè)地址點(diǎn)),當(dāng)有當(dāng)前下棋方的棋子先判斷它是何種型的棋子,爾后依照其棋子型而相地找出其全部合法著法并存入著法列。里到的“合法著法”包括以下幾點(diǎn):1、各棋子按其行子行子。如跳“日”字、象走“田”字、士在九.優(yōu)選文檔宮內(nèi)斜行等等(這里需要特別注意的是卒(兵)的行子規(guī)則會(huì)隨其所在地址的不同樣而發(fā)生變化過(guò)河后能夠左右平移)。2、行子不能夠越出棋盤(pán)的界限。自然全部棋子都不能夠走到棋盤(pán)的外面,同時(shí)某些特定的棋子還有自己的行棋界限,

23、如將、士不能夠出九宮,象不能夠過(guò)河。3、行子的半路上不能夠有其他子阻截(除了炮需要隔一個(gè)子才能打子之外)以及行子的目的點(diǎn)不能夠有本方的棋子。4、將帥不能夠見(jiàn)面(本程序中只在生成計(jì)算機(jī)的著法時(shí)認(rèn)為將帥見(jiàn)面是非法的,而對(duì)用戶所走的以致將帥見(jiàn)面的著法其實(shí)不認(rèn)為其非法,而可是產(chǎn)生敗局罷了)。產(chǎn)生了著法后要將其存入著法隊(duì)列以供找尋之用,由于找尋會(huì)找尋多層,所以在把著法存入著法隊(duì)列的時(shí)候還要同時(shí)儲(chǔ)藏該著法所屬的找尋層數(shù)。所以能夠?qū)⒅?duì)列定義為二維數(shù)組,其中第一個(gè)數(shù)組下標(biāo)為層數(shù),第二個(gè)數(shù)組下標(biāo)為每一層的全部著法數(shù)。著法生成中的各個(gè)棋子走法以及其他規(guī)則代碼見(jiàn)MoveGenerator.cpp。棋子的搬動(dòng)由以

24、下的函數(shù)分別執(zhí)行:帥(將):VoidCMoveGenerator:Gen_KingMove()士:紅士voidCMoveGenerator:Gen_RBishopMove()黑士voidCMoveGenerator:Gen_BBishopMove()象:voidCMoveGenerator:Gen_ElephantMove()馬:voidCMoveGenerator:Gen_HorseMove()車:voidCMoveGenerator:Gen_CarMove()炮:voidCMoveGenerator:Gen_CanonMove()兵(卒):.優(yōu)選文檔紅兵voidCMoveGenerator

25、:Gen_RPawnMove()黑卒voidCMoveGenerator:Gen_BPawnMove()5.6找尋算法我們用一棵象棋樹(shù)來(lái)表示下棋的過(guò)程:樹(shù)中每一個(gè)結(jié)點(diǎn)代表棋盤(pán)上的一個(gè)場(chǎng)面,對(duì)每一個(gè)場(chǎng)面依照不同樣的走法又產(chǎn)生不同樣的場(chǎng)面。該象棋樹(shù)包括三各種類的結(jié)點(diǎn):奇數(shù)層的中間結(jié)點(diǎn)以及根結(jié)點(diǎn),表示輪到紅方走棋;偶數(shù)層的中間結(jié)點(diǎn),表示輪到黑方走棋;葉子結(jié)點(diǎn),表示棋局結(jié)束。結(jié)合上面所講的樹(shù),若給每個(gè)結(jié)點(diǎn)都打一個(gè)分值來(lái)議論其對(duì)應(yīng)的場(chǎng)面,我們經(jīng)過(guò)估值引擎SetEveluator()來(lái)實(shí)現(xiàn),過(guò)比較該分值的大小來(lái)判斷場(chǎng)面的利害。voidSetEveluator(CEveluation*pEval)m_pEv

26、al=pEval;假設(shè)甲乙兩方下棋,甲勝的場(chǎng)面是一個(gè)極大值(一個(gè)很大的正數(shù)),那么乙勝的場(chǎng)面就是一個(gè)極小值(極大值的負(fù)值),和棋的場(chǎng)面則是零值(或是湊近零的值)。這樣,當(dāng)輪到甲走棋時(shí)他會(huì)盡可能地讓場(chǎng)面上的分值大,相反輪到乙走棋時(shí)他會(huì)選盡可能地讓場(chǎng)面上的分值小。反響到博弈樹(shù)上,即若是假設(shè)奇數(shù)層表示輪到甲方走棋,偶數(shù)層表示輪到乙方走棋。那么由于甲方希望棋盤(pán)上的分值盡可能大,則在偶數(shù)層上會(huì)優(yōu)選分值最大的結(jié)點(diǎn)偶數(shù)層的結(jié)點(diǎn)是甲走完一步棋此后的棋盤(pán)場(chǎng)面,反響了甲方對(duì)棋局形勢(shì)的要求。同樣道理,由于乙方希望棋盤(pán)上的分值盡可能小,那么在奇數(shù)層上會(huì)選擇分值最小的結(jié)點(diǎn)。這是“最小-最大”(Minimax)的基本思想

27、。這樣找尋函數(shù)在估值函數(shù)的協(xié)助下能夠經(jīng)過(guò)在奇數(shù)層選擇分值最大(最小)的結(jié)點(diǎn),在偶數(shù)層選擇分值最小(最大)的結(jié)點(diǎn)的方式來(lái)找尋以當(dāng)前場(chǎng)面為根結(jié)點(diǎn)、限制找尋層數(shù)以內(nèi)的整棵樹(shù)來(lái)獲得一個(gè)最正確的著法。下面是“最大-最小”的主要代碼intCNegaMaxEngine:NegaMax(intnDepth).優(yōu)選文檔intcurrent=-20000;intscore;intCount,i;BYTEtype;i=IsGameOver(CurPosition,nDepth);/檢查棋局可否結(jié)束if(i!=0)returni;/棋局結(jié)束,返回極大/極小值if(nDepthEveluate(CurPosition,

28、(m_nMaxDepth-nDepth)%2,m_nUserChessColor);/列舉當(dāng)前棋局下一步全部可能的走法Count=m_pMG-CreatePossibleMove(CurPosition,nDepth,(m_nMaxDepth-nDepth)%2,m_nUserChessColor);if(nDepth=m_nMaxDepth)/在根節(jié)點(diǎn)設(shè)定進(jìn)度條m_pThinkProgress-SetRange(0,Count);m_pThinkProgress-SetStep(1);for(i=0;iStepIt();/走進(jìn)度條type=MakeMove(&m_pMG-m_MoveList

29、nDepthi);/依照走法產(chǎn)生新場(chǎng)面score=-NegaMax(nDepth-1);/遞歸調(diào)用負(fù)極大值找尋下一層節(jié)點(diǎn)UnMakeMove(&m_pMG-m_MoveListnDepthi,type);/恢復(fù)當(dāng)前場(chǎng)面if(scorecurrent)/若是score大于已知的最大值current=score;/更正當(dāng)前最大值為scoreif(nDepth=m_nMaxDepth)m_cmBestMove=m_pMG-m_MoveListnDepthi;/湊近根部時(shí)保留最正確走法.優(yōu)選文檔returncurrent;/返回極大值“最小-最大”思想再加上“樹(shù)的裁剪”就是Alpha-Beta找尋算法

30、的核心。最基本的Alpha-Beta算法的代碼以下:intCAlphaBetaEngine:AlphaBeta(intnDepth,intalpha,intbeta)intscore;intCount,i;BYTEtype;i=IsGameOver(CurPosition,nDepth);/檢查可否游戲結(jié)束if(i!=0)returni;/結(jié)束,返回估值/葉子節(jié)點(diǎn)取估值if(nDepthEveluate(CurPosition,(m_nMaxDepth-nDepth)%2,m_nUserChessColor);此函數(shù)找出當(dāng)前場(chǎng)面全部可能的走法,爾后放進(jìn)m_pMG-m_MoveList中間Cou

31、nt=m_pMG-CreatePossibleMove(CurPosition,nDepth,(m_nMaxDepth-nDepth)%2,m_nUserChessColor);if(nDepth=m_nMaxDepth)/在根節(jié)點(diǎn)設(shè)定進(jìn)度條m_pThinkProgress-SetRange(0,Count);m_pThinkProgress-SetStep(1);/對(duì)全部可能的走法for(i=0;iStepIt();/走進(jìn)度條type=MakeMove(&m_pMG-m_MoveListnDepthi);/將當(dāng)前場(chǎng)面應(yīng)用此走法,變?yōu)樽庸?jié)點(diǎn)的場(chǎng)面score=-AlphaBeta(nDepth-

32、1,-beta,-alpha);/遞歸找尋子節(jié)點(diǎn)UnMakeMove(&m_pMG-m_MoveListnDepthi,type);/將此節(jié)點(diǎn).優(yōu)選文檔的場(chǎng)面恢復(fù)為當(dāng)前節(jié)點(diǎn)if(scorealpha)alpha=score;/保留極大值/湊近根節(jié)點(diǎn)時(shí)保留最正確走法if(nDepth=m_nMaxDepth)m_cmBestMove=m_pMG-m_MoveListnDepthi;if(alpha=beta)break;/剪枝,放棄找尋剩下的節(jié)點(diǎn)returnalpha;/返回極大值A(chǔ)lpha-Beta找尋算法是在“最小-最大”的基礎(chǔ)上引入“樹(shù)的裁剪”的思想以期提高效率,它的效率將在很大程度上取決

33、于樹(shù)的結(jié)構(gòu)若是找尋了沒(méi)多久就發(fā)現(xiàn)能夠進(jìn)行“裁剪”了,那么需要解析的工作量將大大減少,效率自然也就大大提高;而若是直至解析了全部的可能性此后才能做出“裁剪”操作,那此時(shí)“裁剪”也已經(jīng)失去了它原有的價(jià)值(由于你已經(jīng)解析了全部狀況,這時(shí)的Alpha-Beta找尋已和“最小-最大”找尋別無(wú)二致了)。所以,要想保證Alpha-Beta找尋算法的效率就需要調(diào)整樹(shù)的結(jié)構(gòu),即調(diào)整待找尋的結(jié)點(diǎn)的序次,使得“裁剪”能夠盡可能早地發(fā)生。能夠依照部分已經(jīng)找尋過(guò)的結(jié)果來(lái)調(diào)整將要找尋的結(jié)點(diǎn)的序次。由于,平時(shí)當(dāng)一個(gè)場(chǎng)面經(jīng)過(guò)找尋被認(rèn)為較好時(shí),其子結(jié)點(diǎn)中經(jīng)常有一些與它相似的場(chǎng)面(如個(gè)別沒(méi)關(guān)緊迫的棋子地址有所不同樣)也是較好的。

34、由J.Schaeffer所提出的“歷史啟示”(HistoryHeuristic)就是建立在這樣一種見(jiàn)解之上的。在找尋的過(guò)程中,每當(dāng)發(fā)現(xiàn)一個(gè)好的走法,就給該走法累加一個(gè)增量以記錄其“歷史得分”,一個(gè)多次被找尋并認(rèn)為是好的走法的“歷史得分”就會(huì)較高。關(guān)于立刻找尋的結(jié)點(diǎn),依照“歷史得分”的高低對(duì)它們進(jìn)行排序,保證較好的走法(“歷史得分”高的走法)排在前面,這樣Alpha-Beta找尋就可以盡可能早地進(jìn)行“裁剪”,從而保證了找尋的效率。關(guān)于著法的排序能夠使用各種排序算法,在程序中采用了歸并排序。歸并排序的空間復(fù)雜度為O(n),時(shí)間復(fù)雜度為O(nlog2n),擁有較高的效率。歷史啟示部分的主要代碼以下:

35、voidCHistoryHeuristic:ResetHistoryTable()memset(m_HistoryTable,10,8100*4);intCHistoryHeuristic:GetHistoryScore(CHESSMOVE*move).優(yōu)選文檔intnFrom,nTo;nFrom=move-From.y*9+move-From.x;/原始地址nTo=move-To.y*9+move-To.x;/目標(biāo)地址returnm_HistoryTablenFromnTo;/返回歷史得分5.7多線程由于程序出現(xiàn)了異常:有時(shí)對(duì)用戶方的功能完好正確,而對(duì)電腦方的有些功能卻不起作用,這是由于程序

36、在進(jìn)行找尋時(shí)會(huì)占用大量的CPU時(shí)間,所以擁塞了位于同一線程內(nèi)的其他指令,使之無(wú)法正常工作,所以我們引入了多線程的思想別的開(kāi)一個(gè)線程,讓各程序分開(kāi)于多個(gè)線程。函數(shù)原型:CWinThread*AfxBeginThread(AFX_THREADPROCThinkProc,LPVOIDpParam,intnPriority=THREAD_PRIORITY_NORMAL,UINTnStackSize=0,DWORDdwCreateFlags=0,LPSECURITY_ATTRIBUTESlpSecurityAttrs=NULL);該函數(shù)啟動(dòng)一個(gè)新的線程并返回一個(gè)指向該新線程對(duì)象的指針,爾后新的線程與啟動(dòng)

37、該新線程的線程同時(shí)運(yùn)行。該函數(shù)的第一個(gè)參數(shù)AFX_THREADPROCThinkProc指定了線程函數(shù)。線程函數(shù)的內(nèi)容即為新線程所要執(zhí)行的內(nèi)容,線程函數(shù)執(zhí)行達(dá)成,新線程結(jié)束(自動(dòng)銷毀)。線程函數(shù)必定被定義為全局函數(shù),其返回值種類必定是UINT,必定有一個(gè)LPVOID種類的參數(shù)。能夠把調(diào)用引擎部分的找尋函數(shù)的代碼以及達(dá)成走棋動(dòng)作的代碼放入所定義的思慮線程內(nèi),以下:DWORDWINAPIThinkProc(LPVOIDpParam)CChessDlg*pDlg=(CChessDlg*)pParam;pDlg-Think();return0;爾后,只要將本來(lái)調(diào)找尋函數(shù)并達(dá)成走棋的代碼代之以調(diào)用Afx

38、BeginThread來(lái)啟動(dòng)新線程即可,實(shí)現(xiàn)了程序的多線程,不能夠正常工作的問(wèn)題也就隨之解決了。5.8判斷勝敗紅方的帥被吃,也許黑方的將被吃,游戲結(jié)束,判斷被吃的一方輸。詳盡代碼以下:intCChessDlg:IsGameOver(BYTEposition9)inti,j;.優(yōu)選文檔BOOLRedLive=FALSE,BlackLive=FALSE;/檢查紅方九宮可否有帥for(i=7;i10;i+)for(j=3;j6;j+)if(positionij=B_KING)BlackLive=TRUE;if(positionij=R_KING)RedLive=TRUE;/檢查黑方九宮可否有將for(i=0;i3;i+)for(j=3;j6;j+)if(positionij=B_KING)BlackLive=TRUE;if(positionij=R_KING)RedLive=TRUE;if(m_nUserChessColor=REDCHESS)if(!RedLive)return1;if(!Black

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝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ù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 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ì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論