版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
青島理工大學(xué)C++面向?qū)ο笳n程設(shè)計(jì)報(bào)告院(系):計(jì)算機(jī)工程學(xué)院專業(yè):軟件學(xué)生姓名:xxx班級(jí):_XXX_學(xué)號(hào):XXX題目:中國(guó)象棋程序設(shè)計(jì)起迄日期:2011.06.30————2011.07.13設(shè)計(jì)地點(diǎn):現(xiàn)代教育中心機(jī)房指導(dǎo)教師:XXXX完成日期:2010年7月13日課程設(shè)計(jì)目的面向?qū)ο蟪绦蛟O(shè)計(jì)作為一門(mén)軟件設(shè)計(jì)的課程,具有極強(qiáng)的實(shí)踐性,要求學(xué)生具備靈活應(yīng)用理論知識(shí)的能力及面向?qū)ο蟪绦蛟O(shè)計(jì)技能的基礎(chǔ)。所以在《C++面向?qū)ο蟪绦蛟O(shè)計(jì)》課程學(xué)習(xí)完成后,安排課程設(shè)計(jì)教學(xué)環(huán)節(jié)。通過(guò)課程設(shè)計(jì),學(xué)生能了解C++面向?qū)ο蟮脑O(shè)計(jì)方法與技巧,有效地、深刻地理解課程內(nèi)容,體會(huì)理論、方法和設(shè)計(jì)原則;培養(yǎng)分析實(shí)際問(wèn)題和解決問(wèn)題的能力,具備使用面向?qū)ο蟪绦蛟O(shè)計(jì)開(kāi)發(fā)工具設(shè)計(jì)實(shí)際系統(tǒng)的能力。通過(guò)這次課程設(shè)計(jì),能了解并通過(guò)自學(xué)MFC,掌握一種可視化編程的方法,并通過(guò)實(shí)踐加深對(duì)可視化編程與C++面向?qū)ο蟪绦蛟O(shè)計(jì)語(yǔ)言特點(diǎn)的認(rèn)識(shí)與理解。同時(shí),可以提高運(yùn)用C++編程語(yǔ)言解決實(shí)際問(wèn)題的能力;提高調(diào)查研究、查閱技術(shù)文獻(xiàn)、資料以及編寫(xiě)軟件設(shè)計(jì)文檔的能力。課程設(shè)計(jì)內(nèi)容與實(shí)現(xiàn)的功能課程設(shè)計(jì)的題目是中國(guó)象棋,所實(shí)現(xiàn)的功能是能畫(huà)出象棋棋盤(pán),在此基礎(chǔ)上實(shí)現(xiàn)人機(jī)對(duì)弈。對(duì)弈中符合現(xiàn)實(shí)中下棋的規(guī)則情況。系統(tǒng)分析與設(shè)計(jì)1、系統(tǒng)分析中國(guó)象棋具有悠久的歷史,幾千年以來(lái),一直被認(rèn)為是人們所熱愛(ài)的休閑活動(dòng)之一。象棋具有獨(dú)特的規(guī)則,主要為車行直路,馬走狹日,相行田,士相不離老王邊,炮翻山,兵、卒只進(jìn)不退,過(guò)河后方能左右行。程序設(shè)計(jì)就是把現(xiàn)實(shí)中的人與人之間的對(duì)弈,改成電腦與人的對(duì)弈。電腦的形為仿照人的形為,正確的走棋,“思考”,下棋。任務(wù)要求,畫(huà)出棋盤(pán),實(shí)現(xiàn)簡(jiǎn)單的人機(jī)對(duì)弈。2、系統(tǒng)設(shè)計(jì):概要設(shè)計(jì)1、數(shù)據(jù)表示:主要包括棋盤(pán)的表示和棋子的表示。2、走法的產(chǎn)生:包括車馬相士炮等的基本走法和檢測(cè)是否將軍,或被將死,還包括檢查一種棋子是否還有剩余,判斷走法是否和法以及枚舉可能有的合法的走法。3、搜索引擎:搜索棋子可能有的走法,并且產(chǎn)生最佳的走法。搜索引擎包括許多算法,如極大極小值、負(fù)極大值、深度優(yōu)先搜索、置換表、歷史啟發(fā)等等搜索算法。4、估值方法:即對(duì)棋子的價(jià)值進(jìn)行評(píng)估,如兵為300,車為1000,將帥位無(wú)限大等;對(duì)棋子的位置進(jìn)行評(píng)估,如過(guò)河后越逼近九宮的卒/兵價(jià)值越大;對(duì)棋子的靈活性進(jìn)行評(píng)估,靈活性越大,價(jià)值越大,如一般車的靈活性大于卒等;對(duì)棋子間關(guān)系進(jìn)行評(píng)估,即棋子受到的威脅越大,價(jià)值越低,受到的保護(hù)越多,價(jià)值越高;還要與搜索算法相結(jié)合。5、界面設(shè)計(jì):主要有棋盤(pán)、棋子、拖動(dòng)實(shí)現(xiàn)走棋、悔棋、還原、搜素引擎(包括算法和搜索深度)設(shè)置等。一些美化可以直接使用網(wǎng)絡(luò)上的美化資源,消息響應(yīng)函數(shù)與處理函數(shù)等的實(shí)現(xiàn)。詳細(xì)設(shè)計(jì)1棋盤(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,InitChessBoard,90);//初始化棋盤(pán) memcpy(m_byShowChessBoard,InitChessBoard,90); memcpy(m_byBackupChessBoard,InitChessBoard,90); m_pSE->SetSearchDepth(3);//設(shè)定搜索層數(shù)為3 m_pSE->SetMoveGenerator(m_pMG);//給搜索引擎設(shè)定走法產(chǎn)生器 m_pSE->SetEveluator(m_pEvel);//給搜索引擎設(shè)定估值核心 m_pSE->SetUserChessColor(m_nUserChessColor); //設(shè)定用戶為黑方或紅方 m_pSE->SetThinkProgress(&m_progressThink); //設(shè)定進(jìn)度條 m_MoveChess.nChessID=NOCHESS;//將移動(dòng)的棋子清空 returnTRUE;//returnTRUEunlessyousetthefocustoacontrol2顏色public: voidSetTextColor(COLORREFcolor){m_clrText=color;} voidSetBkColor(COLORREFcolor){m_clrBkGround=color;} voidSetStartColor(COLORREFcolor){m_clrStart=color;} voidSetEndColor(COLORREFcolor){m_clrEnd=color;} voidShowPercent(BOOLbShowPercent=TRUE){m_bShowPercent=bShowPercent;} voidShowText(CStringstr,boolbIsShowText){m_strShow=str,m_bIsShowText=bIsShowText;}; COLORREFGetTextColor(void){returnm_clrText;} COLORREFGetBkColor(void){returnm_clrBkGround;} COLORREFGetStartColor(void){returnm_clrStart;} COLORREFGetEndColor(void){returnm_clrEnd;} intSetPos(intnPos); int SetStep(intnStep); intStepIt(); voidSetRange(intnLower,intnUpper);3棋子走法CStringCChessDlg::GetMoveStr(intnFromX,intnFromY,intnToX,intnToY,intnSourceID){ CStringstr; boolbIsAgain; inti; intnCount; intnPos[5]; intj=0; switch(nSourceID) { caseB_KING://黑將 if(nFromY==nToY) { str.Format("黑:將%d平%d",nFromX,nToX); break; } if(nFromY>nToY) str.Format("黑:將%d退%d",nFromX,nFromY-nToY); else str.Format("黑:將%d進(jìn)%d",nFromX,nToY-nFromY); break; caseB_CAR://黑車 bIsAgain=false; for(i=0;i<10;i++) if(m_byChessBoard[i][nFromX-1]==B_CAR&&i!=nFromY-1&&i!=nToY-1) { bIsAgain=true; break; } if(nFromY>nToY) { if(bIsAgain) { if(i>nFromY-1) str.Format("黑:后車進(jìn)%d",nFromY-nToY); else str.Format("黑:前車進(jìn)%d",nFromY-nToY); } else str.Format("黑:車%d退%d",nFromX,nFromY-nToY); } else if(nFromY<nToY) { if(bIsAgain) { if(i>nFromY-1) str.Format("黑:后車進(jìn)%d",nToY-nFromY); else str.Format("黑:前車進(jìn)%d",nToY-nFromY); } else str.Format("黑:車%d進(jìn)%d",nFromX,nToY-nFromY); } else { if(bIsAgain) { if(i>nFromY-1) str.Format("黑:后車平%d",nToX); else str.Format("黑:前車平%d",nToX); } else str.Format("黑:車%d平%d",nFromX,nToX); break; } break; caseB_HORSE://黑馬 bIsAgain=false; for(i=0;i<10;i++) if(m_byChessBoard[i][nFromX-1]==B_HORSE&&i!=nFromY-1&&i!=nToY-1) { bIsAgain=true; break; } if(bIsAgain) { if(i>nFromY-1) { if(nFromY>nToY) str.Format("黑:后馬退%d",nToX); else str.Format("黑:后馬進(jìn)%d",nToX); } else { if(nFromY>nToY) str.Format("黑:前馬退%d",nToX); else str.Format("黑:前馬進(jìn)%d",nToX); } } else { if(nFromY>nToY) str.Format("黑:馬%d退%d",nFromX,nToX); else str.Format("黑:馬%d進(jìn)%d",nFromX,nToX); } break; caseB_CANON://黑炮 bIsAgain=false; for(i=0;i<10;i++) if(m_byChessBoard[i][nFromX-1]==B_CANON&&i!=nFromY-1&&i!=nToY-1) { bIsAgain=true; break; } if(nFromY>nToY) { if(bIsAgain) { if(i>nFromY-1) str.Format("黑:后炮進(jìn)%d",nFromY-nToY); else str.Format("黑:前炮進(jìn)%d",nFromY-nToY); } else str.Format("黑:炮%d退%d",nFromX,nFromY-nToY); } else if(nFromY<nToY) { bIsAgain=false; for(i=0;i<10;i++) if(m_byChessBoard[i][nFromX-1]==B_CANON&&i!=nFromY-1&&i!=nToY-1) { bIsAgain=true; break; } if(bIsAgain) { if(i>nFromY-1) str.Format("黑:后炮進(jìn)%d",nToY-nFromY); else str.Format("黑:前炮進(jìn)%d",nToY-nFromY); } else str.Format("黑:炮%d進(jìn)%d",nFromX,nToY-nFromY); } else { if(bIsAgain) { if(i>nFromY-1) str.Format("黑:后炮平%d",nToX); else str.Format("黑:前炮平%d",nToX); } else str.Format("黑:炮%d平%d",nFromX,nToX); break; } break; caseB_BISHOP://黑士 if(nFromY>nToY) str.Format("黑:士%d退%d",nFromX,nToX); else str.Format("黑:士%d進(jìn)%d",nFromX,nToX); break; caseB_ELEPHANT://黑象 bIsAgain=false; for(i=0;i<5;i++) if(m_byChessBoard[i][nFromX-1]==B_ELEPHANT&&i!=nFromY-1&&i!=nToY-1) { bIsAgain=true; break; } if(bIsAgain) { if(i>nFromY-1) { if(nFromY>nToY) str.Format("黑:后象退%d",nToX); else str.Format("黑:后象進(jìn)%d",nToX); } else { if(nFromY>nToY) str.Format("黑:前象退%d",nToX); else str.Format("黑:前象進(jìn)%d",nToX); } } else { if(nFromY>nToY) str.Format("黑:象%d退%d",nFromX,nToX); else str.Format("黑:象%d進(jìn)%d",nFromX,nToX); } break; caseB_PAWN://黑卒 nCount=0; j=0; for(i=0;i<5;i++) nPos[i]=-1; for(i=0;i<10;i++) if(m_byChessBoard[i][nFromX-1]==B_PAWN&&i!=nFromY-1&&i!=nToY-1) { nPos[j]=i; nCount++; } if(nCount==0) { if(nFromY==nToY) str.Format("黑:卒%d平%d",nFromX,nToX); else str.Format("黑:卒%d進(jìn)%d",nFromX,1); break; } if(nCount==1) { if(nFromY>nPos[0]) { if(nFromY==nToY) str.Format("黑:前卒平%d",nToX); else str.Format("黑:前卒進(jìn)%d",1); } else { if(nFromY==nToY) str.Format("黑:后卒平%d",nToX); else str.Format("黑:后卒進(jìn)%d",1); } break; } j=0; if(nCount>1) { for(i=0;i<5;i++) if(nPos[i]==-1) break; else if(nPos[i]>nFromY) break; else j++; if(nFromY==nToY) str.Format("黑:%d卒平%d",j+1,1); else str.Format("黑:%d卒進(jìn)%d",j+1,1); break; } caseR_KING://紅帥 if(nFromX==nToX) { if(nFromY>nToY) str="紅:帥"+ConvertDigit2Chinese(10-nFromX)+"進(jìn)"+ConvertDigit2Chinese(nFromY-nToY); else str="紅:帥"+ConvertDigit2Chinese(10-nFromX)+"退"+ConvertDigit2Chinese(nToY-nFromY); } else str="紅:帥"+ConvertDigit2Chinese(10-nFromX)+"平"+ConvertDigit2Chinese(10-nToX); break; caseR_CAR://紅車 bIsAgain=false; for(i=0;i<10;i++) if(m_byChessBoard[i][nFromX-1]==R_CAR&&i!=nFromY-1&&i!=nToY-1) { bIsAgain=true; break; } if(nFromY>nToY) { if(bIsAgain) { if(i>nFromY-1) str="紅:前車進(jìn)"+ConvertDigit2Chinese(nFromY-nToY); else str="紅:后車進(jìn)"+ConvertDigit2Chinese(nFromY-nToY); } else str="紅:車"+ConvertDigit2Chinese(10-nFromX)+"進(jìn)"+ConvertDigit2Chinese(nFromY-nToY); } else if(nFromY<nToY) { if(bIsAgain) { if(i>nFromY-1) str="紅:后車退"+ConvertDigit2Chinese(nToY-nFromY); else str="紅:前車退"+ConvertDigit2Chinese(nToY-nFromY); } else str="紅:車"+ConvertDigit2Chinese(10-nFromX)+"退"+ConvertDigit2Chinese(nToY-nFromY); } else { if(bIsAgain) { if(i>nFromY-1) str="紅:后車平"+ConvertDigit2Chinese(nToX); else str="紅:前車平"+ConvertDigit2Chinese(nToX); } else str="紅:車"+ConvertDigit2Chinese(10-nFromX)+"平"+ConvertDigit2Chinese(10-nToX); break; } break; caseR_HORSE://紅馬 bIsAgain=false; for(i=0;i<10;i++) if(m_byChessBoard[i][nFromX-1]==R_HORSE&&i!=nFromY-1&&i!=nToY-1) { bIsAgain=true; break; } if(bIsAgain) { if(i>nFromY-1) { if(nFromY>nToY) str="紅:前馬進(jìn)"+ConvertDigit2Chinese(10-nToX); else str="紅:前馬退"+ConvertDigit2Chinese(10-nToX); } else { if(nFromY>nToY) str="紅:前馬進(jìn)"+ConvertDigit2Chinese(10-nToX); else str="紅:前馬退"+ConvertDigit2Chinese(10-nToX); } } else { if(nFromY>nToY) str="紅:馬"+ConvertDigit2Chinese(10-nFromX)+"進(jìn)"+ConvertDigit2Chinese(10-nToX); else str="紅:馬"+ConvertDigit2Chinese(10-nFromX)+"退"+ConvertDigit2Chinese(10-nToX); } break; caseR_CANON://紅炮 bIsAgain=false; for(i=0;i<10;i++) if(m_byChessBoard[i][nFromX-1]==R_CANON&&i!=nFromY-1&&i!=nToY-1) { bIsAgain=true; break; } if(nFromY>nToY) { if(bIsAgain) { if(i>nFromY-1) str="紅:前炮進(jìn)"+ConvertDigit2Chinese(nFromY-nToY); else str="紅:后炮進(jìn)"+ConvertDigit2Chinese(nFromY-nToY); } else str="紅:炮"+ConvertDigit2Chinese(10-nFromX)+"進(jìn)"+ConvertDigit2Chinese(nFromY-nToY); } else if(nFromY<nToY) { if(bIsAgain) { if(i>nFromY-1) str="紅:前炮退"+ConvertDigit2Chinese(nToY-nFromY); else str="紅:后炮退"+ConvertDigit2Chinese(nToY-nFromY); } else str="紅:炮"+ConvertDigit2Chinese(nFromX)+"退"+ConvertDigit2Chinese(nToY-nFromY); } else { if(bIsAgain) { if(i>nFromY-1) str="紅:前炮平"+ConvertDigit2Chinese(10-nToX); else str="紅:后炮平"+ConvertDigit2Chinese(10-nToX); } else str="紅:炮"+ConvertDigit2Chinese(10-nFromX)+"平"+ConvertDigit2Chinese(10-nToX); } break; caseR_BISHOP://紅士 if(nFromY>nToY) str="紅:士"+ConvertDigit2Chinese(10-nFromX)+"進(jìn)"+ConvertDigit2Chinese(10-nToX); else str="紅:士"+ConvertDigit2Chinese(10-nFromX)+"退"+ConvertDigit2Chinese(10-nToX); break; caseR_ELEPHANT://紅相 bIsAgain=false; for(i=0;i<5;i++) if(m_byChessBoard[i][nFromX-1]==R_ELEPHANT&&i!=nFromY-1&&i!=nToY-1) { bIsAgain=true; break; } if(bIsAgain) { if(i>nFromY-1) { if(nFromY>nToY) str="紅:前相退"+ConvertDigit2Chinese(10-nToX); else str="紅:前相進(jìn)"+ConvertDigit2Chinese(10-nToX); } else { if(nFromY>nToY) str="紅:后相退"+ConvertDigit2Chinese(10-nToX); else str="紅:后相進(jìn)"+ConvertDigit2Chinese(10-nToX); } } else { if(nFromY>nToY) str="紅:相"+ConvertDigit2Chinese(10-nFromX)+"進(jìn)"+ConvertDigit2Chinese(10-nToX); else str="紅:相"+ConvertDigit2Chinese(10-nFromX)+"退"+ConvertDigit2Chinese(10-nToX); } break; caseR_PAWN://紅兵 nCount=0; j=0; for(i=0;i<5;i++) nPos[i]=-1; for(i=0;i<10;i++) if(m_byChessBoard[i][nFromX-1]==R_PAWN&&i!=nFromY-1&&i!=nToY-1) { nPos[j]=i; nCount++; } if(nCount==0) { if(nFromY==nToY) str="紅:兵"+ConvertDigit2Chinese(10-nFromX)+"平"+ConvertDigit2Chinese(10-nToX); else str="紅:兵"+ConvertDigit2Chinese(10-nFromX)+"進(jìn)"+ConvertDigit2Chinese(1); break; } if(nCount==1) { if(nFromY-1>nPos[0]) { if(nFromY==nToY) str="紅:前兵平"+ConvertDigit2Chinese(10-nToX); else str="紅:前兵進(jìn)"+ConvertDigit2Chinese(1); } else { if(nFromY==nToY) str="紅:后兵平"+ConvertDigit2Chinese(10-nToX); else str="紅:后兵進(jìn)"+ConvertDigit2Chinese(1); } break; } j=0; if(nCount>1) { for(i=0;i<5;i++) if(nPos[i]==-1) break; else if(nPos[i]>nFromY-1) break; else j++; if(nFromY==nToY) str="紅:"+ConvertDigit2Chinese(j+1)+"兵平"+ConvertDigit2Chinese(nToX); else str="紅:"+ConvertDigit2Chinese(j+1)+"兵進(jìn)"+ConvertDigit2Chinese(1); } break; default: break; } returnstr;}2.1、模塊設(shè)計(jì):開(kāi)發(fā)Windows下的應(yīng)用程序,首先的路是:Windows應(yīng)用程序運(yùn)行的消息循環(huán)的機(jī)制。當(dāng)一個(gè)應(yīng)用程序建立的時(shí)候,操作系統(tǒng)會(huì)為這個(gè)應(yīng)用程序分配一個(gè)消息隊(duì)列,凡是跟這個(gè)應(yīng)用程序相關(guān)的消息,操作系統(tǒng)都會(huì)把這些消息放到消息隊(duì)列中。然后應(yīng)用程序得用GetMessage()從消息隊(duì)列中取出一條具體的消息。再利用TranslateMessage(),將用戶產(chǎn)生的信息轉(zhuǎn)換成類似WM_KEYDOWRR的消息,再放到消息隊(duì)列中。然后再利用DispatchMessage()將消息投遞出去。投遞給操作系統(tǒng)。操作系統(tǒng)再根據(jù)設(shè)計(jì)窗口類時(shí)的那個(gè)窗口處理函數(shù)WndProc(),對(duì)不同的消息產(chǎn)生不同的響應(yīng)。這樣就完成了整個(gè)消息的循環(huán)。2.2、數(shù)據(jù)結(jié)構(gòu)說(shuō)明:人機(jī)對(duì)弈程序采用了多種搜索算法.以下是本程序主要的類說(shuō)明:1.CEveluation類:估值類,對(duì)給定的棋盤(pán)進(jìn)行估值.2.CMoveGenerator類:走法產(chǎn)生器,對(duì)給定的棋盤(pán)局面搜索出所有可能的走法.3.CSearchEngine類:搜索引擎基類.4.CNegaMaxEngine類:負(fù)極大值法搜索引擎.5.CAlphaBetaEngine類:采用了Alpha-Beta剪枝技術(shù)的搜索引擎.6.CFAlphaBetaEngine類:fail-softalpha-beta搜索引擎.7.CHistoryHeuristic類:歷史啟發(fā)類.8.CAlphabeta_HHEngine類:帶歷史啟發(fā)的Alpha-Beta搜索引擎.9.CAspirationSearch類:渴望搜索引擎.10.CIDAlphabetaEngine類:迭代深化搜索引擎.11.CMTD_fEngine類:MTD(f)搜索引擎.12.CTranspositionTable類:置換表.13.CAlphaBeta_TTEngine類:加置換表的Alpha-Beta搜索引擎.14.CPVS_Engine類:極小窗口搜索引擎.15.CNegaScout_TT_HH類:使用了置換表和歷史啟發(fā)的NegaScout搜索引擎.2.3、算法流程圖:四、系統(tǒng)測(cè)試與調(diào)試分析1、系統(tǒng)測(cè)試測(cè)試方法:黑盒測(cè)試技術(shù):、功能測(cè)試測(cè)試數(shù)據(jù):測(cè)試報(bào)告:測(cè)試說(shuō)明測(cè)試名稱中國(guó)象棋測(cè)試目的驗(yàn)證用戶下棋的整個(gè)過(guò)程測(cè)試技術(shù)功能測(cè)試測(cè)試方法黑盒測(cè)試法測(cè)試用例測(cè)試內(nèi)容象棋運(yùn)行測(cè)試步驟打開(kāi)象棋運(yùn)行實(shí)現(xiàn)與電腦對(duì)弈測(cè)試數(shù)據(jù)正常正常正常預(yù)期結(jié)果正常進(jìn)入系統(tǒng)正常運(yùn)行正常測(cè)試結(jié)果與預(yù)期相符與預(yù)期相符與預(yù)期相符2、調(diào)試分析:由于能力和時(shí)間以及所學(xué)的知識(shí)很有限,在設(shè)計(jì)的過(guò)程中一邊對(duì)照資料,一邊用查詢。更重要的是請(qǐng)教同學(xué)和老師,對(duì)于有些我無(wú)法改正的錯(cuò)誤,我采取了有點(diǎn)消極的做法,注釋掉程序之后再進(jìn)行改正。五、用戶手冊(cè)1、使用的平臺(tái)是Windows操作系統(tǒng)。2、不需要安裝,直接打開(kāi)SourceCode文件夾,雙擊Release文件夾,再雙擊其中的象棋圖標(biāo),就可以運(yùn)行程序。3、詳細(xì)使用說(shuō)明:第一步:打開(kāi)運(yùn)行文件第二步:雙擊選擇chess.exe第三步:開(kāi)始運(yùn)行第四步:運(yùn)行完畢,直接退出。六、程序清單1//鼠標(biāo)左鍵響應(yīng)消息voidCChessDlg::OnLButtonDown(UINTnFlags,CPointpoint){ //TODO:Addyourmessagehandlercodehereand/orcalldefault if(m_iChessSort==CS_CCCHESS) { m_staticTip.SetWindowText(m_strWelcome); return; } if(m_Status==Previewing) { m_staticTip.SetWindowText("現(xiàn)在處于預(yù)覽狀態(tài),如要下棋,請(qǐng)彈出右鍵菜單點(diǎn)預(yù)覽完畢"); return; } if(m_bIsGameOver) { m_staticTip.SetWindowText("老兄,這盤(pán)棋下完了"); return; } if(m_bIsThinking)//電腦正在想 return; intx,y; //將坐標(biāo)換算成棋盤(pán)上的格子 y=(point.y-14)/GRILLEHEIGHT; x=(point.x-15)/GRILLEWIDTH; //判斷鼠標(biāo)是否在棋盤(pán)內(nèi),并且點(diǎn)中了用戶棋子 if(y>=0&&y<10&&x>=0&&x<9&&(m_nUserChessColor==REDCHESS?IsRed(m_byChessBoard[y][x]):IsBlack(m_byChessBoard[y][x]))) { memcpy(m_byBackupChessBoard,m_byChessBoard,90);//備份棋盤(pán) //將當(dāng)前棋子的信息裝入,記錄移動(dòng)棋子的結(jié)構(gòu)中 m_ptMoveChess.x=x; m_ptMoveChess.y=y; m_MoveChess.nChessID=m_byChessBoard[y][x]; //將該棋子原位置棋子去掉 m_byChessBoard[y][x]=NOCHESS; m_byShowChessBoard[y][x]=NOCHESS; //讓棋子中點(diǎn)坐標(biāo)位于鼠標(biāo)所在點(diǎn) point.x-=18; point.y-=18; m_MoveChess.ptMovePoint=point; //重繪屏幕 InvalidateRect(NULL,FALSE); UpdateWindow(); SetCapture();//獨(dú)占鼠標(biāo)焦點(diǎn) } else if(m_Status==Chessing) if(y>=0&&y<10&&x>=0&&x<9&&(m_nUserChessColor!=REDCHESS?IsRed(m_byChessBoard[y][x]):IsBlack(m_byChessBoard[y][x]))) m_staticTip.SetWindowText("不好意思,這是我的棋子,請(qǐng)你不要亂動(dòng)"); else m_staticTip.SetWindowText("老兄,那又沒(méi)有棋子,你瞎點(diǎn)什么啊"); CDialog::OnLButtonDown(nFlags,point);}2//響應(yīng)鼠標(biāo)左鍵彈起的消息voidCChessDlg::OnLButtonUp(UINTnFlags,CPointpoint){ //TODO:Addyourmessagehandlercodehereand/orcalldefault if(m_bIsGameOver) { m_staticTip.SetWindowText("老兄,這盤(pán)棋下完了"); return; } if(m_bIsThinking||m_Status!=Chessing) return; BOOLbTurnSide=FALSE; intx,y; CStringstr;//將坐標(biāo)換算成棋盤(pán)上的格子 y=(point.y-14)/GRILLEHEIGHT; x=(point.x-15)/GRILLEWIDTH; //判斷是否有移動(dòng)棋子,并且該棋子的移動(dòng)是一個(gè)合法走法// if(m_MoveChess.nChessID&&CMoveGenerator::IsValidMove(m_byBackupChessBoard,m_ptMoveChess.x,m_ptMoveChess.y,x,y,m_nUserChessColor)) if(m_MoveChess.nChessID&&m_pMG->IsValidMove(m_byBackupChessBoard,m_ptMoveChess.x,m_ptMoveChess.y,x,y,m_nUserChessColor)) { //---------將用戶走法壓棧--------- m_cmBestMove.From.x=m_ptMoveChess.x; m_cmBestMove.From.y=m_ptMoveChess.y; m_cmBestMove.To.x=x; m_cmBestMove.To.y=y; m_cmBestMove.nChessID=m_MoveChess.nChessID; m_umUndoMove.cmChessMove=m_cmBestMove; m_umUndoMove.nChessID=m_byChessBoard[y][x]; m_stackUndoMove.push(m_umUndoMove); //-------------------------------- m_btnUndo.EnableWindow(1);//激活悔棋按鈕 if(m_nUserChessColor==REDCHESS) m_iBout++; this->AddChessRecord(m_ptMoveChess.x+1,m_ptMoveChess.y+1,x+1,y+1,m_nUserChessColor,m_MoveChess.nChessID); m_byChessBoard[y][x]=m_MoveChess.nChessID; m_byShowChessBoard[y][x]=m_MoveChess.nChessID; bTurnSide=TRUE; } else//否則恢復(fù)移動(dòng)前的棋盤(pán)狀態(tài) { memcpy(m_byShowChessBoard,m_byBackupChessBoard,90); memcpy(m_byChessBoard,m_byBackupChessBoard,90); } m_MoveChess.nChessID=NOCHESS;//將移動(dòng)的棋子清空 //重繪屏幕 InvalidateRect(NULL,FALSE); UpdateWindow(); ReleaseCapture();//釋放鼠標(biāo)焦點(diǎn) if(m_iChessSort==CS_PPCHESS) { m_iWhoChess=m_iWhoChess%2+1; return; } if(bTurnSide==TRUE) { m_btnStop.EnableWindow(1); m_hHandle=::CreateThread(0,0,ThinkProc,this,0,&m_dwThreadID); } else m_staticTip.SetWindowText(m_strWelcome); CDialog::OnLButtonUp(nFlags,point);}3//響應(yīng)鼠標(biāo)移動(dòng)函數(shù)voidCChessDlg::OnMouseMove(UINTnFlags,CPointpoint){ //TODO:Addyourmessagehandlercodehereand/orcalldefault if(m_bIsThinking) return; if(m_MoveChess.nChessID) { if(m_Status==Chessing) { //防止將棋子拖出棋盤(pán) if(point.x<15)//左邊 point.x=15; if(point.y<15)//上邊 point.y=15; if(point.x>m_nBoardWidth-15)//右邊 point.x=m_nBoardWidth-15; if(point.y>m_nBoardHeight-15)//下邊 point.y=m_nBoardHeight-15; //讓棋子中心位于鼠標(biāo)所在處 point.x-=18; point.y-=18; m_MoveChess.ptMovePoint=point;//保存移動(dòng)棋子的坐標(biāo) } else { //讓棋子中心位于鼠標(biāo)所在處 point.x-=18; point.y-=18; m_MoveChess.ptMovePoint=point;//保存移動(dòng)棋子的坐標(biāo) //棋子拖出棋盤(pán)時(shí)將該棋子刪掉 if(point.x<15||point.y<15||point.x>m_nBoardWidth-15||point.y>m_nBoardHeight-15) m_byChessBoard[m_ptMoveChess.y][m_ptMoveChess.x]=NOCHESS; } InvalidateRect(NULL,FALSE);//刷新窗口 UpdateWindow();//立即執(zhí)行刷新 } CDialog::OnMouseMove(nFlags,point);}4//統(tǒng)計(jì)紅黑兩方總分 intnRedValue=0;intnBlackValue=0; for(i=0;i<10;i++) for(j=0;j<9;j++) { nChessType=position[i][j]; if(nChessType!=NOCHESS) { if(IsRed(nChessType)) nRedValue+=m_chessValue[i][j];//把紅棋的值加總 else nBlackValue+=m_chessValue[i][j];//把紅棋的值加總 } } if(nUserChessColor==REDCHESS) { if(bIsRedTurn) returnnRedValue-nBlackValue;//如果輪到紅棋走返回估值 returnnBlackValue-nRedValue;//如果輪到黑棋走返回負(fù)估值 } if(bIsRedTurn) returnnBlackValue-nRedValue;//如果輪到黑棋走返回負(fù)估值 returnnRedValue-nBlackValue;//如果輪到紅棋走返回估值}intCEveluation::GetRelatePiece(BYTEposition[][9],intj,inti){ nPosCount=0; BYTEnChessID; BYTEflag; intx,y; nChessID=position[i][j]; switch(nChessID) { caseR_KING://紅帥 caseB_KING://黑將 //循環(huán)檢查九宮之內(nèi)哪些位置可到達(dá)/保護(hù) //掃描兩邊就宮包含了照像的情況 for(y=0;y<3;y++) for(x=3;x<6;x++) if(CanTouch(position,j,i,x,y))//能否到達(dá) AddPoint(x,y);//可達(dá)到/保護(hù)的位置加入數(shù)組 //循環(huán)檢查九宮之內(nèi)哪些位置可到達(dá)/保護(hù) //掃描兩邊就宮包含了照像的情況 for(y=7;y<10;y++) for(x=3;x<6;x++) if(CanTouch(position,j,i,x,y))//能否到達(dá) AddPoint(x,y);//可達(dá)到/保護(hù)的位置加入數(shù)組 break; caseR_BISHOP://紅士 //循環(huán)檢查九宮之內(nèi)哪些位置可到達(dá)/保護(hù) for(y=7;y<10;y++) for(x=3;x<6;x++) if(CanTouch(position,j,i,x,y)) AddPoint(x,y);//可達(dá)到/保護(hù)的位置加入數(shù)組 break; caseB_BISHOP://黑士 //循環(huán)檢查九宮之內(nèi)哪些位置可到達(dá)/保護(hù) for(y=0;y<3;y++) for(x=3;x<6;x++) if(CanTouch(position,j,i,x,y)) AddPoint(x,y);//可達(dá)到/保護(hù)的位置加入數(shù)組 break; caseR_ELEPHANT://紅相 caseB_ELEPHANT://黑象 //右下 x=j+2; y=i+2; if(x<9&&y<10&&CanTouch(position,j,i,x,y)) AddPoint(x,y); //右上 x=j+2; y=i-2; if(x<9&&y>=0&&CanTouch(position,j,i,x,y)) AddPoint(x,y); //左下 x=j-2; y=i+2; if(x>=0&&y<10&&CanTouch(position,j,i,x,y)) AddPoint(x,y); //左上 x=j-2; y=i-2; if(x>=0&&y>=0&&CanTouch(position,j,i,x,y)) AddPoint(x,y); break; caseR_HORSE://紅馬 caseB_HORSE://黑馬 //檢查右下方能否到達(dá)/保護(hù) x=j+2; y=i+1; if((x<9&&y<10)&&CanTouch(position,j,i,x,y)) AddPoint(x,y); //檢查右上方能否到達(dá)/保護(hù) x=j+2; y=i-1; if((x<9&&y>=0)&&CanTouch(position,j,i,x,y)) AddPoint(x,y); //檢查左下方能否到達(dá)/保護(hù) x=j-2; y=i+1; if((x>=0&&y<10)&&CanTouch(position,j,i,x,y)) AddPoint(x,y); //檢查左上方能否到達(dá)/保護(hù) x=j-2; y=i-1; if((x>=0&&y>=0)&&CanTouch(position,j,i,x,y)) AddPoint(x,y); //檢查右下方能否到達(dá)/保護(hù) x=j+1; y=i+2; if((x<9&&y<10)&&CanTouch(position,j,i,x,y)) AddPoint(x,y); //檢查右上方能否到達(dá)/保護(hù) x=j+1; y=i-2; if((x<9&&y>=0)&&CanTouch(position,j,i,x,y)) AddPoint(x,y); //檢查左下方能否到達(dá)/保護(hù) x=j-1; y=i+2; if((x>=0&&y<10)&&CanTouch(position,j,i,x,y)) AddPoint(x,y); //檢查左上方能否到達(dá)/保護(hù) x=j-1; y=i-2; if((x>=0&&y>=0)&&CanTouch(position,j,i,x,y)) AddPoint(x,y); break; caseR_CAR://紅車 caseB_CAR://黑車 //檢查向右能否到達(dá)/保護(hù) x=j+1; y=i; while(x<9) { if(NOCHESS==position[y][x])//空白 AddPoint(x,y); else{ //碰到第一個(gè)棋子 AddPoint(x,y); break;//后面的位置不能走了 } x++; } //檢查向左能否到達(dá)/保護(hù) x=j-1; y=i; while(x>=0) { if(NOCHESS==position[y][x])//空白 AddPoint(x,y); else{ //碰到第一個(gè)棋子 AddPoint(x,y); break;//后面的位置不能走了 } x--; } //檢查向下能否到達(dá)/保護(hù) x=j; y=i+1; while(y<10) { if(NOCHESS==position[y][x])//空白 AddPoint(x,y); else{ //碰到第一個(gè)棋子 AddPoint(x,y); break;//后面的位置不能走了 } y++; } //檢查向上能否到達(dá)/保護(hù) x=j; y=i-1; while(y>=0) { if(NOCHESS==position[y][x])//空白 AddPoint(x,y); else{ //碰到第一個(gè)棋子 AddPoint(x,y); break;//后面的位置不能走了 } y--; } break; caseR_PAWN://紅兵 //觀看向前是否到底 y=i-1; x=j; if(y>=0) AddPoint(x,y);//沒(méi)到底,可走 if(i<5) { //如已過(guò)河 y=i; x=j+1;//向右 if(x<9) AddPoint(x,y);//未到右邊,可走 x=j-1;//向左 if(x>=0) AddPoint(x,y);//未到左邊,可走 } break; caseB_PAWN://黑卒 //觀看向前是否到底 y=i+1; x=j; if(y<10) AddPoint(x,y);//沒(méi)到底,可走 if(i>4) { //如已過(guò)河 y=i; x=j+1;//向右 if(x<9) AddPoint(x,y);//未到右邊,可走 x=j-1;//向左 if(x>=0) AddPoint(x,y);//未到左邊,可走 } break; caseB_CANON://黑炮 caseR_CANON://紅炮 //檢查向右能否到達(dá)/保護(hù)的位置 x=j+1; y=i; flag=FALSE; while(x<9) { if(NOCHESS==position[y][x]) { //空白位置 if(!flag) AddPoint(x,y); } else { if(!flag) flag=TRUE;//是第一個(gè)棋子 else { //是第二個(gè)棋子 AddPoint(x,y); break; } } x++;//繼續(xù)向右 } //檢查向左能否到達(dá)/保護(hù)的位置 x=j-1; y=i; flag=FALSE; while(x>=0) { if(NOCHESS==position[y][x]) { //空白位置 if(!flag) AddPoint(x,y); } else { if(!flag) flag=TRUE;//是第一個(gè)棋子 else { //是第二個(gè)棋子 AddPoint(x,y); break; } } x--;//繼續(xù)向左 } //檢查向下能否到達(dá)/保護(hù)的位置 x=j; y=i+1; flag=FALSE; while(y<10) { if(NOCHESS==position[y][x]) { //空白位置 if(!flag) AddPoint(x,y); } else { if(!flag) flag=TRUE;//是第一個(gè)棋子 else { //是第二個(gè)棋子 AddPoint(x,y); break; } } y++;//繼續(xù)向下 } //檢查向上能否到達(dá)/保護(hù)的位置 x=j; y=i-1; flag=FALSE; while(y>=0) { if(NOCHESS==position[y][x]) { //空白位置 if(!flag) AddPoint(x,y); } else { if(!flag) flag=TRUE;//是第一個(gè)棋子 else { //是第二個(gè)棋子 AddPoint(x,y); break; } } y--;//繼續(xù)向上 } break; default: break; } returnnPosCount;}5//下面的循環(huán)繼續(xù)統(tǒng)計(jì)掃描到的數(shù)據(jù) intnHalfvalue; for(i=0;i<10;i++) for(j=0;j<9;j++) { if(position[i][j]!=NOCHESS) { nChessType=position[i][j]; nHalfvalue=m_BaseValue[nChessType]/16;//棋子基本價(jià)值的1/16作為威脅/保護(hù)增量 m_chessValue[i][j]+=m_BaseValue[nChessType];//每個(gè)棋子的基本價(jià)值加入其總價(jià)值 if(IsRed(nChessType))//紅棋 { if(m_AttackPos[i][j])//當(dāng)前紅棋如果被威脅 { if(bIsRedTurn)//輪到紅棋走 { if(nChessType==R_KING)//如果是紅將 m_chessValue[i][j]-=20;//價(jià)值降低20 else { //價(jià)值減去2倍nHalfvalue m_chessValue[i][j]-=nHalfvalue*2; if(m_GuardPos[i][j])//是否被己方棋子保護(hù) m_chessValue[i][j]+=nHalfvalue;//被保護(hù)再加上nHalfvalue } } else//當(dāng)前紅棋被威脅,輪到黑棋走 { if(nChessType==R_KING)//是否是紅帥 return18888;//返回失敗極值 m_chessValue[i][j]-=nHalfvalue*10;//減去10倍的nHalfvalue,表示威脅程度高 if(m_GuardPos[i][j])//如果被保護(hù) m_chessValue[i][j]+=nHalfvalue*9;//被保護(hù)再加上9倍的nHalfvalue } //被威脅的棋子加上威脅差,防止一個(gè)兵威脅 //一個(gè)被保護(hù)的車,而估值函數(shù)沒(méi)有反映此類問(wèn)題 m_chessValue[i][j]-=m_AttackPos[i][j]; } else { //沒(méi)受威脅 if(m_GuardPos[i][j]) m_chessValue[i][j]+=5;//受保護(hù),加一點(diǎn)分 } } else { //如果是黑棋 if(m_AttackPos[i][j]) { //受威脅 if(!bIsRedTurn) { //輪到黑棋走 if(nChessType==B_KING)//如果是黑將 m_chessValue[i][j]-=20;//棋子價(jià)值降低20 else { //棋子價(jià)值降低2倍nHalfvalue m_chessValue[i][j]-=nHalfvalue*2; if(m_GuardPos[i][j])//如果受保護(hù) m_chessValue[i][j]+=nHalfvalue;//棋子價(jià)值增加nHalfvalue } } else { //輪到紅棋走 if(nChessType==B_KING)//是黑將 return18888;//返回失敗極值
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 廣西貴港市覃塘區(qū)2023-2024學(xué)年七年級(jí)下學(xué)期4月期中考試英語(yǔ)試題(含答案)
- 開(kāi)放作文之觀點(diǎn)看法類-2024年中考英語(yǔ)寫(xiě)作??碱}型專項(xiàng)突破
- 視頻系統(tǒng)的實(shí)時(shí)性優(yōu)化
- 宜君養(yǎng)豬場(chǎng)改擴(kuò)建項(xiàng)目可行性研究報(bào)告
- 成都2024年07版小學(xué)三年級(jí)下冊(cè)英語(yǔ)第3單元真題試卷
- 重慶2024年09版小學(xué)五年級(jí)英語(yǔ)第六單元期中試卷
- 名著閱讀(講練)-2023年部編版中考語(yǔ)文一輪復(fù)習(xí)(原卷版)
- 2024年醫(yī)用液氧貯槽項(xiàng)目投資申請(qǐng)報(bào)告代可行性研究報(bào)告
- 2023年固態(tài)地振動(dòng)強(qiáng)度記錄儀投資申請(qǐng)報(bào)告
- 三維數(shù)字內(nèi)容制作-三維動(dòng)畫(huà)毛發(fā)制作流程規(guī)范
- 藍(lán)色簡(jiǎn)約風(fēng)中國(guó)空軍成立75周年紀(jì)念日
- 2024年全國(guó)企業(yè)員工全面質(zhì)量管理知識(shí)競(jìng)賽題庫(kù)(含答案)(共132題)
- 知識(shí)創(chuàng)業(yè)思維與方法智慧樹(shù)知到答案2024年湖南師范大學(xué)
- 無(wú)人機(jī)全行業(yè)保險(xiǎn)
- 員工人事檔案目錄
- 迅達(dá)SWE30-100K自動(dòng)扶梯電路分析_圖文
- 拌混凝土拌合站管理辦法
- 文明如廁講衛(wèi)生PPT課件
- 電子工程師必備基礎(chǔ)知識(shí)
- 鈑金與焊接工藝規(guī)范
- 最新X線診斷報(bào)告模板(干貨分享)
評(píng)論
0/150
提交評(píng)論