在尝试编写 Tic tac toe 游戏时,我有一些javascript代码。
因此AI(人工智能)扮演“ X ”,而“人类”玩家分别扮演“ O ”;
为了测试我把板子作为
['e','e','o',
'x','o','e',
'e','e','e']
AI转向移动。显然,AI(人工智能)的最佳举措是
['e','e','o',
'x','o','e',
'x','e','e']。
但它让我回复
['x','e','o',
'x','o','e',
'e','e','e']
变种。
如果有好的提示,我将不胜感激,这将以正确的方式重新引导我
是的,我读了一周关于Minimax的一堆文章。就个人而言,我用这个教程作为原型http://blog.circuitsofimagination.com/2014/06/29/MiniMax-and-Tic-Tac-Toe.html
所以请看看我的代码:
var board = ['e', 'e', 'o', 'x', 'o', 'e', 'e', 'e', 'e'];
var signPlayer = 'o';
var signAI = (signPlayer === 'x') ? 'o' : 'x';
//Circuits Of Imagination
game = {
over: function(board) {
for (var i = 0; i < board.length; i += 3) {
if (board[i] === board[i + 1] && board[i + 1] === board[i + 2]) {
return board[i] !== 'e' ? board[i] : false;
}
}
for (var j = 0; j < board.length; j++) {
if (board[j] === board[j + 3] && board[j + 3] === board[j + 6]) {
return board[j] !== 'e' ? board[j] : false;
}
}
if ((board[4] === board[0] && board[4] === board[8]) ||
(board[4] === board[2] && board[4] === board[6])) {
return board[4] !== 'e' ? board[4] : false;
}
var element;
if (board.every(function(element) {
return element !== 'e';
})) {
return true;
}
},
winner: function(board) {
return game.over(board);
},
possible_moves: function(board, sign) {
var testBoard = [],
nextBoard;
for (var i = 0; i < board.length; i++) {
nextBoard = board.slice();
if (nextBoard[i] === 'e') {
nextBoard[i] = sign;
testBoard.push(nextBoard);
}
}
return testBoard;
}
}
function score(board) {
if (game.winner(board) === signPlayer) {
return -10;
} else if (game.winner(board) === signAI) {
return +10;
} else {
return 0;
//Game is a draw
}
}
function max(board) {
if (game.over(board)) {
return score(board);
}
var newGame = [];
var best_score = -10;
var movesArray = game.possible_moves(board, signAI);
for (var i = 0; i < movesArray.length; i++) {
newGame = movesArray[i].slice();
score = min(newGame);
if (score > best_score) {
best_score = score;
}
console.log('maxnewGame', newGame);
return best_score;
}
}
function min(board) {
if (game.over(board)) {
return score(board);
}
var newGame = [];
var worst_score = 10;
var movesArray = game.possible_moves(board, signPlayer);
for (var i = 0; i < movesArray.length; i++) {
newGame = movesArray[i].slice();
score = max(newGame);
if (score < worst_score) {
worst_score = score;
}
console.log('minnewGame', newGame);
return worst_score;
}
}
max(board);
答案 0 :(得分:2)
您的代码中存在一些错误:
return best/worst_score
,它过早地终止了搜索。把它带出循环。score
在循环中被重新定义为一个数字,当它应该是一个函数时。将其重命名为moveScore
。max/minnewGame
设置不正确。best/worse_score
被启动为+/- 10,这意味着有时没有找到最大值。固定代码如下。 然而请注意,X仍然没有选择&#34;显而易见的&#34;移动。这实际上是针对你的minimax算法工作的。这是由于算法假设对手正在最佳地进行比赛。在你给定的棋盘状态下,最佳对手将无法以X赢得胜利。因此,算法&#34;放弃&#34;并选择第一个可能的举动。
这是minmax算法的最大特性之一:算法只能做出与对手一样好的决策。如果对手被最佳地模拟,算法将不会考虑错误的可能性并放弃。为了让算法选择你认为的算法,显而易见的是,你必须让算法也考虑到转向直到丢失,所以它会在游戏中尽可能地输掉可能(这可以通过给出失败的移动-10+turns
来完成,其中转弯是失去的转弯次数)。另一种方法是根据可能的游戏超过状态来制作得分,并支持在X获胜的更多可能状态下进行移动。
var board = ['e', 'e', 'o', 'x', 'o', 'e', 'e', 'e', 'e'];
var signPlayer = 'o';
var signAI = (signPlayer === 'x') ? 'o' : 'x';
//Circuits Of Imagination
game = {
over: function(board) {
for (var i = 0; i < board.length; i += 3) {
if (board[i] === board[i + 1] && board[i + 1] === board[i + 2]) {
return board[i] !== 'e' ? board[i] : false;
}
}
for (var j = 0; j < board.length; j++) {
if (board[j] === board[j + 3] && board[j + 3] === board[j + 6]) {
return board[j] !== 'e' ? board[j] : false;
}
}
if ((board[4] === board[0] && board[4] === board[8]) ||
(board[4] === board[2] && board[4] === board[6])) {
return board[4] !== 'e' ? board[4] : false;
}
var element;
if (board.every(function(element) {
return element !== 'e';
})) {
return true;
}
},
winner: function(board) {
return game.over(board);
},
possible_moves: function(board, sign) {
var testBoard = [],
nextBoard;
for (var i = 0; i < board.length; i++) {
nextBoard = board.slice();
if (nextBoard[i] === 'e') {
nextBoard[i] = sign;
testBoard.push(nextBoard);
}
}
return testBoard;
}
}
function score(board) {
if (game.winner(board) === signPlayer) {
return -10;
} else if (game.winner(board) === signAI) {
return +10;
} else {
return 0;
//Game is a draw
}
}
function max(board) {
if (game.over(board)) {
return score(board);
}
var newGame = [];
var moveScore, maxnewGame;
var best_score = -Infinity;
var movesArray = game.possible_moves(board, signAI);
for (var i = 0; i < movesArray.length; i++) {
newGame = movesArray[i].slice();
moveScore = min(newGame);
if (moveScore > best_score) {
best_score = moveScore;
maxnewGame = newGame;
}
}
console.log('maxnewGame', maxnewGame);
return best_score;
}
function min(board) {
if (game.over(board)) {
return score(board);
}
var newGame = [];
var moveScore, minnewGame;
var worst_score = Infinity;
var movesArray = game.possible_moves(board, signPlayer);
for (var i = 0; i < movesArray.length; i++) {
newGame = movesArray[i].slice();
moveScore = max(newGame);
if (moveScore < worst_score) {
worst_score = moveScore;
minnewGame = newGame;
}
}
console.log('minnewGame', minnewGame);
return worst_score;
}
console.log(max(board));
&#13;