当前位置:首页 » 电脑资讯 » 为什么下围棋电脑会自动走棋

为什么下围棋电脑会自动走棋

发布时间: 2023-09-04 04:14:33

‘壹’ 电脑为什么会下象棋

我是学计算机的,呵呵,其实这个问题很有趣的呢^_^
中国的象棋我还不是很清楚,我目前所知道的最牛的机子名叫【深蓝】,战胜了国际象棋大师【卡斯帕罗夫】,详细资料如下
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++的】呵呵,加了注释,你应该能明白一点^_^

‘贰’ 为什么ai围棋天下无敌,但象棋就不行

象棋变化相对较少,计算机通过穷举的方式就可以赢人类了,所以很早之前还没出现AI时人类就下不过计算机了,能够穷举变化,那象棋在计算机眼里就一览无遗,没有东西可以深挖了,也就没有再做深入研究了。攻克了这个堡垒,目标就变成下一个了,那就是围棋,围棋变化繁多,用穷举的方式行不通了,于是就要寻求算法上的突破,好比玄幻小说中的等级,等级一旦突破,高一阶就可以碾压低一阶,由于还不知道围棋的极限在哪,所以AI还能持续进化,人类只会被越甩越远。

1997年以前,人类勉强可以自欺欺人的说,人工智能不足以挑战顶尖象棋大师。但是1997年以后,电脑足以无差别碾压任何一位人类象棋天才。

1996年,电脑cpu还是从486向奔腾迈进的年代,国际巨头ibm打造了一台超级计算机,深蓝。向当时国际象棋界无可争议的第一人卡斯帕罗夫发起挑战。那是如同乔丹在篮球场一样的具有绝对统治力的存在。深蓝落败。

1997年,经过改良的更深的蓝卷土重来,与卡斯帕罗夫手谈数局,攻克了这位国际象棋的最巅峰棋手。

犹记得那时有国内媒体骄傲的宣称,代表中国智慧的围棋复杂程度在量级上远超象棋,是电脑极难攻克的智力竞技项目。

国际芯片巨头英特尔的创始人摩尔经过观察和总结,提出了着名的摩尔定律,即每隔十八个月,电脑的运算速度快一倍。

时间来到21世纪10年代,人工智能先后击败了代表围棋界最强实力的李世石和柯洁。从此,人类的任何棋类运动在电脑面前毫无胜算。这配渣渗其中,当然也包括中国象棋。

当今中国象棋第一人王天一,类似于c罗之于足球的存在,在电脑软件面前毫无招架之力。

现在,无论围棋还是象棋,用软件拆招练习的人,胜负感更敏锐,招法更新颖,成绩也更好。这也是棋类竞技项目中,电脑胜过人类的有力佐证。

从 游戏 角度分析,象棋的核心目标是将军,将死王之后 游戏 结束。而围棋的核心目标则是围到更大的空,这个在很多围棋入门介绍视频中也在反复提到,但这个定义过于抽象,导致很多人都摸不到头脑,这个还和形式判断有关。

象棋的入门相对围棋要高一点,有七种不同的子,走法不同,而且还有河和宫的概念,其中将士不出宫,将士象不过河,兵过河可以横着走。

而围棋的入门其实更简单,两人交叉落子,落子不动,气尽而亡,两眼活棋(禁着点)。同时还有防止loop的打劫规则(象棋中其实也有对应的长将和不能行子判负的规则)

当然真正学围棋的不会把这些当作入门,他们会学习大量死活,行棋方向,手筋,收官,定式等。学完这些他们才算入门。而象棋玩家学完上面那些真的可以开始玩了。


象棋其实更像是rpg 游戏 ,你带领你的16位小伙伴去打怪,他们各有各自的能力,目标是杀死对面玩家(将/帅)这个会不会都可以开,无非是玩的好还是不好的区别。

而围棋更像是回合制的rts(即时战略)需要前期发展(定式)中期对战和厮杀(中盘)以及签订战后协议,划分最后地盘(收官)。虽然 游戏 早期rts本身的竞技性让它曾经风靡一时,但这几年还火的rts其实也没几个了。而且围棋的中盘厮杀更像是一道大型解迷,这种需要动脑子的活动还是很难普及的。


