電腦為什麼能計算象棋
1. 電腦下象棋的原理
一種主要是通過棋譜少量由電腦計算來下棋的。還有一種則主要通過電腦的計算,當然不能完全脫離棋譜第二種的比較少見而且下起來比較卡(因為運算大,手機什麼的特別明顯,電腦幾乎無差別)
2. 為什麼機器人能夠戰勝國際象棋大神
因為普通的國際象棋棋手只能計算到7步多。而電腦卻能計算到40步以外。它能計算和租戚存儲一步棋以後所有可能的變化。這種性能人腦做不到。電腦散胡計算速度非常快。人腦也比不上沖型攔。所以機器 人能夠戰勝國際象棋大神。
3. 電腦下中國象棋時,是怎樣思考的,怎樣分析的,怎樣運算的
電腦是根據棋子價值和雙方子力總和對比分值。如果雙方各100分,帥是無價之寶50分,車9分,炮4.5分,馬4分,襪彎卜士象均為2分,兵未過河1分,過河2分,當然兵過河後位置好能大於2分,但絕不會超過炮的價值。從戰略的角度,在中國象棋局面評估中所要考慮的最基本的幾個因素主要包括如下四點:
1、子力這個理解起來很簡單,「紅方多個炮」這黑棋劣勢了。這個結論的得出,就是「子力」比較的結果。子力是指某一棋子本身所具有的價值。通俗地講就是一個棋子它值個什麼價。例如,車值300的話,那可能馬值140,炮值150等等。所以在評估局面時,我們首先要考慮雙方的子力總和的對比。
2、棋子位置棋子位置,決定「控制區域「。是指某一方的棋子在棋盤上所佔據(控制)的位置。每個棋子在棋盤的不同位置,其價值是不同的,開局要鬧悄考慮棋子在該位置對陣型的維護作用,從它的開始位置移出參戰,對這樣的棋步要給分;中局則更多的考慮棋子在該位置對對方子力、將帥的威脅。移到」敵區「的加分。同時例如,沉底炮、過河卒、以及車占士角等都是較好的棋子位置狀態加分,而窩心馬、將離開底線等則屬較差的棋子位置狀態罰分
3、棋子的活動性棋子的活動性指棋子的靈活度(可移動性)。是棋子在該位置向各處調動的可能性。棋子的威力能否充分發揮作用,與他的活動性有直接的關系。例如,起始位置的車機動性較差,所以我們下棋講究早出車。同樣四面被憋馬腿的死馬機動性也較差(對於一步也不能走的棋子,可以認為其機動性為零)。活動性的計算是把棋子在棋盤所能到達的位置數作為活動性,給予評分,而能移動到對方九宮之內,評分稍高。
4、棋子的協調性這一點的分析較為復雜,因為一個棋子與其它子之間往往存在多重關系(包括攻擊關系和保護關系)。如:一個馬可能在對方的炮的攻擊之下同時它又攻擊著對方的車。估值過程最後返回的是每一方的總分的差值,而各方的總分就是上面所提到的幾個因素的打分的總告穗和。同時棋子的協調性有許多戰術的應用,比如捉雙、抽子、棄子……等本文不再贅述。這就是開始提到幾種進攻策略的評估選取,勢必從棋子的協調性中「定型「給予不同的分值設定,決定棋局所選擇的「側翼「、」底線「、」中路「進攻的方向。如果棋子在該位置導致數個棋子(同兵種或不同兵種)有目地的配合作戰,它從屬總的行動計劃,服從於特定的作戰目地,那麼這樣的棋步根據不同的作戰方針(SideAttack(側翼、底線進攻)、MidAttack(圍繞中路進攻)、HybidAttack(混合式進攻、棄子強攻),給予不同的分數。當然,上述四條只是中國象棋局面評估中需考慮的基本情況,覆蓋並不全面。「局面評估「決定著每一步棋的走向。所以,如果今後要對引擎進行改進,提高程序的下棋水平的話,還應當在此多做文章……在象棋與計算機結合的那天起,註定軟體引擎必須隨著計算機的發展而不斷更新。同時也引來大批的計算機博弈開發者。未來中國象棋的「引擎「會隨著軟硬體技術的發展,進步驚人!
4. 計算機怎麼會下棋呢
1997年5月,紐約舉行了一場別開生面的國際象棋比賽,對陣雙方是世界冠軍卡斯帕羅夫和IBM公司的「深藍」超級並行計算機。最終,在全世界的矚目下,卡斯帕羅夫輸給了「深藍」,許多人因此感到人類將面臨前所未有的挑戰。要讓計算機能夠下棋,首先要用計算機語言把國際象棋的走法及下棋的一般規律編定為程序輸入計算機,這種規律能使計算機通過計敏姿洞算走子後的局面來選擇最佳落子方案。計算機除橋枯了掌握一般的應對招法,還要具有隨機應變的本領。計算機會在下棋過程中從自己的失敗中吸取教訓,從對手那裡吸取長處,積累經驗,不斷提高棋藝。這樣一來,如果計算機按冊羨照某種下法輸了棋,它就會吸取經驗,再次下棋時,計算機就會選擇新的走法,不再上當。
5. 電腦走象棋怎麼這么厲害
因為電腦
一、幾乎不犯錯誤……
二、幾乎不知疲倦……
三、引擎越來越強(簡單說,就是程序員編寫的核心代碼,越來越優化)
四、內含海量開局庫……(人能記多少?電腦無限)
五、開始有了「智能學習」。
說「人腦比電腦厲害的」,請在哲學論壇上去講。勿在象棋軟體中瞎扯蛋。我們討論的不是哲學,是技術,是現實。
當前的幾個軟體什麼「倚天」「棋天大聖」「奇兵」「天機」「猴王」等等,幾乎都可以戰勝「中象第一人」許銀川。相信三兩年內,許銀川將不再是電腦的對手。
6. 電腦下象棋是如何程式設計的
象棋程式是讓乎耐人跟電腦下棋的,下面我給你介紹,歡迎閱讀。
棋類游戲一般都能建立起數學模型,電腦做的只是判斷這一步棋的下一歲態春步的每種可能走法,以及每種走法的下一步……以此類推,也就是說電腦能判斷下一步怎麼走,才能對自己在下下一步以致以後的多少步內都對自己有利。隨著電腦預測的步數的增加,計算量成指數級增加,計算時間也會更長,這閉租樣,除了棋類程式的演演算法因素以外,考驗的就是計算機的CPU計算速度了~所以要在電腦的「預測能力」和等待時間之間取一個折中的步數,比如20步。1997年IBM的「深藍」戰敗世界棋王卡西帕羅夫,就是因為他的計算機的計算能力是當時世界頂尖的。
中國象棋原始碼-C語言小程式
*--------------------che;#include"dos.h";#include"stdio.h&qu;/*----------------------;#defineRED7;#defineBLACK14;#definetrue1;#definefalse0;#defineSELECT0;#defineMOVE*--------------------chess.c----------------------*/#include "dos.h"#include "stdio.h"/*----------------------------------------------------*/#define RED 7#define BLACK 14#define true 1#define false 0#define SELECT 0#define MOVE 1#define RED_UP 0x1100#define RED_DOWN 0x1f00#define RED_LEFT 0x1e00#define RED_RIGHT 0x2000#define RED_DO 0x3900#define RED_UNDO 0x1000#define BLACK_UP 0x4800#define BLACK_DOWN 0x5000#define BLACK_LEFT 0x4b00#define BLACK_RIGHT 0x4d00#define BLACK_DO 0x1c00#define BLACK_UNDO 0x2b00#define ESCAPE 0x0100#define RED_JU 1#define RED_MA 2#define RED_XIANG 3#define RED_SHI 4#define RED_JIANG 5#define RED_PAO 6#define RED_BIN 7#define BLACK_JU 8#define BLACK_MA 9#define BLACK_XIANG 10#define BLACK_SHI 11#define BLACK_JIANG 12#define BLACK_PAO 13#define BLACK_BIN 14/*----------------------------------------------------*/int firsttime=1;int savemode;char page_new=0,page_old=0;int finish=false,turn=BLACK,winner=0;int key;int redstate=SELECT,blackstate=SELECT;int board[10][9];/*----------------------------------------------------*/char *chessfile[15]={"","bmp\rju.wfb", "bmp\rma.wfb", "bmp\rxiang.wfb","bmp\rshi.wfb","bmp\rjiang.wfb","bmp\rpao.wfb","bmp\rbin.wfb","bmp\bju.wfb", "bmp\bma.wfb", "bmp\bxiang.wfb","bmp\bshi.wfb","bmp\bjiang.wfb","bmp\bpao.wfb","bmp\bbin.wfb"};char *boardfile[10][9]={{"bmp\11.wfb","bmp\1t.wfb","bmp\1t.wfb","bmp\14.wfb","bmp\15.wfb","bmp\16.wfb","bmp\1t.wfb","bmp\1t.wfb","bmp\19.wfb"},{"bmp\21.wfb","bmp\2c.wfb","bmp\2c.wfb","bmp\24.wfb","bmp\25.wfb","bmp\26.wfb","bmp\2c.wfb","bmp\2c.wfb","bmp\29.wfb"},{"bmp\21.wfb","bmp\3a.wfb","bmp\3t.wfb","bmp\34.wfb","bmp\3t.wfb","bmp\36.wfb","bmp\3t.wfb","bmp\3a.wfb","bmp\29.wfb"},{"bmp\41.wfb","bmp\4t.wfb","bmp\4a.wfb","bmp\4t.wfb","bmp\4a.wfb","bmp\4t.wfb","bmp\4a.wfb","bmp\4t.wfb","bmp\49.wfb"},{"bmp\51.wfb","bmp\52.wfb","bmp\5t.wfb","bmp\54.wfb","bmp\5t.wfb","bmp\56.wfb","bmp\5t.wfb","bmp\58.wfb","bmp\59.wfb"},{"bmp\61.wfb","bmp\62.wfb","bmp\6t.wfb","bmp\64.wfb","bmp\6t.wfb","bmp\66.wfb","bmp\6t.wfb","bmp\68.wfb","bmp\69.wfb"},{"bmp\71.wfb","bmp\7t.wfb","bmp\7a.wfb","bmp\7t.wfb","bmp\7a.wfb","bmp\7t.wfb","bmp\7a.wfb","bmp\7t.wfb","bmp\79.wfb"},{"bmp\81.wfb","bmp\8a.wfb","bmp\8t.wfb","bmp\84.wfb","bmp\85.wfb","bmp\86.wfb","bmp\8t.wfb","bmp\8a.wfb","bmp\89.wfb"},{"bmp\91.wfb","bmp\9t.wfb","bmp\9t.wfb","bmp\9t.wfb","bmp\95.wfb","bmp\9t.wfb","bmp\9t.wfb","bmp\9t.wfb","bmp\99.wfb"},{"bmp\101.wfb","bmp\102.wfb","bmp\102.wfb","bmp\104.wfb","bmp\105.wfb","bmp\106.wfb","bmp\108.wfb","bmp\108.wfb","bmp\109.wfb"}};char cursor[14][14]={0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,255,255,255,255,255,255,255,0,0,1,1,1,1,0,255,255,255,255,255,255,0,0,1,1,1,1,1,0,255,255,255,255,255,255,0,0,1,1,1,1,1,0,255,255,255,255,255,255,255,0,0,1,1,1,1,0,255,255,255,255,255,255,255,255,0,0,1,1,1,0,255,255,255,255,255,255,255,255,255,0,0,1,1,0,255,255,0,255,255,255,255,255,255,255,0,0,1,0,255,0,1,1,0,255,255,255,255,255,255,255,0,0,0,1,1,1,1,0,255,255,255,255,255,0,1,0,1,1,1,1,1,1,0,255,255,255,0,1,1,1,1,1,1,1,1,1,1,0,255,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1};struct pos{int x;int y;}position[10][9],redcurpos,redtemppos,redoldpos,blackcurpos,blacktemppos,blackoldpos; /*----------------------------------------------------*/selectpage***register char page*** /*換頁函式*/{union REGS r;r.x.ax=0x4f05;r.x.bx=0;r.x.dx=page; /*選擇頁面*/int86***0x10,&r,&r***;}unsigned char set_SVGA_mode***int vmode*** /*設定SVGA螢幕模式*/{union REGS r;r.x.ax=0x4f02;r.x.bx=vmode;int86***0x10,&r,&r***;return***r.h.ah***;}unsigned int get_SVGA_mode****** /*獲取當前SVGA螢幕模式*/{union REGS r;r.x.ax=0x4f03;int86***0x10,&r,&r***;return***r.x.bx***;}drawbmp***int start_x,int start_y,char filename[]***{char buffer[640];int i,j,k,n,r,g,b,width,length;long position;FILE *fp;if******fp=fopen***filename,"rb"******==NULL***{printf***"Error! Can't open file!"***;getch******;return;}fseek***fp,28,SEEK_SET***;fread***&i,2,1,fp***;if***i!=8*** /*檢查是否為256色點陣圖*/{puts***"Error!Can't find bitmap!"***;fclose***fp***;getch******;exit***0***;}fseek***fp,18,SEEK_SET***;fread***&width,4,1,fp***;fread***&length,4,1,fp***;if***firsttime***{fseek***fp,54,SEEK_SET***;for***i=0;i<256;i++*** /*按照該圖片的DAC色表設定色彩暫存器*/{b=fgetc***fp***;g=fgetc***fp***;r=fgetc***fp***; /*獲取R、G、B分量*/outportb***0x3c8,i***;outportb***0x3c9,r>>2***; /*右移是要轉化為VGA的6位暫存器形式*/ outportb***0x3c9,g>>2***;outportb***0x3c9,b>>2***;fgetc***fp***;}}elsefseek***fp,300,SEEK_SET***;k=***width%4***?***4-width%4***:0; /*寬度修正值*/for***j=length-1+start_x;j>=start_x;j--***{fread***buffer,width,1,fp***;for***i=start_y,n=0;i
7. 為什麼和電腦走象棋都這么厲害,不是人機嗎,人機怎麼會有這么高的智商
電腦下棋靠的不是智商,而是算力。
從計算復雜度的角度來說,圍棋>國際象棋>象棋>跳棋,目前最復雜的圍棋都已經是電腦狂勝人類的水平了(還達不到完勝),象棋這種規則上就不允許太多變化的種類,更是被電腦拿捏的死死的——只要電腦不放水,人類就沒有贏的可能。
8. 計算機去算棋類的每一步的走法可能嗎
在三項棋類中,國際象棋和中國象棋電腦的水平都已經可以跟最頂級的職業棋手抗衡了,為什麼圍棋電腦的水平卻上不去呢?
目前圍棋電腦的水平確實不高,圍棋電腦大賽獲得冠軍的軟體如果與當今中國的一流圍枯局吵棋手過招,恐怕讓九子還不夠。也就是說,它的水平連業余初段棋手都不如,更別說職業棋手了。
為什麼圍棋電腦水平上不去呢?原因大致有三。
一、國際象棋盤64格,中國象棋90個交叉點,而圍棋則有361個交叉點。象棋一局棋一般三四十個回合七八十步棋,而圍棋一盤棋要一百七八十步棋,最多的會超過300步,恐怕目前的電腦容量還不能勝任。
二、中國象棋和沒侍國際象棋的目的比較明確,就是保存子力,保衛老將。而圍棋的厚勢與薄味、要子和廢子、模樣和實地,這些都是判斷上的問題,很難在電腦上作出界定。
三、在國象和中國象棋中,計算占的比重很大,因此電腦可以用准確無誤的計算來彌補它判斷上的不足。但圍棋的計算只是圍棋的一部分,只有在中盤攻殺或死活問題時才需要,因此電腦計算的強項不能彌補它判斷上的弱項。
正是臘鍵由於上述三個原因,圍棋電腦水平恐怕在短時間內還不會有重大突破。
9. 為什麼計算機能戰勝國際象棋世界冠軍
深藍計算機是由IBM開發的象棋電腦,歷史上第一個成功在標准國際象棋比賽中打敗衛冕世界冠軍的計算機系統。深藍計算機是採用混合決策的方法。它將通用超級計算機處理器與象棋加速器晶元相結合。在超級計算機上運行的軟體執行一部分運算,更復雜的棋步交給加速器處理,然後計算出可能的棋步和結果。
深藍計算機是由IBM開發的象棋電腦。眾所周知,這是第一台計算機象棋系統,在常規時間控制下贏得了一場與世界冠軍的國際象棋比賽。深藍計算機重1270公斤,有32個大腦(微處理器),每秒鍾可以計算2億步。
深藍計算機1996年2月進行了對世界冠軍的第一場比團游信賽,然而,卡斯帕羅夫擊敗了深藍,得分為4:2。深藍當時開始升級,並於1997年5月再次對抗卡斯帕羅夫以3.5:2.5贏得了比賽,成為歷史上第一個在標准國際象棋比賽中打敗衛冕世界冠軍的計算機系統。機器的勝利磨羨標志著國際象棋歷史的新時代。隨後,卡斯帕羅夫指責IBM 作弊,並要求重新進行比賽。IBM拒絕並宣布深藍退役。
深藍計算機的評估功能最初是以廣義的形式寫成的,其中包含許多要確定的參數(塌輪例如,與中心空間優勢相比,安全的國王位置有多重要等等)。然後,通過分析成千上萬的主游戲,通過系統本身來確定這些參數的最優值。評估功能已分為8,000部分,其中許多部分專為特殊職務而設計。在開始的時候,有超過4000個職位和70萬個大師級的游戲。最終游戲資料庫包含了六個棋子,五個或更少的棋子位置。
10. 電腦為什麼會下象棋
我是學計算機的,呵呵,其實這個問題很有趣的呢^_^
中國的象棋我還不是很清楚,我目前所知道的最牛的機子名叫【深藍】,戰勝了國際象棋大師【卡斯帕羅夫】,詳細資料如下
http://www.wst.net.cn/history/5.11/10.htm
其實,計算機本身是沒有隻能的,之所以他能夠擁有下棋的能力,是因為我們預先教會了他,通過程序語言,實現了我們跟計算機之前的對話,就好像我們告訴他:
如果別人走馬,你就走馬,如果別人走象,你就走象一樣……
在計算機中,是通過程序語言來實現的,格式是
if......then......
else if......then.......
就跟上面的如果怎麼樣就怎麼樣是一樣的了,這樣計算機就懂得在不同情況下如何處理了哦^_^
希望姐姐的解釋還比較清晰^_^
【補充來了】^_^
思路1,平均每方每步可有35種走法。50回合。
思路2,棋盤上90個點,各點可走的點。如車可以走到任意一點。
按照思路一的演算法 往多了算
一盤棋有50回合,也就是100步,每步有50種變化
一共的變化數就是50的100次方
就算少算一點
一盤棋有20回合,也就是40步,每步10種變化
一共的變化數是10的40次方
這個數也足夠大了,就是1後面跟著40個0
【也就是說,別人走了一步以後,你有多少種可能的走法,計算機會去計算,然後擇優錄取】
給你個演算法吧,我們實驗課上經常做這些^_^
#include "StdAfx.h"
#include "Calculate.h"
#include "MantisChessThink.h"
#include "string.h"
#include "stdio.h"
/*************************************************************************
把Think重新包裝一下,進行坐標變換,希望以後其他人的演算法的介面都採用這個函數
這樣的編譯出來的DLL可以直接替換原來的CChessThinker.dll
timespan是思考的限定時間,以毫秒為單位,時間不同可能導致不同的思考策略。
本程序中的演算法沒有使用這一變數。
**************************************************************************/
BOOL Calculate(char* map,int timespan,int& x1,int& y1,int& x2,int& y2)
{
//BOOL Thinking(int tmap[11][12],POINT tmanposition[32],int &tside,int &resultman, POINT &resultpoint);
int tmap[11][12];
POINT manpoint[32];
int side=(int)map[0]-48;
int resultman=32;
POINT resultpoint={0,0};
for (int i = 0; i < 11; i++)
{
for (int j = 0; j < 12; j++)
{
tmap[i][j] = 32;
}
}
for (int i = 0; i < 32; i++)
{
manpoint[i].x=0;
manpoint[i].y=0;
}
int length=(int)strlen(map);
int index = 1;
while (index < length)
{
int x =1 + ((int)map[index + 0]-48);//thinking的x從1到9
int y = 10 - ((int)map[index + 1]-48);//thinking的y從10到1
int color = (int)map[index + 2]-48;//0-RED,1-BLAVK
int type = (int)map[index + 3]-48;//0-6
int manIndex=0;
if (color==0)
{
switch (type)
{
case 0:
manIndex=0;
break;
case 1:
if (manpoint[1].x==0) manIndex=1;
else manIndex=2;
break;
case 2:
if (manpoint[3].x==0) manIndex=3;
else manIndex=4;
break;
case 3:
if (manpoint[5].x==0) manIndex=5;
else manIndex=6;
break;
case 4:
if (manpoint[7].x==0) manIndex=7;
else manIndex=8;
break;
case 5:
if (manpoint[9].x==0) manIndex=9;
else manIndex=10;
break;
case 6:
if (manpoint[11].x==0) manIndex=11;
else if (manpoint[12].x==0) manIndex=12;
else if (manpoint[13].x==0) manIndex=13;
else if (manpoint[14].x==0) manIndex=14;
else manIndex=15;
break;
}
}
else
{
switch (type)
{
case 0:
manIndex=16;
break;
case 1:
if (manpoint[17].x==0) manIndex=17;
else manIndex=18;
break;
case 2:
if (manpoint[19].x==0) manIndex=19;
else manIndex=20;
break;
case 3:
if (manpoint[21].x==0) manIndex=21;
else manIndex=22;
break;
case 4:
if (manpoint[23].x==0) manIndex=23;
else manIndex=24;
break;
case 5:
if (manpoint[25].x==0) manIndex=25;
else manIndex=26;
break;
case 6:
if (manpoint[27].x==0) manIndex=27;
else if (manpoint[28].x==0) manIndex=28;
else if (manpoint[29].x==0) manIndex=29;
else if (manpoint[30].x==0) manIndex=30;
else manIndex=31;
break;
}
}
manpoint[manIndex].x=x;
manpoint[manIndex].y=y;
tmap[x][y]=manIndex;
index += 4;
}
//ShowInt(side);
//ShowInt(resultman);
//ShowInt(resultpoint.x);
//ShowInt(resultpoint.y);
BOOL b=Think( tmap,manpoint,side,resultman,resultpoint);
if (b)
{
x1=manpoint[resultman].x-1;
y1=10-manpoint[resultman].y;
x2=resultpoint.x-1;
y2=10-resultpoint.y;
}
return b;
//return FALSE;
}
BOOL test(char* x1)
{
return FALSE;
}
void ShowInt(int i)
{
char buf[256];
sprintf(buf,"%d",i);
MessageBox(NULL,buf,"test",0);
}
void ShowString(char * t)
{
MessageBox(NULL,t,"test",0);
}
/ CChessThink.cpp : 定義 DLL 應用程序的入口點。
//
#include "stdafx.h"
#ifdef _MANAGED
#pragma managed(push, off)
#endif
BOOL APIENTRY DllMain( HMODULE hMole,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
#ifdef _MANAGED
#pragma managed(pop)
#endif
Calculate.h
void ShowInt(int i);
void ShowString(char * t);
BOOL Calculate(char* map,int timespan,int& x1,int& y1,int& x2,int& y2);
MantisChessDef.h
const int MW=32,SW=1; //MW-棋子寬度;SW-棋子間隔的一半
const int BWA=MW+SW*2; //BWA-棋格寬度
const int XBW=BWA*9,YBW=BWA*10; //棋盤的長寬
const int MAN=0; //人
const int COM=1; //計算機
const int RED=0; //紅方
const int BLACK=1; //黑方
const int RED_K=0; //紅帥
const int RED_S=1; //仕
const int RED_X=2; //相
const int RED_M=3; //馬
const int RED_J=4; //車
const int RED_P=5; //炮
const int RED_B=6; //兵
const int BLACK_K=7; //黑將
const int BLACK_S=8; //士
const int BLACK_X=9; //象
const int BLACK_M=10; //馬
const int BLACK_J=11; //車
const int BLACK_P=12; //炮
const int BLACK_B=13; //卒
//以下是全局函數定義:
//把棋子序號轉換為對應圖標的序號
const int ManToIcon[33]= {0,1,1,2,2,3,3,4,4,5,5,6,6,6,6,6
,7,8,8,9,9,10,10,11,11,12,12,13,13,13,13,13,-1};
//棋子類型與圖標的序號相同
#define ManToType ManToIcon
const int ManToType7[33]= {0,1,1,2,2,3,3,4,4,5,5,6,6,6,6,6
,0,1,1,2,2,3,3,4,4,5,5,6,6,6,6,6,-1};
//隨即函數,返回小於n的隨機整數
int rnd(const int& n);
//給出棋子序號!!,判斷是紅是黑
const int SideOfMan[33]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,-1};
const int _defaultmap[11][12]=
{
// [0][1][2][3][4][5][6][7][8][9][10][11]
{32,32,32,32,32,32,32,32,32,32,32,32},//[0]
{32,32,32,32,32,32,32,32,32,32,32,32},//[1]
{32,32,32,32,32,32,32,32,32,32,32,32},//[2]
{32,32,32,32,32,32,32,32,32,32,32,32},//[3]
{32,32,32,32,32,32,32,32,32,32,32,32},//[4]
{32,32,32,32,32,32,32,32,32,32,32,32},//[5]
{32,32,32,32,32,32,32,32,32,32,32,32},//[6]
{32,32,32,32,32,32,32,32,32,32,32,32},//[7]
{32,32,32,32,32,32,32,32,32,32,32,32},//[8]
{32,32,32,32,32,32,32,32,32,32,32,32},//[9]
{32,32,32,32,32,32,32,32,32,32,32,32}//[10]
};
const int FistOfSide[2]={0,16};
const int LastOfSide[2]={15,31};
const int MAXMOVE = 1000;
struct MOVEHISTORY
{
int count;
int man[MAXMOVE];
POINT from[MAXMOVE];
POINT to[MAXMOVE];
int betaken[MAXMOVE];
};
#include "StdAfx.h"
#include "MantisChessDef.h"
#include "MantisChessThink.h"
//-------------下面幾項可以調試智能模塊---------------------------
#define S_WIDTH 8
#define S_DEPTH 6
// 將 士 象 馬 車 炮 兵
const int base[7]= {300,400,300,600, 1000,600,300}; //平均價值
const int range[7]= {0 , 0, 0, 20, 10, 0, 50}; //價值的變動范圍
const int contactpercent1=20; //防守的重視程度
const int contactpercent2=25; //進攻的重視程度
/******************************************************************
例:把馬設為平均價值200,變動范圍±13%應設base[3]=200,range[3]=13
*******************************************************************/
//-----------------------------------------------------------------
const int BV1[7]=//基本價值
{
base[0]-base[0]*range[0]/100,
base[1]-base[1]*range[1]/100,
base[3]-base[2]*range[2]/100,
base[3]-base[3]*range[3]/100,
base[4]-base[4]*range[4]/100,
base[5]-base[5]*range[5]/100,
base[6]-base[6]*range[6]/100
};
const int BV2[7]=//活躍度
{
2*base[0]*range[0]/100/4,
2*base[1]*range[1]/100/4,
2*base[2]*range[2]/100/4,
2*base[3]*range[3]/100/8,
2*base[4]*range[4]/100/17,
2*base[5]*range[5]/100/17,
0,
};
const int BV3[5]=//兵在不同位置的價值附加
{
0*2*base[6]*range[6]/100/4,
1*2*base[6]*range[6]/100/4,
2*2*base[6]*range[6]/100/4,
3*2*base[6]*range[6]/100/4,
4*2*base[6]*range[6]/100/4,
};
#define NORED(i,j) (SideOfMan[tmap[i][j]]!=0)
#define NOBLACK(i,j) (SideOfMan[tmap[i][j]]!=1)
#define NOMAN(i,j) (tmap[i][j]==32)
//兵卒在不同位置的價值,數字越大價值越高
const int ManBPlus[2][12][11]=
{
{
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 1, 2, 3, 4, 4, 4, 3, 2, 1, 0},
{ 0, 1, 2, 3, 4, 4, 4, 3, 2, 1, 0},
{ 0, 1, 2, 3, 3, 3, 3, 3, 2, 1, 0},
{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
{ 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0},
{ 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
},
{
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0},
{ 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0},
{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
{ 0, 1, 2, 3, 3, 3, 3, 3, 2, 1, 0},
{ 0, 1, 2, 3, 4, 4, 4, 3, 2, 1, 0},
{ 0, 1, 2, 3, 4, 4, 4, 3, 2, 1, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
}
};
//-------------------------------------------
static void ContactV(int tmap[11][12],POINT tmanposition[32],int &tside,int activity[32],int contact[32][32]);
/******************************************************************
Mantis_QuickSort:對走法列表進行快速排序
參數:
A: 關鍵值
chessman: 待排序的棋子列表
targetpoint: 待排序的目標點列表
low,high: QuickSort上下限
返回值: 無
******************************************************************/
void Mantis_QuickSort(int A[],int chessman[],POINT targetpoint[],int low,int high)
{
int pivot;
int pivot_man;
POINT pivot_point;
int scanUp,scanDown;
int mid,k;
POINT point;
if(high-low<=0)
{
return;
}
else
{
if(high-low==1)
{
if(A[high]>A[low])
{
k=A[high];
A[high]=A[low];
A[low]=k;
k=chessman[high];
chessman[high]=chessman[low];
chessman[low]=k;
point=targetpoint[high];
targetpoint[high]=targetpoint[low];
targetpoint[low]=point;
return;
}
}
}
mid=(low +high)/2;
pivot=A[mid];
pivot_man=chessman[mid];
pivot_point=targetpoint[mid];
k=A[mid];
A[mid]=A[low];
A[low]=k;
k=chessman[mid];
chessman[mid]=chessman[low];
chessman[low]=k;
point=targetpoint[mid];
targetpoint[mid]=targetpoint[low];
targetpoint[low]=point;
scanUp =low+1;
scanDown = high;
do{
while(scanUp<=scanDown && A[scanUp]>=pivot)
scanUp++;
while(pivot>A[scanDown])
scanDown--;
if(scanUp<scanDown)
{
k=A[scanUp];
A[scanUp]=A[scanDown];
A[scanDown]=k;
k=chessman[scanUp];
chessman[scanUp]=chessman[scanDown];
chessman[scanDown]=k;
point=targetpoint[scanUp];
targetpoint[scanUp]=targetpoint[scanDown];
targetpoint[scanDown]=point;
}
}while(scanUp<scanDown);
A[low]=A[scanDown];
A[scanDown]=pivot;
chessman[low]=chessman[scanDown];
chessman[scanDown]=pivot_man;
targetpoint[low]=targetpoint[scanDown];
targetpoint[scanDown]=pivot_point;
if(low<scanDown-1)
Mantis_QuickSort(A,chessman,targetpoint,low,scanDown-1);
if(scanDown+1<high)
Mantis_QuickSort(A,chessman,targetpoint,scanDown+1,high);
}
/******************************************************************
Value: 估值函數
參數:
tmap: 各棋位狀態
tmanposition: 32棋子的坐標
tside: 輪到哪一放走
返回值: 局面的價值
******************************************************************/
int Value(int tmap[11][12],POINT tmanposition[32],int &tside)
{
static int k;
static int ManExtValue[32];
static int ManBaseValue[32];
static int ManContact[32][32];
static int BeAteCount[32];
static BOOL OwnSee[32];
ZeroMemory(ManContact,sizeof(int)*32*32);
ZeroMemory(ManBaseValue,sizeof(int)*32);
ZeroMemory(ManExtValue,sizeof(int)*32);
ZeroMemory(BeAteCount,sizeof(int)*32);
ZeroMemory(OwnSee,sizeof(int)*32);
int maxvalue=0;
int i,j;
ContactV(tmap,tmanposition,tside,ManBaseValue,ManContact);
//己方將軍
for(i=FistOfSide[tside];i<=LastOfSide[tside];i++)
{
if(ManContact[i][FistOfSide[!tside]])
{
maxvalue=9700;
return maxvalue;
}
}
for(i=0;i<32;i++)
{
k=ManToType7[i];
ManBaseValue[i]=BV1[k]+ManBaseValue[i]*BV2[k];
switch(k)
{
case 6: ManBaseValue[i]+=BV3[ ManBPlus[SideOfMan[i]][tmanposition[i].y][tmanposition[i].x] ];
break;
}
}
for(i=0;i<32;i++)
{
for(j=0;j<32;j++)
{
if(ManContact[i][j])
{
if(SideOfMan[i]==SideOfMan[j])
{
BeAteCount[j]++;
if(!OwnSee[j])
{
ManExtValue[i]+=ManBaseValue[j]*contactpercent1/100;//己方
OwnSee[j]=TRUE;
}
}
else
{
ManExtValue[i]+=ManBaseValue[j]*contactpercent2/100;//對方
BeAteCount[j]--;
}
}
}
}
for(i=FistOfSide[tside];i<=LastOfSide[tside];i++)
{
if(tmanposition[i].x)maxvalue+=ManBaseValue[i]+ManExtValue[i];
}
static BOOL flag;
flag=FALSE;k=32;
for(i=FistOfSide[!tside];i<=LastOfSide[!tside];i++)
{
if(tmanposition[i].x)maxvalue-=ManBaseValue[i]+ManExtValue[i];
//對方將軍
if(ManContact[i][FistOfSide[tside]])
{
flag=TRUE;
k=i;
break;
}
}
if(flag&&BeAteCount[k]>=0)//被將,所將軍的棋子不能被吃掉
{
j=0;
for(i=FistOfSide[tside];i<=LastOfSide[tside];i++)
{
if(BeAteCount[i]<0 && ManBaseValue[i]>j)
j=ManBaseValue[i];
}
maxvalue -=j;
}
else
{
j=0;
for(i=FistOfSide[!tside];i<=LastOfSide[!tside];i++)
{
if(BeAteCount[i]<0 && ManBaseValue[i]>j)
j=ManBaseValue[i];
}
maxvalue +=j;
}
return maxvalue;
}
/******************************************************************
EnumList: 列出所有走法
參數:
tmap: 各棋位狀態
tmanposition: 32棋子的坐標
tside: 輪到哪一放走
chessman: 指向棋子列表的指針(存放結果)
move: 指向棋子所走到位置的指針,與chessman一起組成走法列表
(存放結果)
count: 走法的總數(存放結果)
返回值: 「照相」返回TRUE,否則返回FALSE
******************************************************************/
BOOL EnumList(int tmap[11][12],POINT tmanposition[32],int &tside,int *chessman,POINT *move,int &count)
{
#define ADD(man,tx,ty) {chessman[count]=man;move[count].x=tx;move[count].y=ty;count++;if(tmap[tx][ty]==FistOfSide[!tside])goto _NOKING;}
static int i,j,n,x,y;
static BOOL flag;
count=0;
for(n=FistOfSide[tside];n<=LastOfSide[tside];n++)
{
x=tmanposition[n].x;
if(!x)continue;
y=tmanposition[n].y;
switch(n)
{
case 0:
if(tmanposition[0].x==tmanposition[16].x) //將帥在同一列
{
flag=FALSE;
for(j=tmanposition[16].y+1;j<tmanposition[0].y;j++)
{
if(tmap[x][j]!=32)
{
flag=TRUE;
break;
}
}
if (!flag)
{
ADD(0,x,tmanposition[16].y);
}
}
j=y+1;if(j<=10 && NORED(x,j)) ADD(0,x,j)
j=y-1;if(j>=8 && NORED(x,j)) ADD(0,x,j)
i=x+1;if(i<=6 && NORED(i,y)) ADD(0,i,y)
i=x-1;if(i>=4 && NORED(i,y)) ADD(0,i,y)
break;
case 16:
if(tmanposition[0].x==tmanposition[16].x) //將帥在同一列
{
flag=FALSE;
for(j=tmanposition[16].y+1;j<tmanposition[0].y;j++)
{
if(tmap[x][j]!=32)
{
flag=TRUE;
break;
}
}
if (!flag)
{
ADD(16,x,tmanposition[0].y);
}
}
j=y+1;if(j<=3 && NOBLACK(x,j)) ADD(16,x,j)
j=y-1;if(j>=1 && NOBLACK(x,j)) ADD(16,x,j)
i=x+1;if(i<=6 && NOBLACK(i,y)) ADD(16,i,y)
i=x-1;if(i>=4 && NOBLACK(i,y)) ADD(16,i,y)
break;
case 1:
case 2:
i=x+1;j=y+1;if(i<=6 && j<=10 && NORED(i,j)) ADD(n,i,j)
i=x+1;j=y-1;if(i<=6 && j>=8 && NORED(i,j)) ADD(n,i,j)
i=x-1;j=y+1;if(i>=4 && j<=10 && NORED(i,j)) ADD(n,i,j)
i=x-1;j=y-1;if(i>=4 && j>=8 && NORED(i,j)) ADD(n,i,j)
break;
case 17:
case 18:
i=x+1;j=y+1;if(i<=6 && j<=3 && NOBLACK(i,j)) ADD(n,i,j)
i=x+1;j=y-1;if(i<=6 && j>=1 && NOBLACK(i,j)) ADD(n,i,j)
i=x-1;j=y+1;if(i>=4 && j<=3 && NOBLACK(i,j)) ADD(n,i,j)
i=x-1;j=y-1;if(i>=4 && j>=1 && NOBLACK(i,j)) ADD(n,i,j)
break;
case 3:
case 4:
i=x+2;j=y+2;if(i<=9 && j<=10 && NORED(i,j)) if(NOMAN(x+1,y+1)) ADD(n,i,j)
i=x+2;j=y-2;if(i<=9 && j>=6 && NORED(i,j)) if(NOMAN(x+1,y-1)) ADD(n,i,j)
i=x-2;j=y+2;if(i>=1 && j<=10 && NORED(i,j)) if(NOMAN(x-1,y+1)) ADD(n,i,j)
i=x-2;j=y-2;if(i>=1 && j>=6 && NORED(i,j)) if(NOMAN(x-1,y-1)) ADD(n,i,j)
break;
case 19:
case 20:
i=x+2;j=y+2;if(i<=9 && j<=5 && NOBLACK(i,j)) if(NOMAN(x+1,y+1)) ADD(n,i,j)
i=x+2;j=y-2;if(i<=9 && j>=1 && NOBLACK(i,j)) if(NOMAN(x+1,y-1)) ADD(n,i,j)
i=x-2;j=y+2;if(i>=1 && j<=5 && NOBLACK(i,j)) if(NOMAN(x-1,y+1)) ADD(n,i,j)
i=x-2;j=y-2;if(i>=1 && j>=1 && NOBLACK(i,j)) if(NOMAN(x-1,y-1)) ADD(n,i,j)
break;
case 5:
case 6:
i=x+1;
if(NOMAN(i,y))
{
i=x+2;j=y+1;if(i<=9 && j<=10 && NORED(i,j)) ADD(n,i,j)
i=x+2;j=y-1;if(i<=9 && j>=1 && NORED(i,j)) ADD(n,i,j)
}
i=x-1;
if(NOMAN(i,y))
{
i=x-2;j=y+1;if(i>=1 && j<=10 && NORED(i,j)) ADD(n,i,j)
i=x-2;j=y-1;if(i>=1 && j>=1 && NORED(i,j)) ADD(n,i,j)
}
j=y+1;
if(NOMAN(x,j))
{
i=x+1;j=y+2;if(i<=9 && j<=10 && NORED(i,j)) ADD(n,i,j)
i=x-1;j=y+2;if(i>=1 && j<=10 && NORED(i,j)) ADD(n,i,j)
}
j=y-1;
if(NOMAN(x,j))
{
i=x+1;j=y-2;if(i<=9 && j>=1 && NORED(i,j)) ADD(n,i,j)
i=x-1;j=y-2;if(i>=1 && j>=1 && NORED(i,j)) ADD(n,i,j)
}
break;
case 21:
case 22:
i=x+1;
if(NOMAN(i,y))
{
i=x+2;j=y+1;if(i<=9 && j<=10 && NOBLACK(i,j)) ADD(n,i,j)
i=x+2;j=y-1;if(i<=9 && j>=1 && NOBLACK(i,j)) ADD(n,i,j)
}
i=x-1;
if(NOMAN(i,y))
{
i=x-2;j=y+1;if(i>=1 && j<=10 && NOBLACK(i,j)) ADD(n,i,j)
i=x-2;j=y-1;if(i>=1 && j>=1 && NOBLACK(i,j)) ADD(n,i,j)
}
j=y+1;
if(NOMAN(x,j))
{
i=x+1;j=y+2;if(i<=9 && j<=10 && NOBLACK(i,j)) ADD(n,i,j)
i=x-1;j=y+2;if(i>=1 && j<=10 && NOBLACK(i,j)) ADD(n,i,j)
}
j=y-1;
if(NOMAN(x,j))
{
i=x+1;j=y-2;if(i<=9 && j>=1 && NOBLACK(i,j)) ADD(n,i,j)
i=x-1;j=y-2;if(i>=1 && j>=1 && NOBLACK(i,j)) ADD(n,i,j)
}
break;
case 7:
case 8:
i=x+1;
while(i<=9)
{
if (NOMAN(i,y)) ADD(n,i,y)
else
{
if(NORED(i,y)) ADD(n,i,y)
break;
}
i++;
}
i=x-1;
while(i>=1)
{
if (NOMAN(i,y)) ADD(n,i,y)
else
{
if(NORED(i,y)) ADD(n,i,y)
break;
}
i--;
}
j=y+1;
while(j<=10)
{
if (NOMAN(x,j)) ADD(n,x,j)
else
{
if(NORED(x,j)) ADD(n,x,j)
break;
}
j++;
}
j=y-1;
while(j>=1)
{
if (NOMAN(x,j)) ADD(n,x,j)
else
{
if(NORED(x,j)) ADD(n,x,j)
break;
}
j--;
}
break;
case 23:
case 24:
i=x+1;
while(i<=9)
{
if (NOMAN(i,y)) ADD(n,i,y)
else
{
if(NOBLACK(i,y)) ADD(n,i,y)
break;
}
i++;
}
i=x-1;
while(i>=1)
{
if (NOMAN(i,y)) ADD(n,i,y)
else
{
if(NOBLACK(i,y)) ADD(n,i,y)
break;
}
i--;
}
j=y+1;
while(j<=10)
{
if (NOMAN(x,j)) ADD(n,x,j)
else
{
if(NOBLACK(x,j)) ADD(n,x,j)
break;
}
j++;
}
j=y-1;
while(j>=1)
{
if (NOMAN(x,j)) ADD(n,x,j)
else
{
if(NOBLACK(x,j)) ADD(n,x,j)
break;
}
j--;
}
break;
case 9:
case 10:
i=x+1;flag=FALSE;
while(i<=9)
{
if(NOMAN(i,y))
{
if(!flag) ADD(n,i,y)
}
else
{
if(!flag)flag=TRUE;
else
{
if(NORED(i,y)) ADD(n,i,y)
break;
}
}
i++;
}
i=x-1;flag=FALSE;
while(i>=1)
{
if(NOMAN(i,y))
{
if(!flag) ADD(n,i,y)
}
else
{
if(!flag)flag=TRUE;
else
{
if(NORED(i,y)) ADD(n,i,y)
break;
}
}
i--;
}
j=y+1;flag=FALSE;
while(j<=10)
{
if(NOMAN(x,j))
{
if(!flag) ADD(n,x,j)
【我是學c++的】呵呵,加了注釋,你應該能明白一點^_^