算法分析:
跟车一样,需要向4个方向上搜索
若该方向上没棋子,则记录该方向所有点坐标
若走着走着发现一个棋子,先冷静一下(跳出本次循环),偷偷地看接下来该方向上有没有敌方棋子,有,就可以越塔gank了。然后把敌方死的位置记录下来留作纪念~ ~ ~
(七)卒
com.bylaw.z = function (x,y,map,my){
var d=[];
if (my===1){ //红方
//上
if ( y-1>= 0 && (!com.mansmap[y-1] || com.mansmap[y-1].my!=my)) d.push([x,y-1]);
//右
if ( x+1<= 8 && y<=4 && (!com.mansmap[y] || com.mansmap[y].my!=my)) d.push([x+1,y]); //y<4,即过河之后,才能左右移动
//左
if ( x-1>= 0 && y<=4 && (!com.mansmap[y] || com.mansmap[y].my!=my))d.push([x-1,y]);
}else{
//下
if ( y+1<= 9 && (!com.mansmap[y+1] || com.mansmap[y+1].my!=my)) d.push([x,y+1]);
//右
if ( x+1<= 8 && y>=6 && (!com.mansmap[y] || com.mansmap[y].my!=my)) d.push([x+1,y]);
//左
if ( x-1>= 0 && y>=6 && (!com.mansmap[y] || com.mansmap[y].my!=my))d.push([x-1,y]);
}
return d;
}
算法分析:
同样分情况讨论。且由于卒不能后退所以只用判断上,左,右三种情况。而卒由于过河后才能左右移动,所以左右的判断除了x的界定还有y值的界定。最后跟车一样如果该着点没有棋子或该棋子颜色不同,记录该点
二 ,使用alpha-beta在所有着法当中搜索最佳着法
AI.getAlphaBeta = function (A, B, depth, map ,my) {
if (depth == 0) {
return {"value":AI.evaluate(map , my)}; //当搜索深度为0是时调用局面评价函数;
}
var moves = AI.getMoves(map , my ); //生成全部走法;
//这里排序以后会增加效率
for (var i=0; i < moves.length; i++) {
//走这个走法;
var move= moves[i];
var key = move[4];
var oldX= move[0];
var oldY= move[1];
var newX= move[2];
var newY= move[3];
var clearKey = map newY ||"";
map newY = key; //走,赋新值,删除旧值
delete map oldY ;
play.mans[key].x = newX;
play.mans[key].y = newY;
if (clearKey=="j0"||clearKey=="J0") { //被吃老将
play.mans[key].x = oldX;
play.mans[key].y = oldY;
map oldY = key;
delete map newY ; //并不是真的走,所以这里要撤销
if (clearKey){
map newY = clearKey;
}
return {"key":key,"x":newX,"y":newY,"value":8888};
}else {
var val = -AI.getAlphaBeta(-B, -A, depth - 1, map , -my).value; //上面代表AI,这里倒置,-my,代表人的着法,然后再从上面开始执行
//val = val || val.value;
//撤消这个走法;
play.mans[key].x = oldX;
play.mans[key].y = oldY;
map oldY = key;
delete map newY ;
if (clearKey){
map newY = clearKey;
//play.mans[ clearKey ].isShow = true;
}
if (val >= B) {
//将这个走法记录到历史表中;
//AI.setHistoryTable(txtMap,AI.treeDepth-depth+1,B,my);
return {"key":key,"x":newX,"y":newY,"value":B};
}
if (val > A) {
A = val; //设置最佳走法,
if (AI.treeDepth == depth) var rootKey={"key":key,"x":newX,"y":newY,"value":A};
}
}
}
if (AI.treeDepth == depth) {//已经递归回根了
if (!rootKey){
//AI没有最佳走法,说明AI被将死了,返回false
return false;
}else{
//这个就是最佳走法;
return rootKey;
}
}
return {"key":key,"x":newX,"y":newY,"value":A};
}
简化后的伪代码(与上面代码一一对应):
int AlphaBeta(int vlAlpha, int vlBeta, int nDepth) {
if (nDepth == 0) {
return 局面评价函数;
}
生成全部走法;
按历史表排序全部走法;
for (每个生成的走法) {
走这个走法;
if (被将军) {
撤消这个走法;
} else {
int vl = -AlphaBeta(-vlBeta, -vlAlpha, nDepth - 1);
撤消这个走法;
if (vl >= vlBeta) {
将这个走法记录到历史表中;
return vlBeta;
}
if (vl > vlAlpha) {
设置最佳走法;
vlAlpha = vl;
}
}
}
if (没有走过任何走法) { //AI被将死
return 杀棋的分数;
}
将最佳走法记录到历史表中;
if (根节点) {
最佳走法就是电脑要走的棋;
}
return vlAlpha;
}
最后设置坐标就可以实现AI自动走棋或吃子了
以上就是利用AI算法玩象棋的全部内容了