因为象棋和围棋的难度不同,象棋本身就得到了极大的普及,而且象棋画几个格子,拿几个瓶盖就能玩,在中国建国时物资还不充足时,一种好玩而且成本低的运动必然会受到许多人的追捧。而围棋就算成本再低,几百个有区分度的两种不同颜色的棋子总得有吧。所以你会在大街上,看到那些老大爷下象棋的多,这可能还与围棋不好携带有关,当然我们还说麻将也不好携带呢,为啥麻将普及度那么高呢?我们还要提到另一个原因。

一种 游戏 的普及,尤其是一种需要操作和意识的竞技 游梁歼戏 。往往一些比赛会带动观众的情绪和热情,不论是足球还是篮球,即使你不懂他们的规则,你也会在观看中知道这边把球丢进了框里得一分。像是电竞最近仍比较火热得lol,即使你没玩过,也会知道这个塔倒了,这个人被杀死了。象棋就具备这种培脊最直观得体验,少个车,丢个马还是能看出来胜负的。

而围棋,天然缺失这种优势。如果你不懂围棋,你看比赛就是一脸懵。就拿你不能要求一个听音乐会的,至少钢琴入级。一个看电影的,至少得学过影视赏析,这不现实。而且早期围棋还存在一个很致命的问题,参考柯洁和阿尔法下过的第二盘棋的解说,解说要么看不懂双方的好点,要么是不摆变化(可能觉得无足轻重,但摆变化才是呈现棋手双方复杂博弈的手段之一)讲棋的已经是职业棋手了,但还是看不懂一些棋是好是坏,这个我们普通人就更难看懂了。


固然象棋在后续还有流派,学杀招,学行棋效率,但一切都是很明了的,哪步好哪步不好都是能判断的,ai的出现只不过穷举完象棋的变化,但象棋的路数其实也差不多到头了,毕竟棋子数量就那么多,实在不行用ai去走着试试。现在象棋比赛依旧存在,双方的比拼点就是在比双方对棋的理解谁更深了。而围棋在阿尔法狗出现之前,对一些下法还存在很多争议,其实比较多是定式的争议,早期开局点三三是绝对的败招,像《围棋少年》中江流儿就下出过这样一招,剧中说这是长辈对晚辈谦恭才下这个败招,但ai时代也让很多定式的有了不一样的好坏定义。而现在看棋的人也不一定需要看讲解的说辞了,自己用ai摆摆也能看出一步棋的好坏,解说的作用可能是告诉你这步为什么好,毕竟观众不一样。

除了ai时代才把棋的好坏逐渐讲清楚这点外,围棋的宣传和教育方式也有问题。

宣传上,围棋是国粹,是一种高雅艺术,因为之前谁也讲不清,所以还是门玄学 游戏 ,一直都和高智商和高境界挂在一起。但这个能让围棋活下去但不能让围棋活得很好。早期京剧是千人千面,是真正意义的市井艺术,为了卖座,还有很多的比较俗的艺术。这里的俗分通俗和低俗,通俗让你听懂,而低俗则是直接上来挠你痒,不管怎么样,观众进到剧场里了,才会知道京剧原来是这样的,才会逐渐欣赏更雅一点的曲目。而现在京剧作为国粹,使得很多剧种都没法演,观众想看要么忍受一些不入流的京剧演员,要么只能看老片子,这对京剧的发展不利。倒不如出一些像《三审伽利略》这样的偏喜剧的京剧让一些人入一下坑,不然京剧就是下一个昆曲。

而围棋和京剧一样,无论是文学作品里的神乎奇技,还是和高雅人士挂钩。其实都是其入门难,所有人都对其抱有神秘感,而且以前有心思琢磨围棋的人都是有钱有闲的人,所以只在小众圈子里流传,现在也差不多,只不过可以利用碎片化时间了而已。

