?? mantischessthink.cpp
字號(hào):
/***************************************************************
MantisChessThink.cpp : MantisChess 人工智能部分
版權(quán)所有(C) 陳成濤
這一程序是自由軟件,你可以遵照自由軟件基金會(huì)出版的GNU通用公共
許可證條款來修改和重新發(fā)布這一程序。或者用許可證的第二版,或者
(根據(jù)你的選擇)用任何更新的版本。
發(fā)布這一程序的目的是希望它有用,但沒有任何擔(dān)保。甚至沒有適合特
定目的的隱含的擔(dān)保。更詳細(xì)的情況請(qǐng)參閱GNU通用公共許可證。
你應(yīng)該已經(jīng)和程序一起收到一份GNU通用公共許可證的副本。
如果還沒有,寫信給:
The Free Software Foundation,Inc,,675 Mass Ave, Cambridge,
MAO2139,USA
如果你在使用本軟件時(shí)有什么問題或建議,用以下地址可以與我取得聯(lián)
系:
http://thecct.51.net
或發(fā)Email到:
stove@eyou.com
thecct@163.com
------------------------------------------------------------------
MantisChessThink.cpp : MantisChess AI functions
Copyright (C) Chen Chengtao, China
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
If you have any question about this software please visit my hompage:
http://thecct.51.net
or E_mail to:
stove@eyou.com
thecct@163.com
******************************************************************/
#include "StdAfx.h"
#include "MantisChessDef.h"
#include "MantisChessThink.h"
//-------------下面幾項(xiàng)可以調(diào)試智能模塊---------------------------
#define S_WIDTH 8
#define S_DEPTH 6
// 將 士 象 馬 車 炮 兵
const base[7]= {300,400,300,600, 1000,600,300}; //平均價(jià)值
const range[7]= {0 , 0, 0, 20, 10, 0, 50}; //價(jià)值的變動(dòng)范圍
const int contactpercent1=20; //防守的重視程度
const int contactpercent2=25; //進(jìn)攻的重視程度
/******************************************************************
例:把馬設(shè)為平均價(jià)值200,變動(dòng)范圍±13%應(yīng)設(shè)base[3]=200,range[3]=13
*******************************************************************/
//-----------------------------------------------------------------
const int BV1[7]=//基本價(jià)值
{
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]=//兵在不同位置的價(jià)值附加
{
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)
//兵卒在不同位置的價(jià)值,數(shù)字越大價(jià)值越高
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:對(duì)走法列表進(jìn)行快速排序
參數(shù):
A: 關(guān)鍵值
chessman: 待排序的棋子列表
targetpoint: 待排序的目標(biāo)點(diǎn)列表
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: 估值函數(shù)
參數(shù):
tmap: 各棋位狀態(tài)
tmanposition: 32棋子的坐標(biāo)
tside: 輪到哪一放走
返回值: 局面的價(jià)值
******************************************************************/
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];
memset(ManContact,0,sizeof(int)<<10);
memset(ManBaseValue,0,sizeof(int)<<5);
memset(ManExtValue,0,sizeof(int)<<5);
memset(BeAteCount,0,sizeof(int)<<5);
memset(OwnSee,0,sizeof(int)<<5);
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;//對(duì)方
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];
//對(duì)方將軍
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: 列出所有走法
參數(shù):
tmap: 各棋位狀態(tài)
tmanposition: 32棋子的坐標(biāo)
tside: 輪到哪一放走
chessman: 指向棋子列表的指針(存放結(jié)果)
move: 指向棋子所走到位置的指針,與chessman一起組成走法列表
(存放結(jié)果)
count: 走法的總數(shù)(存放結(jié)果)
返回值: “照相”返回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)
}
else
{
if(!flag)flag=TRUE;
else
{
if(NORED(x,j)) ADD(n,x,j)
break;
}
}
j++;
}
j=y-1;flag=FALSE;
while(j>=1)
{
if(NOMAN(x,j))
{
if(!flag) ADD(n,x,j)
}
else
{
if(!flag)flag=TRUE;
else
{
if(NORED(x,j)) ADD(n,x,j)
break;
}
}
j--;
}
break;
case 25:
case 26:
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(NOBLACK(i,y)) ADD(n,i,y)
break;
}
}
i++;
}
i=x-1;flag=FALSE;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -