中國象棋游戲開發(fā)設計報告_第1頁
中國象棋游戲開發(fā)設計報告_第2頁
中國象棋游戲開發(fā)設計報告_第3頁
中國象棋游戲開發(fā)設計報告_第4頁
中國象棋游戲開發(fā)設計報告_第5頁
已閱讀5頁,還剩13頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、 中國象棋游戲開發(fā)設計報告班級: 小組編號: 小組成員: 指導老師: 17 / 18文檔可自由編輯打印一、開發(fā)的目的和意義面向對象程序設計作為一門軟件設計的課程,具有極強的實踐性,要求學生具備靈活應用理論知識的能力及面向對象程序設計技能的基礎。通過游戲開發(fā),學生能了解C+面向對象的設計方法與技巧,有效地、深刻地理解課程內容,體會理論、方法和設計原則,培養(yǎng)分析實際問題和解決問題的能力,具備使用面向對象程序設計開發(fā)工具設計實際系統(tǒng)的能力。還能夠了解并通過使用MFC,掌握一種可視化編程的方法,并通過游戲的開發(fā)加深對可視化編程的理解。同時,可以提高運用C+編程語言解決實際問題的能力。棋牌游戲屬于休閑類

2、游戲,具有上手快、游戲時間短的特點,更利于用戶進行放松休閑,為人們所喜愛,特別是棋類游戲,方便、快捷、操作簡單,在休閑娛樂中占主要位置。中國象棋作為中國自古以來的經典棋牌游戲之一,一直都是人之間的較量,將中國象棋制作成游戲,可以實現(xiàn)人與計算機之間的對弈。而且人工智能是綜合性很強的一門邊緣學科,它的中心任務是研究如何使計算機去做那些過去只能靠人的智力才能做的工作。開發(fā)出了計算機象棋游戲,以后不僅僅可以進行休閑游戲,還能鍛煉自己的智力和象棋技術,更加方便了人們的日常生活。二、功能描述和分析(用戶需求分析)2.1開發(fā)背景 我們周圍有許多同學喜歡下象棋,尤其是男同學,希望能有人可以和自己下象棋,但這種

3、意愿常因為受到條件的限制而難以如愿,比如說需要身邊剛好有現(xiàn)成的棋盤棋子,比如說需要是同樣懂得中國象棋的對手,但是大家都知道我們這所大學男性同學占少數,即便是條件都滿足了,還要考慮這位對手是否有何自己下棋的心情。 這時,如果有一臺計算機,一個能夠支持人機對弈的程序,上面的問題迎刃而解。而我們小組的這個想起游戲設計,正是希望能夠做出一款擁有良好性能,良好的智能,能夠滿足大多數愛好象棋的同學的需求中國象棋人機對弈程序。2.2用戶需求分析 一款能夠與用戶對弈,滿足用戶需求的中國象棋程序,需要有棋盤棋子的局面、鼠標響應控制棋子移動、棋子的走法規(guī)則、人機對弈的搜索算法、避免異常引入的多線程、勝負判斷,具體

4、分析如下:2.2.1棋盤棋子的局面 作為中國象棋的這項游戲,其必不可少的是就是棋子和棋盤,沒有這兩個部分,想起功能無法實現(xiàn),不僅僅如此,如果,僅僅有棋子和棋盤,而沒有將兩者結合起來,那么,也將無法實現(xiàn)中國象棋的游戲功能,所以,棋子和棋盤的設計在這個游戲設計中至關重要。2.2.2鼠標響應在對弈中,棋子是必須可以移動的,不然游戲無法進行。因此,鼠標左鍵點擊是必不可少的一部分。2.2.3棋子的功能分析:中國象棋中各色的象棋棋子的功能使象棋具有了真正的趣味性,中國象棋的棋子的類型大致分為:帥(將)、士、象、馬、車、炮、兵(卒)等幾個類型。帥(將):紅方中的帥和黑方中的將的功能相同,都是只能在九宮格中進