中国围棋的普及其实有几个特殊时间点,一是聂卫平在日本的十几连胜,当时只要中国在世界舞台上取得相当的成就,都会带动国内的项目的普及和发展。比如篮球,乒乓球,足球(2002),排球等。而且当时围棋入段能加分,很多人都送自己孩子去学棋,毕竟有提高智力之名。

之后可能就是棋魂和《围棋少年》的火爆。虽然棋魂是我后续补的,不知道当时有多大的影响程度,但很多围棋up都说自己是因为棋魂开始下围棋的。而围棋少年,虽然现在开始重新分析其作画有问题,过于傲慢拒绝了棋手的影视指导,导致这部剧存在了很大的瑕疵,而且天地大同和天魔大化太过故弄玄虚,本身就像是两个武林高手双方比试重要的双方的名字而不是真正的动作。其实更好的处理是在作画上体现,但是原因看前一条。但不可否认的是,围棋少年依旧是一部优秀的讲棋心,讲人情世故得动画,如果你把它当作武侠片的话。

第三阶段可能就是2016年的ai时代的来临,曾经在科幻小说里出现的,人类坚守围棋这片智力的最后高地,没想到居然来的这么快。2015年时央视还出了个围棋的记录片,讲ai要和人类一战或许还要20年,没想到才一年就杀得人类丢盔弃甲,仿佛世界末日就要到来。当时阿尔法狗还是学习人类棋谱训练的,还会输给李世石。才一年,自我学习的阿尔法狗zero就已诞生,甚至比之前还要强大数倍。之后,柯洁也在对局中败给了再次进化的阿尔法狗master。其实在这之前master已经和60位棋手下过了,基本是全胜。当时的讨论都是ai会不会统治人类,围棋现在还有要学的必要,至此,围棋可以说是脱去了神秘的面纱,关注度真正来到了顶峰。

之后是柯洁被狗打哭后连赢人类棋手十几盘,棋手这时才判然醒悟,原来和ai学棋是对的,至此,围棋不但没有衰落,反而在路人中间获得了极大的关注度,还提高了职业棋手和业余棋手的水平等级。加上柯洁本身是个很有争议的人物,所有人都来关注他,虽然我相信很多人都不是来看围棋的,但学围棋的肯定是多了起来。人们对围棋总算有了个更清晰的判断。围棋毕竟还是一个智力 游戏 。虽然有人提倡超脱于室外的道,但想下好围棋,还是得磨好杀棋制胜的术。

至此,象棋的普及基于其本身战争 游戏 的抽象,同时又简单上手,走街都能看到老大爷在下棋,普及度自然原超围棋。而围棋本身入门门槛较高,导致很多人都不愿进门槛,但现在ai和网棋的发展,人们大可以和ai去学习围棋,而不用报一些身份不明的围棋班,对于一些小伙伴来说这也是加入围棋的好机会(虽然肯定也不会很多就是了)

象棋AI早就吊打人类顶尖棋手了,只不过现在人类棋手也开始学习AI布局。加上象棋变化少,还有逼和下法;但是整体上还是不如AI。象棋现在已经发展出AI比赛,双方比拼电脑硬件,软件算法还有最关键的是AI棋库;最新的棋库都是要收费的!网上有很多AI象棋比赛视频,水平高人类选手一大截。各种精妙进攻搏杀,飞刀又见飞刀,刀刀致命!

笑死我了。

你知道象棋把世界冠军赢了的那个年代,随便一个围棋小白都能把最强的围棋AI打赢吗?

现在随便一个合格的人工智能领域的计算机博士,都有能力开发出一个世界冠军水平的象棋AI。

没人做是因为已经过时了,搞象棋AI,就好比在21世纪干BB机维修。

到目前为止。我认为Al.逻辑思维。以及追赶变化的能力仍然是远远不够的。象棋好像有个固定的路子。Al容易掌控。但对围棋我没有见过。更别说懂。但据分析,围棋的路子不是固定的。灵活的变化性较大。所以Al.掌控不了。比如像磁动机的组合。Al是组合不出来的。不知我这样评论Al.是否有一些道理?

象棋早就把人虐了,毕竟变化少,开局库加上搜索几乎能够涵盖所有的变化,而围棋变化太多,靠开局库和穷举搜索是解决不了的!所以在alphago之前,最牛的围棋软件也就有个业余五段水平!

