我想在我的連接四個遊戲中使用minimax算法創建AI,但我無法正常工作。我相信我非常接近,但我仍然無法弄清楚。任何人都可以幫助我解決任何錯誤嗎?我意識到我的代碼並不好,因爲我對Javascript的效率不高,這就是爲什麼我想試試這個。如果我完全偏離軌道,有人能告訴我更好的方法嗎?提前致謝。用maximax算法幫助連接四個Javascript
編輯:我用我更新後的代碼替換了我的代碼。它現在「工作」,只要給我AI動作,但問題是他們不是「聰明」的動作。我已經看過許多極小極小定義,我覺得我已經正確實現了它。即使當我跑到7尺的深度時,一個5歲的人也可以擊敗它。任何幫助,將不勝感激。
function getBestMove(currBoard,depth,who) {
var opp;
//Get opponent for next piece
if(who == 'a') {
opp = 'p';
} else {
opp = 'a';
}
var tBoard = new Array(rows);
for(var i=0; i<tBoard.length; i++) {
tBoard[i] = new Array(cols);
}
var moves = new Array(aiOpenCols.length);
//Drop each piece and use minimax function until depth == 0
for(var i=0; i<aiOpenCols.length; i++) {
for(var j=0; j<rows; j++) {
for(var k=0; k<cols; k++) {
tBoard[j][k] = currBoard[j][k];
}
}
tBoard = dropPiece(aiOpenCols[i],who,tBoard);
moves[i] = minimax(tBoard,(+depth - 1),opp,aiOpenCols[i]);
}
var bestAlpha = -100000; //Large negative
//Use random column if no moves are "good"
var bestMove = Math.floor(Math.random() * aiOpenCols.length);
bestMove = +aiOpenCols[bestMove];
//Get largest value from moves for best move
for(var i=0; i<aiOpenCols.length; i++) {
if(+moves[i] > bestAlpha) {
bestAlpha = moves[i];
bestMove = aiOpenCols[i];
}
}
bestMove++; //Offset by 1 due to actual drop function
return bestMove;
}
function minimax(currBoard,depth,who,col) {
//Drop current piece, called from getBestMove function
currBoard = dropPiece(col,who,currBoard);
//When depth == 0 return heuristic/eval of board
if(+depth == 0) {
var ev = evalMove(currBoard);
return ev;
}
var alpha = -100000; //Large negative
var opp;
//Get opponent for next piece
if(who == 'a') {
opp = 'p';
} else {
opp = 'a';
}
//Loop through all available moves
for(var i=0; i<aiOpenCols.length; i++) {
var tBoard = new Array(rows);
for(var i=0; i<tBoard.length; i++) {
tBoard[i] = new Array(cols);
}
for(var j=0; j<rows; j++) {
for(var k=0; k<cols; k++) {
tBoard[j][k] = currBoard[j][k];
}
}
//Continue recursive minimax until depth == 0
var next = minimax(tBoard,(+depth - 1),opp,aiOpenCols[i]);
//Alpha = max(alpha, -minimax()) for negamax
alpha = Math.max(alpha, (0 - +next));
}
return alpha;
}
function evalMove(currBoard) {
//heuristic function
//AI = # of 4 streaks + # of 3 streaks + # of 2 streaks - # of 3 streaks opp - # of 2 streaks opp
var fours = checkFours(currBoard,'b') * 1000;
var threes = checkThrees(currBoard,'b') * 100;
var twos = checkTwos(currBoard,'b') * 10;
var oppThrees = checkThrees(currBoard,'r') * 100;
var oppTwos = checkTwos(currBoard,'r') * 10;
var scores = fours + threes + twos - oppThrees - oppTwos;
//If opponent wins, return large negative
var oppFours = checkFours(currBoard,'r');
if(+oppFours > 0) {
return -100000;
} else {
return scores;
}
}
function dropPiece(col,who,currBoard) {
for(var i=0; i<currBoard.length; i++) {
if(currBoard[i][col] != 'w') {
//Make sure column isn't full
if(i != 0) {
if(who == 'p') {
currBoard[i-1][col] = 'r';
} else {
currBoard[i-1][col] = 'b';
}
break;
}
}
//If column is empty, place in first row
if(i == (currBoard.length - 1)) {
if(who == 'p') {
currBoard[i][col] = 'r';
} else {
currBoard[i][col] = 'b';
}
}
}
return currBoard;
}
此代碼:var eval = evalMove(currBoard,who);產生一個錯誤,重命名變量。這是因爲
eval
是javascript中的[內置函數](http://www.w3schools.com/jsref/jsref_eval.asp),因此您不能將其用作變量名稱。如果您在瀏覽器的JS控制檯中運行以下命令,則可以看到它:eval; eval(「x = 2; console.log(x);」); var eval = 5; eval; eval(「x = 2; console。日誌(X);「); – linski這絕對是一個問題,謝謝指出。我仍然遇到了AI實際上是「智能」的麻煩,但這可能是我遇到的幾個問題之一。 – Tricky12
我必須糾正自己,我只注意到你*不使用eval內置函數,所以這不會影響算法的結果。這不是一個錯誤,但肯定是一個糟糕的實踐。 – linski