您的位置:首页 > 大数据 > 人工智能

五子棋AI算法简易实现(六)

2018-03-07 22:38 519 查看

电脑AI篇

(3)Minimax算法(极小极大值搜索算法)

这是五子棋AI进行下子位置判断的基本方法,是整个AI最核心的算法。

A minimax algorithm is a recursive algorithm for choosing the next move in an n-player game, usually a two-player game. A value is associated with each position or state of the game. This value is computed by means of a position evaluation function and it indicates how good it would be for a player to reach that position. The player then makes the move that maximizes the minimum value of the position resulting from the opponent’s possible following moves. If it is A’s turn to move, A gives a value to each of their legal moves. —– from wikipedia

维基百科对Minimax算法的解释总结一下就是:

游戏中的每一个状态,类比棋类游戏就是玩家每下一步棋,都会产生一个值。这个值是由评估函数根据一定的方法对棋盘上同一方下棋的位置,产生的棋型等情况做出相应评估后产生的,它表示玩家在当前位置下棋所能带来的收益的大小(局势的好坏)。玩家所走的每一步,要最大化对手可能的后续移动所产生的不同位置对应的最小值(对你而言)。通俗点来说,就是在你下了当前这步棋,轮到你的对手时,你的对手会想方设法减弱你这步棋所产生的优势,而你需要做的,就是使得对手削减你的优势的程度越小越好,这使得你能够保持你的局面优势。

因此我们可以得出以下结论:

电脑走棋的层我们称为 MAX 层,这一层电脑要保证自己利益最大化,那么就需要选分最高的节点。


玩家走棋的层我们称为 MIN 层,这一层玩家要保证自己的利益最大化,那么就会选分最低的节点。


我也盗个图说明一下原理:



此图中甲是电脑,乙是玩家,那么在甲层(MAX层)的时候,总是选其中值最大的节点,乙层(MIN层)的时候,总是选其中最小的节点。而每一个节点的分数,都是由此节点的子节点所决定的,因此我们对博弈树只能进行深度优先搜索而无法进行广度优先搜索。

下面这个动图是我从维基百科上摘抄下来的,大家有时间可以看看,加深一下理解



代码实现:

con
4000
st MIN = Number.NEGATIVE_INFINITY;
const MAX = Number.POSITIVE_INFINITY;

var pointCounter = 0;

//board 当前棋盘, deep 思考步数
var FunctionMaxMin = function(board, color, deep) {
var best = MIN;
//console.log(board);
var boardTemp = StepGenerator.copyAndWrapBoard(board);
var points = StepGenerator.generateAllNextPossibleMove(boardTemp, color);
//console.log(points);
var bestPoints = [];
//console.log(points);
for(var i = 0; i < points.length; i++){
var now_point = points[i];
boardTemp[now_point[0]+2][now_point[1]+2] = color;         //下子的颜色

var value = min(boardTemp, Math.abs(color-1), deep-1);

pointCounter++;

if(value == best){
bestPoints.push(now_point);
}
else if(value > best){
best = value;
bestPoints = [];
bestPoints.push(now_point);
}
else{
console.log('ignore');
}
boardTemp[now_point[0]+2][now_point[1]+2] = 'e';
}
console.log("搜索节点数:"+pointCounter);
var result = bestPoints[Math.floor(Math.random() * bestPoints.length)];
if(result == undefined)
return [];
return [result[0]+1, result[1]+1];
}

//max函数
var max = function(board, color, deep){
var v = ModuleEvaluate.evaluate(board);
if(deep <= 0 || ModuleWinnerCheck.checkWinnerInAiController(board, color))
return v;

var best = MIN;
var points = StepGenerator.generateAllNextPossibleMove(board, color);

for( var i = 0; i < points.length; i++){

pointCounter++;

var p = points[i];
board[p[0]+2][p[1]+2] = color;
var v = min(board, Math.abs(color-1), deep-1);
board[p[0]+2][p[1]+2] = 'e';
if(v > best)
best = v;
}

return best;
};

//min函数
var min = function(board, color, deep){
var v = ModuleEvaluate.evaluate(board);
if(deep <= 0 || ModuleWinnerCheck.checkWinnerInAiController(board, color))
return v;

var best = MAX;
var points = StepGenerator.generateAllNextPossibleMove(board, color);

for( var i = 0; i < points.length; i++){

pointCounter++;

var p = points[i];
board[p[0]+2][p[1]+2] = color;
var v = max(board, Math.abs(color-1), deep-1);
board[p[0]+2][p[1]+2] = 'e';
if(v < best)
best = v;
}

return best;
};


下一篇博客将介绍AlphaBeta剪枝算法的实现。

项目地址:https://github.com/huangzhutao/Gomoku.git,相关源码可在上面查看

欢迎大家对我叙述和代码中出现的不足之处进行批评指正
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: