我已经为玩tic-tac-toe编写了一个minimax实现。这是一个独立的函数,接受游戏状态并转向并返回最佳位置。
以下是代码:
function minimax(grid,isMaximizingPlayer,depth){
let turnOf = (isMaximizingPlayer)?'O':'X';
console.log("Playing turn of : "+turnOf);
console.log("Starting minimax @ depth: "+depth);
let vacancies = getVacantPlaces(grid);
let winner = calculateWinner(grid);
if(vacancies.length === 0){
if((isMaximizingPlayer && winner==='O') || (!isMaximizingPlayer &&
winner==='X'))
return {score: 10,position: -1};
else if((isMaximizingPlayer && winner==='X') || (!isMaximizingPlayer &&
winner==='O'))
return {score: -10,position: -1};
else if(null===winner)
return {score: 0,position: -1};
}
let moves = [];
for(let i=0;i<vacancies.length;i++){
let move = {position: -1,score: 0};
grid[vacancies[i]] = (isMaximizingPlayer) ? 'O' : 'X';
move.score = minimax(grid,!isMaximizingPlayer,depth+1).score;
if((isMaximizingPlayer && 10===move.score) ||
(!isMaximizingPlayer && -10===move.score)){
move.position = vacancies[i];
console.log("Pruning other choices, best score got @:
"+JSON.stringify(move));
return move;
}
//reset the grid
grid[vacancies[i]] = null;
moves.push(move);
}
let bestMove = {position: -1,score: 0};
if(isMaximizingPlayer){
//start with minimum score and select max of moves
bestMove.score = -10;
bestMove = moves.reduce((previousBest,currentMove) => {
return (currentMove.score > previousBest.score) ? currentMove :
previousBest;
},bestMove);
}else {
//start with maximum score and select min of moves
bestMove.score = 10;
bestMove = moves.reduce((previousBest,currentMove) => {
return (currentMove.score < previousBest.score) ? currentMove :
previousBest;
},bestMove);
}
console.log("Best move for iteration : "+ JSON.stringify(bestMove));
return bestMove;
}
//Testing input
var gameState = [null,null,'X',
'O',null,'X',
null,null,null];
console.log(JSON.stringify(minimax(gameState,true,1)));
//OUTPUTS: {"position":7,"score":10}
//EXPECTED: {"position":8,"score":0}
Here's上面代码的jsfiddle以及辅助函数,用于获取空位和计算胜利者。虽然很难但却无法找出缺失的部分。