2017-04-18 8 views
-1

私はminimaxアルゴリズムを使ってTicTacToe AIを実装しようとしています。TicTacToe Minimaxアルゴリズムは常に最低値を返します

AIの順番に再生するときは、ComputerTurn(ボード状態、正方形がX、O、または空であるかどうかを追跡するintの配列)を呼び出します。 ComputerTurnはminimax(minimaxアルゴリズム)を呼び出し、win(3行をチェックする)を呼び出します。

私がスクリプトを実行すると、アルゴリズムは常に最も低い正当なプレイを返すことにします。 IEの場合、左上の四角形(タイル0)が利用できる限り、常に最初に返します。その正方形が取られれば、上の中間(タイル1)などが返されます。

ここで何が起きているのかわかりません。私の伝統的なデバッグ手法(Debug.Logまたはprint)はUnityを多くの点でクラッシュさせています見たいです。

void ComputerTurn(int[] board) 
{ 
    int move = -1; 
    int score = -2; 
    int i; 
    for (i = 0; i < 9; ++i) 
    { 
     if (board[i] == 0) 
     { 
      board[i] = 1; 
      int tempScore = -minimax(board, -1); 
      board[i] = 0; 
      if (tempScore > score) 
      { 
       score = tempScore; 
       move = i; 
      } 
     } 
    } 

    board[move] = 1; 
    if (PlayerTurn == 1) 
    { 
     //Draw an O 
     Board[move] = -1; 
    } 
    else 
    { 
     //Draw an X 
     Board[move] = 1; 
    } 
    //Changes to player's turn 
} 

int minimax(int[] board, int player) 
{ 
    int winner = win(board); 
    if (winner != 0) return winner * player; 

    int move = -1; 
    int score = -2;//Losing moves are preferred to no move 
    int i; 
    for (i = 0; i < 9; ++i) 
    {//For all moves, 
     if (board[i] == 0) 
     {//If legal, 
      board[i] = player;//Try the move 
      int thisScore = -minimax(board, player * -1); 
      if (thisScore > score) 
      { 
       score = thisScore; 
       move = i; 
      }//Pick the one that's worst for the opponent 
      board[i] = 0;//Reset board after try 
     } 
    } 
    if (move == -1) return 0; 
    return score; 
} 

int win(int[] board) 
{ 
    //determines if a player has won, returns 0 otherwise. 
    int[,] wins = new int[8, 3] { { 0, 1, 2 }, { 3, 4, 5 }, { 6, 7, 8 }, { 0, 3, 6 }, { 1, 4, 7 }, { 2, 5, 8 }, { 0, 4, 8 }, { 2, 4, 6 } }; 
    int i; 
    for (i = 0; i< 8; ++i) 
    { 
     if (board[wins[i, 0]] != 0 && 
      board[wins[i, 0]] == board[wins[i, 1]] && 
      board[wins[i, 0]] == board[wins[i, 2]]) 
     { 
      return board[wins[i, 2]]; 
     } 
    } 
    return 0; 
} 
+0

これはminmaxではありません。これはバックトラッキングです。 – AhmadWabbi

+0

申し訳ありませんが、間違った用語を使用しています。私はまだ私の論理エラーがどこにあるのか混乱している。なぜそれが最適な動きを返さないのか分かりません。 – 3dward3lric

+0

ブレークポイントを設定できませんか? – Neil

答えて

0

編集:これを解決済みとする方法を教えてください。

私は何が起こっているのかを発見しました。

board[move] = 1; 
if (PlayerTurn == 1) 
{ 
    //Draw an O 
    Board[move] = -1; 
} 
else 
{ 
    //Draw an X 
    Board[move] = 1; 
} 
//Changes to player's turn 

は実際に

Board[move] = 1; 

if (PlayerTurn == 1) 
{ 
    //Draw a Y 
} 
else 
{ 
    //Draw an X 
} 

//Change turn 

エラーが、私は私のプレーヤーのターンをしていたかにもあったであるべき。私の質問を見てくれた人のおかげです。

1

必ずしも最初の空のセルを返すわけではありません。たとえば、[0、0、0、-1、0、-1、0、1]の位置でフィードを試行します。0を返しません。代わりに4を選択します。実装にはエラーはありません。

問題はアルゴリズムにあります。あなたの体重機能は1、0または-1にしかならないので、あなたのプログラムは、そのターンで勝てるかどうかを見ることができますが、強い動き(高い勝利の結果を持つもの)と弱いもの(勝利は可能ですが、そうは思われません)。これは、提供された例からわかるように、失われた動きをフィルタリングします。

関連する問題