易商讯
当前位置: 首页 » 资讯 » 科普 » 正文

电脑为什么能计算象棋

放大字体  缩小字体 发布日期:2023-05-24 16:23:55
导读

1. 电脑下象棋的原理一种主要是通过棋谱少量由电脑计算来下棋的。还有一种则主要通过电脑的计算,当然不能完全脱离棋谱第二种的比较少见而且下起来比较卡(因为运算大,手机什么的特别明显,电脑几乎无差别)2. 为什么机器人能够战胜国际象棋大神因为普通的国际象棋棋手只能计算到7步多。而电脑却能计算到40步以外

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. 为什么和电脑走象棋都这么厉害,不是人机吗,人机怎么会有这么高的智商

  1. 电脑下棋靠的不是智商,而是算力。

  2. 从计算复杂度的角度来说,围棋>国际象棋>象棋>跳棋,目前最复杂的围棋都已经是电脑狂胜人类的水平了(还达不到完胜),象棋这种规则上就不允许太多变化的种类,更是被电脑拿捏的死死的——只要电脑不放水,人类就没有赢的可能。

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++的】呵呵,加了注释,你应该能明白一点^_^


声明:易商讯尊重创作版权。本文信息搜集、整理自互联网,若有来源标记错误或侵犯您的合法权益,请联系我们。我们将及时纠正并删除相关讯息,非常感谢!

 
(文/小编)
免责声明
• 
本文电脑为什么能计算象棋链接:http://www.esxun.cn/news/170906.html 。本文仅代表作者个人观点,请读者仅做参考,如若文中涉及有违公德、触犯法律的内容,一经发现,立即删除,作者需自行承担相应责任。涉及到版权或其他问题,请及时联系我们,我们将在24小时内处理完毕。如涉及作品内容、版权等问题,请在作品发表之日起一周内与本网联系,否则视为放弃相关权利。
 

Copyright © www.esxun.cn 易商讯ALL Right Reserved


冀ICP备2023038169号-3