5、行橫向和豎向的移動,每次移動一格,并且不能移動超出九宮格,帥和將不能見面。士:士在整片棋盤中,和帥的移動范圍類似,也是只能在九宮格中移動,不過士的移動方向是對角線,并且每次只能在一個格子中移動。象:象的走法遵循“象走田”的原則,不能絆象腿。馬:馬的走法遵循“馬走日”的原則,不能絆馬腿。車:在整塊棋盤中,車可以橫向或縱向3移動任意格。炮:每次移動和車的類似,但是在吃對方棋子的時候必須中間有且只能有一個棋子的間隔。兵(卒):紅方的兵和黑方的卒的功能相同,特點是只能向對方前進,而不能后退,過河之前不能橫向移動,過河之后可以橫向移動,不管是前進還是橫向移動,每次都只能移動一格。2.2.4良好的人機對弈

6、要實現(xiàn)人機的對弈,搜索算法是很重要的一部分。關于棋類對弈程序中的搜索算法,已有成熟的Alpha-Beta搜索算法。我們在程序中直接借鑒了Alpha-Beta搜索算法并輔以歷史啟發(fā)。Alpha-Beta搜索算法:在中國象棋里,雙方棋手獲得相同的棋盤信息。他們輪流走棋,目的就是吃掉對方的將或帥,或者避免自己的將或帥被吃。搜索算法的搜索過程很漫長,因此對搜索算法進行簡化是有必要的。2.2.5多線程的必要性由于程序在進行搜索時會占用大量的CPU時間,因而阻塞了位于同一線程內的其他指令,使之無法正常工作,因而引入了多線程的思想另外開一個線程,讓各程序分開于多個線程。就可以解決程序異常的問題了,因此,多線

7、程思想的引入是有必要的。2.2.6判斷勝負游戲需要判斷最后由誰勝出三、采用的開發(fā)工具和技術,開發(fā)環(huán)境,適用環(huán)境開發(fā)工具:Visual C+ MFC工程;開發(fā)環(huán)境:win7;適用環(huán)境:windows系統(tǒng);四、小組成員分工初始化、局面設計部分(賀景);判斷勝負、棋子走法部分(鄒京甫);鼠標響應、繪圖部分(吳鑫);搜索引擎部分等由組員共同完成。五、具體開發(fā)方法和過程5.1初始化部分OnInitDialog()負責的是對話框的初始化。可以把有關中國象棋的棋局初始化情況也放在了這里面。初始化的內容包括:對引擎部分所用到的變量的初始化。包括對棋盤上的棋子位置進行初始化(棋盤數組的初始化),對搜索深度、當前

8、走棋方標志、棋局是否結束標志等的初始化;對棋盤、棋子的貼圖位置(即棋盤、棋子在程序中實際顯示位置)的初始化;對程序輔助部分所用到的一些變量的初始化。棋盤、棋子樣式的默認形式,以及著法名稱列表的初始化等。1.對棋盤的初始化memcpy(m_byChessBoard,InitChessBoard,90);2.對棋盤、棋子的貼圖位置(即棋盤、棋子在程序中實際顯示位置)的初始化;MemDC.SelectObject(&pOldBmp);/恢復內存Dc的原位圖3.對程序輔助部分所用到的一些變量的初始化棋盤、棋子樣式的默認形式,下棋模式的默認選擇,以及著法名稱列表的初始化等。初始化部分的代碼如下:

9、BOOL CChessDlg:OnInitDialog()CDialog:OnInitDialog();/ Add "About." menu item to system menu./ IDM_ABOUTBOX must be in the system command range.ASSERT(IDM_ABOUTBOX & 0xFFF0) = IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX < 0xF000);CMenu* pSysMenu = GetSystemMenu(FALSE);if (pSysMenu != NULL)CStr