从把深度学习(神经网络)引入围棋以来,围棋ai现在针对人而言,几乎就是神一般的存在!

现在围棋ai这么轰动,跟 社会 环境也有关系,现在整个 社会 都在热炒ai,所以象棋就相形见绌了!其实leela zero的作者也把ai应用到国际象棋上了,只是国内没大用!

说AI象棋不行的,说明你根本就没了解过,都不用ai大牛阿尔法狗上阵,低端ai就能横扫所有象棋高手了!!

相对围棋来说,象棋的变化要少的多,对于ai而言更是简单的多,需要的算力更是不可同日而语,人工智能也就是最近这两年才打败顶级人类高手,而象棋早早就被攻克了!!!

现在象棋第一人是谁你知道不?这种问题也提。。。。

我认为这个问题是由于围棋与象棋的区别造成的:

象棋对棋子的规则很多,而围棋对棋子的规则很少。

从一开局,象棋的每一个棋子都必须按照规定,放置在固定的位置上。而且,对奕双方的棋子数量和各亇棋子的作用是相同的。这就使象棋从一开始搏奕时,就有了思维基础。对奕双方就可以在这亇基础上,进行通盘谋划。

而围棋没有预设棋子的规定。开局后,对奕双方你来我往,可以在棋盘上的任意一个点落子。而后,己经落下的棋子才成为固定位置上的棋子。而那些仍然掌握在双方棋手中,还没落到棋盘上的棋子,究竟会落在那亇点上成为固定棋子,对搏奕的双方都是未知数。这就使围棋相比象棋,从开局时就对通盘谋划产生了极大的难度。

象棋对每一亇棋子的走棋方法有着严格的规定:“马走日子象走田,车走直路一炮翻山,小卒攻的一杠烟,老将蹲在后花园”。因此,造成了各个棋子的作用和杀伤力大不相同。这亇规定,可以使棋手比较容易地通过对单个棋子的所在位置,走棋规定和作用,结合全盘考虑,计祘出自己和对方的下一步棋如何走。

而围棋的棋子落在棋盘上任何一个点上后,就只能成为固定棋子,不得再挪动。因此,围棋的棋子不存在棋子走棋方法的规定问题。这就使围棋相比于象棋,减少了一个思维,判断和计祘的依据。从而也就大大地增加了围棋搏奕的难度。

象棋取胜的目标是吃掉对方的老将,简单而又明确,贯穿于整亇搏奕过程中。为此,从开局始双方就杀气腾腾,对准取胜目标,通过进攻和防守,牵制和消灭对方的棋子,直至吃掉对方的老将。当双方都无法吃掉对方老将时,只能握手言和。

围棋取胜的目标是占领比对方更多的“地盘”。而这个致胜的“地盘”究竟在那里,从一开局就是不确定的,模糊的。只有在搏奕的过程中才能逐渐显露出来。而在搏奕过程中双方产生的各个“地盘”,都有可能成为取胜的致命目标。搏奕双方在落下每一个棋子时,都要结合这些目标,全面考虑和计祘将要落下的这一亇棋子的得失。随着棋盘上双方棋子的增加,局面将会变得愈加复杂,取胜将会更难,顾此失彼的可能性很大。

象棋棋盘上的落子点只有90个,而围棋棋盘上的落子点竟多达361亇。这种落子点的增多,大大增加了围棋的变化程度和难度。

通过以上对比,显而易见,围棋需要的计祘难度远远高出于象棋。而象棋的计祘难度虽不及围棋,却规则繁多,需要较多的逻辑思维。而计祘机的优势就在于计祘。随着计祘机的发展,人类的计祘能力己远不如计祘机。因此ai围棋可以天下无敌,而象棋却不行。

围棋AI是使用的最近几年很火的深度学习算法来取胜的。象棋其实也早有软件了,但是使用的不是深度学习,而是其他技术。

深度学习目前正在发展中,还有很多需要突破的难题,但是也有很多成熟的算法。最典型的成熟算法就是图像处理。