10、ing strAboutMenu;strAboutMenu.LoadString(IDS_ABOUTBOX);if (!strAboutMenu.IsEmpty()pSysMenu->AppendMenu(MF_SEPARATOR);pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);SetIcon(m_hIcon, TRUE);/ Set big iconSetIcon(m_hIcon, FALSE);/ Set small icon/彩色進度條設置m_progressThink.SetStartColor(RG

11、B(0xFF,0xFF,0x00);/黃色m_progressThink.SetEndColor(RGB(0x00,0x93,0x00); /綠色m_progressThink.SetBkColor(RGB(0xE6,0xE6,0xFA); /淡紫色m_progressThink.SetTextColor(RGB(0,0,255);m_progressThink.ShowPercent(1);m_tooltip.Create(this);m_tooltip.Activate(1);m_Chessman.Create(IDB_CHESSMAN,36,14,RGB(0,255,0);/創(chuàng)建含有棋子

12、圖形的ImgList,用于繪制棋子/下面這段代碼取棋盤圖形的寬,高BITMAP BitMap;m_BoardBmp.LoadBitmap(IDB_CHESSBOARD);m_BoardBmp.GetBitmap(&BitMap); /取BitMap 對象m_nBoardWidth=BitMap.bmWidth; /棋盤寬度m_nBoardHeight=BitMap.bmHeight;/棋盤高度m_BoardBmp.DeleteObject();memcpy(m_byChessBoard,InitChessBoard,90);/初始化棋盤memcpy(m_byShowChessBoard

13、,InitChessBoard,90);memcpy(m_byBackupChessBoard,InitChessBoard,90);m_pSE->SetSearchDepth(3); /設定搜索層數為3m_pSE->SetMoveGenerator(m_pMG);/給搜索引擎設定走法產生器m_pSE->SetEveluator(m_pEvel); /給搜索引擎設定估值核心m_pSE->SetUserChessColor(m_nUserChessColor); /設定用戶為黑方或紅方m_pSE->SetThinkProgress(&m_progressTh

14、ink); /設定進度條m_MoveChess.nChessID=NOCHESS;/將移動的棋子清空return TRUE; / return TRUE unless you set the focus to a control5.2局面設計游戲設計中,我們的象棋棋盤采用的是直接加載位圖生成棋盤,圖片的大小是寬度377*高度417,棋盤上每個格子的大?。?9*39,圖片格式為:BMP。棋子部分是通過加載位圖實現(xiàn)的,圖片的大小是:寬度32*高度32,圖片的格式也是BMP。我們用一個10*9的數組來存儲棋盤上的信息,數組的每個元素存儲棋盤上是否有棋子。棋盤的初始情形如下所示(圖1是整個棋盤與棋子的

15、局面圖):const BYTE InitChessBoard109=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,NOCHESS,B_

16、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,R_CANO

17、N,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;圖1 局面設計圖棋子的定義:#define NOCHESS 0 /沒有棋子#define B_KING 1 /黑帥#define B_CAR 2 /黑車#define B_HORSE 3 /黑馬#define B_CANON 4 /黑炮#define B_BISHOP 5 /黑士#de

18、fine B_ELEPHANT 6 /黑象#define B_PAWN 7 /黑卒#define B_BEGIN B_KING#define B_END B_PAWN#define R_KING 8 /紅將#define R_CAR 9 /紅車#define R_HORSE 10/紅馬#define R_CANON 11/紅炮#define R_BISHOP 12/紅士#define R_ELEPHANT 13/紅相#define R_PAWN 14/紅兵#define R_BEGIN R_KING#define R_END R_PAWN#define IsBlack(x) (x>=B_

19、BEGIN && x<=B_END)/判斷某個棋子是不是黑色。#define IsRed(x) (x>=R_BEGIN && x<=R_END)/判斷某個棋子是不是紅色。/判斷兩個棋子是不是同色#define IsSameSide(x,y) (IsBlack(x) && IsBlack(y) | (IsRed(x) && IsRed(y)/棋子位置typedef structBYTE x;BYTE y;CHESSMANPOS;5.3繪圖部分對于繪圖部分,主要實現(xiàn)的是程序界面的繪圖因此我們在這里將要完成棋盤、棋子的

20、顯示走棋起始位置和目標位置的提示框的顯示。而要實現(xiàn)這些我們必須通過void CChessDlg:OnPaint() 這個函數實現(xiàn)void CChessDlg:OnPaint() CPaintDC dc(this);CDC MemDC;int i,j;POINT pt;CBitmap* pOldBmp;MemDC.CreateCompatibleDC(&dc);m_BoardBmp.LoadBitmap(IDB_CHESSBOARD);pOldBmp=MemDC.SelectObject(&m_BoardBmp);/繪制棋盤上的棋子for(i=0;i<10;i+)for(j

21、=0;j<9;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);/繪制用戶正在拖動的棋子if(m_MoveChess.nChessID!=NOCHESS)m_Chessman.Draw(&MemDC,m_MoveChess.nChessID-1,m_MoveChess.ptMovePoint,ILD_TRANSPAR

22、ENT);dc.BitBlt(0,0,m_nBoardWidth,m_nBoardHeight,&MemDC,0,0,SRCCOPY); /將繪制的內容刷新到屏幕MemDC.SelectObject(&pOldBmp);/恢復內存Dc的原位圖MemDC.DeleteDC(); /釋放內存 m_BoardBmp.DeleteObject(); /刪除棋盤位圖對象5.4鼠標響應部分鼠標響應部分包括LButtonDown和LButtonUp兩個功能,LButtonDown實現(xiàn)的主要功能是拖動棋子在棋盤上的移動,他的重要性是,如果沒有這個功能,將無法走棋,其函數實現(xiàn)通過:void CC

23、hessDlg:OnLButtonDown(UINT nFlags, CPoint point) LButtonUp這個函數主要實現(xiàn)的功能是:拖動棋子完畢后放置到拖動后的位置,在進行放置的過程中,需要使用一個Drop的釋放函數。函數實現(xiàn)通過:void CChessDlg:OnLButtonUp(UINT nFlags, CPoint point) 5.5棋子走法typedef structshort nChessID; /表明是什么棋子CHESSMANPOS From;/起始位置CHESSMANPOS To; /走到什么位置int Score; /走法的分數CHESSMOVE;在著法生成器中,

24、采用的基本思想就是遍歷整個棋盤(一個接一個地查看棋盤上的每個位置點),當發(fā)現(xiàn)有當前下棋方的棋子時先判斷它是何種類型的棋子,然后根據其棋子類型而相應地找出其所有合法著法并存入著法隊列。這里談到的“合法著法”包括以下幾點:1、各棋子按其行子規(guī)則行子。諸如馬跳“日”字、象走“田”字、士在九宮內斜行等等(這里需要特別注意的是卒(兵)的行子規(guī)則會隨其所在位置的不同而發(fā)生變化過河后可以左右平移)。2、行子不能越出棋盤的界限。當然所有棋子都不能走到棋盤的外面,同時某些特定的棋子還有自己的行棋界限,如將、士不能出九宮,象不能過河。3、行子的半路上不能有其它子阻攔(除了炮需要隔一個子才能打子之外)以及行子的目的

25、點不能有本方的棋子。4、將帥不能碰面(本程序中只在生成計算機的著法時認為將帥碰面是非法的,而對用戶所走的導致將帥碰面的著法并不認為其非法,而只是產生敗局罷了)。產生了著法后要將其存入著法隊列以供搜索之用,由于搜索會搜索多層,所以在把著法存入著法隊列的時候還要同時存儲該著法所屬的搜索層數。因此可以將著法隊列定義為二維數組,其中第一個數組下標為層數,第二個數組下標為每一層的全部著法數。著法生成中的各個棋子走法以及其他規(guī)則代碼見MoveGenerator.cpp。棋子的移動由以下的函數分別執(zhí)行:帥(將):Void CMoveGenerator:Gen_KingMove()士:紅士void CMove

26、Generator:Gen_RBishopMove()黑士void CMoveGenerator:Gen_BBishopMove()象:void CMoveGenerator:Gen_ElephantMove()馬:void CMoveGenerator:Gen_HorseMove()車:void CMoveGenerator:Gen_CarMove()炮:void CMoveGenerator:Gen_CanonMove()兵(卒):紅兵void CMoveGenerator:Gen_RPawnMove() 黑卒 void CMoveGenerator:Gen_BPawnMove()5.6搜

27、索算法我們用一棵象棋樹來表示下棋的過程:樹中每一個結點代表棋盤上的一個局面,對每一個局面根據不同的走法又產生不同的局面。該象棋樹包含三種類型的結點:奇數層的中間結點以及根結點,表示輪到紅方走棋;偶數層的中間結點,表示輪到黑方走棋;葉子結點,表示棋局結束。結合上面所講的樹,若給每個結點都打一個分值來評價其對應的局面,我們通過估值引擎SetEveluator()來實現(xiàn),過比較該分值的大小來判斷局面的優(yōu)劣。void SetEveluator(CEveluation* pEval)m_pEval=pEval;假定甲乙兩方下棋,甲勝的局面是一個極大值(一個很大的正數),那么乙勝的局面就是一個極小值(極大

28、值的負值),和棋的局面則是零值(或是接近零的值)。如此,當輪到甲走棋時他會盡可能地讓局面上的分值大,相反輪到乙走棋時他會選盡可能地讓局面上的分值小。反映到博弈樹上,即如果假設奇數層表示輪到甲方走棋,偶數層表示輪到乙方走棋。那么由于甲方希望棋盤上的分值盡可能大,則在偶數層上會挑選分值最大的結點偶數層的結點是甲走完一步棋之后的棋盤局面,反映了甲方對棋局形勢的要求。同樣道理,由于乙方希望棋盤上的分值盡可能小,那么在奇數層上會選擇分值最小的結點。這是“最小-最大”(Minimax)的基本思想。這樣搜索函數在估值函數的協(xié)助下可以通過在奇數層選擇分值最大(最?。┑慕Y點,在偶數層選擇分值最?。ㄗ畲螅┑慕Y點的

29、方式來搜索以當前局面為根結點、限定搜索層數以內的整棵樹來獲得一個最佳的著法。下面是“最大-最小”的主要代碼int CNegaMaxEngine:NegaMax(int nDepth)int current=-20000;int score;int Count,i;BYTE type;i=IsGameOver(CurPosition,nDepth);/檢查棋局是否結束if(i!=0)return i;/棋局結束,返回極大/極小值if(nDepth<=0)/葉子節(jié)點取估值return m_pEval->Eveluate(CurPosition,(m_nMaxDepth-nDepth)%

30、2,m_nUserChessColor);/列舉當前棋局下一步所有可能的走法Count=m_pMG->CreatePossibleMove(CurPosition,nDepth,(m_nMaxDepth-nDepth)%2,m_nUserChessColor);if(nDepth=m_nMaxDepth)/在根節(jié)點設定進度條m_pThinkProgress->SetRange(0,Count);m_pThinkProgress->SetStep(1);for(i=0;i<Count;i+)if(nDepth=m_nMaxDepth)m_pThinkProgress-&g

31、t;StepIt();/走進度條type=MakeMove(&m_pMG->m_MoveListnDepthi); /根據走法產生新局面 score=-NegaMax(nDepth-1); /遞歸調用負極大值搜索下一層節(jié)點UnMakeMove(&m_pMG->m_MoveListnDepthi,type); /恢復當前局面if(score>current) /如果score大于已知的最大值current=score; /修改當前最大值為scoreif(nDepth=m_nMaxDepth)m_cmBestMove=m_pMG->m_MoveListnDe

32、pthi;/靠近根部時保存最佳走法return current;/返回極大值“最小-最大”思想再加上“樹的裁剪”就是Alpha-Beta搜索算法的核心。最基本的Alpha-Beta算法的代碼如下:int CAlphaBetaEngine:AlphaBeta(int nDepth,int alpha,int beta)int score;int Count,i;BYTE type;i=IsGameOver(CurPosition,nDepth);/檢查是否游戲結束if(i!=0)return i;/結束,返回估值/葉子節(jié)點取估值if(nDepth<=0)return m_pEval->

33、;Eveluate(CurPosition,(m_nMaxDepth-nDepth)%2,m_nUserChessColor);/此函數找出當前局面所有可能的走法,然后放進m_pMG ->m_MoveList當中Count=m_pMG->CreatePossibleMove(CurPosition,nDepth,(m_nMaxDepth-nDepth)%2,m_nUserChessColor);if(nDepth=m_nMaxDepth)/在根節(jié)點設定進度條m_pThinkProgress->SetRange(0,Count);m_pThinkProgress->Set

34、Step(1);/對所有可能的走法for(i=0;i<Count;i+)if(nDepth=m_nMaxDepth)m_pThinkProgress->StepIt();/走進度條type=MakeMove(&m_pMG->m_MoveListnDepthi); /將當前局面應用此走法,變?yōu)樽庸?jié)點的局面score=-AlphaBeta(nDepth-1,-beta,-alpha); /遞歸搜索子節(jié)點UnMakeMove(&m_pMG->m_MoveListnDepthi,type);/將此節(jié)點的局面恢復為當前節(jié)點if(score>alpha)alp

35、ha=score;/保留極大值/靠近根節(jié)點時保留最佳走法if(nDepth=m_nMaxDepth)m_cmBestMove=m_pMG->m_MoveListnDepthi;if(alpha>=beta)break;/剪枝,放棄搜索剩下的節(jié)點return alpha;/返回極大值Alpha-Beta搜索算法是在“最小-最大”的基礎上引入“樹的裁剪”的思想以期提高效率,它的效率將在很大程度上取決于樹的結構如果搜索了沒多久就發(fā)現(xiàn)可以進行“裁剪”了,那么需要分析的工作量將大大減少,效率自然也就大大提高;而如果直至分析了所有的可能性之后才能做出“裁剪”操作,那此時“裁剪”也已經失去了它原

36、有的價值(因為你已經分析了所有情況,這時的Alpha-Beta搜索已和“最小-最大”搜索別無二致了)。因而,要想保證Alpha-Beta搜索算法的效率就需要調整樹的結構,即調整待搜索的結點的順序,使得“裁剪”可以盡可能早地發(fā)生。可以根據部分已經搜索過的結果來調整將要搜索的結點的順序。因為,通常當一個局面經過搜索被認為較好時,其子結點中往往有一些與它相似的局面(如個別無關緊要的棋子位置有所不同)也是較好的。由J.Schaeffer所提出的“歷史啟發(fā)”(History Heuristic)就是建立在這樣一種觀點之上的。在搜索的過程中,每當發(fā)現(xiàn)一個好的走法,就給該走法累加一個增量以記錄其“歷史得分”

37、,一個多次被搜索并認為是好的走法的“歷史得分”就會較高。對于即將搜索的結點,按照“歷史得分”的高低對它們進行排序,保證較好的走法(“歷史得分”高的走法)排在前面,這樣Alpha-Beta搜索就可以盡可能早地進行“裁剪”,從而保證了搜索的效率。對于著法的排序可以使用各種排序算法,在程序中采用了歸并排序。歸并排序的空間復雜度為O(n),時間復雜度為O(nlog2n),具有較高的效率。歷史啟發(fā)部分的主要代碼如下:void CHistoryHeuristic:ResetHistoryTable()memset(m_HistoryTable,10,8100*4);int CHistoryHeuristi

38、c:GetHistoryScore(CHESSMOVE *move)int nFrom,nTo;nFrom=move->From.y*9+move->From.x;/原始位置nTo=move->To.y*9+move->To.x; /目標位置return m_HistoryTablenFromnTo;/返回歷史得分5.7多線程由于程序出現(xiàn)了異常:有時對用戶方的功能完全正確,而對電腦方的有些功能卻不起作用,這是由于程序在進行搜索時會占用大量的CPU時間,因而阻塞了位于同一線程內的其他指令,使之無法正常工作,因而我們引入了多線程的思想另外開一個線程,讓各程序分開于多個線程。

39、函數原型:CWinThread* AfxBeginThread(AFX_THREADPROC ThinkProc,LPVOID pParam,int nPriority = THREAD_PRIORITY_NORMAL,UINT nStackSize = 0,DWORD dwCreateFlags = 0,LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL );該函數啟動一個新的線程并返回一個指向該新線程對象的指針,然后新的線程與啟動該新線程的線程同時運行。該函數的第一個參數AFX_THREADPROC ThinkProc指定了線程函數。線程函數的內容即為

40、新線程所要執(zhí)行的內容,線程函數執(zhí)行完畢,新線程結束(自動銷毀)。線程函數必須被定義為全局函數,其返回值類型必須是UINT,必須有一個LPVOID類型的參數。可以把調用引擎部分的搜索函數的代碼以及完成走棋動作的代碼放入所定義的思考線程內,如下:DWORD WINAPI ThinkProc(LPVOID pParam)CChessDlg* pDlg=(CChessDlg*)pParam;pDlg->Think();return 0;然后,只要將原先調搜索函數并完成走棋的代碼代之以調用AfxBeginThread來啟動新線程即可,實現(xiàn)了程序的多線程,不能正常工作的問題也就隨之解決了。5.8判斷

41、勝負紅方的帥被吃,或者黑方的將被吃,游戲結束,判斷被吃的一方輸。具體代碼如下:int CChessDlg:IsGameOver(BYTE position9)int i,j;BOOL RedLive=FALSE,BlackLive=FALSE;/檢查紅方九宮是否有帥for(i=7;i<10;i+)for(j=3;j<6;j+)if(positionij=B_KING)BlackLive=TRUE;if(positionij=R_KING)RedLive=TRUE;/檢查黑方九宮是否有將for(i=0;i<3;i+)for(j=3;j<6;j+)if(positionij=B_KING)BlackLive=TRUE;if(positionij=R_KING)RedLive=TRUE;if(m_nUserC

溫馨提示

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

評論

0/150

提交評論