而围棋的规则,决定了它天生就是一幅“简单”的图像。图像中,有19 19个像素。像素总共只有3种颜色:黑、白、黄(假设棋盘是黄的)。围棋是比较偏“静止”的,棋子落地生根,不允许再运动,最多就是提子。这些特点,使得看待围棋局势,就像看一幅图一样。这与象棋不同, 象棋很难当成图像进行处理

象棋棋子太多,走子规则复杂,每个棋子与周边棋子的联系不像围棋那样简单粗暴。看待围棋“图像”时,脑海中可以把某一大片黑子(或白子)连成片,当成一个整体。然后就变成了,看谁容易围住谁,谁“实”多,谁“虚”多。这就是“图像”。象棋则不行。比方说车马炮就是不相干的,很难连起来当一幅图看。

深度学习,是人工智能的一种,模拟的是人类的智能。按目前的技术,它 最接近人类不需要思考就能得立刻出结果的问题 。比方说人类识别一张人脸,是不需要思考的,靠“感觉”,而且用不了1秒钟。但是又很难描述这种“感觉”。患有脸盲症的人很难感觉出人脸,他们需要通过思考来确定特征(黑痣、发型、胡须等)。

人工智能下围棋,那就是有“棋感”。人类下围棋时,运用“棋感”,就是说下一步棋时,不需要计算和过多思考,直接通过“图像”的感觉直接走子。这在围棋开局前几十着特别常见。而计算是指,一步一步推演,比方说看看某条大龙能不能最终走活。

国际象棋的深蓝软件则不一样,那个不叫棋感,而是绝大部分是精密复杂的数学运算。

以上只是为了简单起见,提到了围棋AI的“棋感”,而且强调人工智能 目前 特别擅长处理类似图像一类的问题。实际上,阿尔法狗使用了多个网络,其中一部分负责“棋感”,另外一部分还是需要计算的。其实,这和人类下棋就很像了,人类下棋也是棋感加计算相结合的。不过阿尔法狗的精华肯定是棋感那部分。人类又何尝不是。稍微学过围棋的,谁都会推演死活,但是依赖棋感的那些“神之一手”,以及判断局势,那才是大师与菜鸟的最大区别。

‘叁’ 计算机怎么会下棋呢

‍‍

1997年5月,纽约举行了一场别开生面的国际象棋比赛,对阵双方是世界冠军卡斯帕罗夫和IBM公司的“深蓝”超级并行计算机。最终,在全世界的瞩目下,卡斯帕罗夫输给了“深蓝”,许多人因此感到人类将面临前所未有的挑战。要让计算机能够下棋,首先要用计算机语言把国际象棋的走法及下棋的一般规律编定为程序输入计算机,这种规律能使计算机通过计敏姿洞算走子后的局面来选择最佳落子方案。计算机除桥枯了掌握一般的应对招法,还要具有随机应变的本领。计算机会在下棋过程中从自己的失败中吸取教训,从对手那里吸取长处,积累经验,不断提高棋艺。这样一来,如果计算机按册羡照某种下法输了棋,它就会吸取经验,再次下棋时,计算机就会选择新的走法,不再上当。

‍‍
热点内容
为什么小米可以消灭山寨机 发布:2025-01-31 08:14:39 浏览:333
淘宝买菜为什么次日送达 发布:2025-01-31 08:14:36 浏览:528
为什么微信转账显示已转入 发布:2025-01-31 08:10:42 浏览:242
为什么女生出汗会长腿毛 发布:2025-01-31 08:01:53 浏览:825
为什么桌面上的软件点一下没了 发布:2025-01-31 07:50:20 浏览:536
为什么植入文件好慢 发布:2025-01-31 07:48:48 浏览:953
为什么男生会怂 发布:2025-01-31 07:34:28 浏览:940
晚上没喝水为什么有眼袋 发布:2025-01-31 07:22:46 浏览:906
uc书架阅读为什么会变颜色 发布:2025-01-31 07:21:18 浏览:993
为什么二极管能发出不同颜色的灯 发布:2025-01-31 07:13:52 浏览:345