2016-10-22 7 views
0

У меня есть класс доски, который представляет игровое поле в Tic-Tac-Toe, но мой AI не работает. Я бы очень признателен за любую помощь. Благодаря!Fix Tic-Tac-Toe Minimax ai

Я пытаюсь использовать алгоритм минимаксного типа, чтобы попытаться понять, какой лучший способ сделать на доске, но я получаю странные результаты. Прямо сейчас, чтобы проверить мой код, я просто запускаю метод testAI().

public class Board 
{ 
    private int[] board = {0,0,0,0,0,0,0,0,0}; 
    private final int HUMAN = -1; 
    private final int COMPUTER = 1; 
    private final int[][] winList = { 
      {0, 1, 2}, 
      {3, 4, 5}, 
      {6, 7, 8}, 
      {0, 3, 6}, 
      {1, 4, 7}, 
      {2, 5, 8}, 
      {0, 4, 8}, 
      {2, 4, 6} 
     }; 
private int[] choice = new int[10000]; 
private int choiceCount = 0; 
private int[] scoreArray = new int[10000]; 

public void reset() { 
    for (int i = 0; i < board.length; i++) { 
     board[i] = 0; 
    } 
} 

public void set(int index, int player) { 
    board[index] = player; 
} 

public int[] set(int[] board2, int index, int player) { 
    board2[index] = player; 
    return board2; 
} 

public boolean checkEmpty(int index) { 
    if (board[index] == 0) { 
     return true; 
    } else { 
     return false; 
    } 
} 

public boolean isGameOver() { 
    for (int i = 0; i < board.length; i++) { 
     if (board[i] == 0) { 
      return false; 
     } 
    } 
    return true; 
} 

public boolean isGameOver(int[] board2) { 
    for (int i = 0; i < board2.length; i++) { 
     if (board2[i] == 0) { 
      return false; 
     } 
    } 
    return true; 
} 

public int chooseRandomSpot() { 
    while (true) { 
     int r = (int)(9 * Math.random()); 
     if (checkEmpty(r)) 
      return r; 
    } 
} 

private String[] toStringArray() { 
    String[] y = new String[9]; 
    for (int i = 0; i < board.length; i++) { 
     if (board[i] == 0) { 
      y[i] = " "; 
     } else if (board[i] == 1) { 
      y[i] = "x"; 
     } else if (board[i] == -1) { 
      y[i] = "o"; 
     } 
    } 
    return y; 
} 

public void printBoard() { 
    String[] y = toStringArray(); 
    System.out.println(" a b c"); 
    for (int i = 0; i < 3; i++) { 
     if (i == 0) { 
      System.out.println("a " + y[0] + " " + y[1] + " " + y[2]); 
     } else if (i == 1) { 
      System.out.println("b " + y[3] + " " + y[4] + " " + y[5]); 
     } else if (i == 2) { 
      System.out.println("c " + y[6] + " " + y[7] + " " + y[8]); 
     } 

    } 
} 

public boolean checkForWin(int player) { 
    for (int i = 0; i < 8; i++) { 
     int a = winList[i][0]; 
     int b = winList[i][1]; 
     int c = winList[i][2]; 

     if (board[a] == player && board[b] == player && board[c] == player) { 
      return true; 
     } 
    } 
    return false; 
} 

public boolean checkForWin(int[] board2, int player) { 
    for (int i = 0; i < 8; i++) { 
     int a = winList[i][0]; 
     int b = winList[i][1]; 
     int c = winList[i][2]; 

     if (board2[a] == player && board2[b] == player && board2[c] == player) { 
      return true; 
     } 
    } 
    return false; 
} 

public int getMaxChoice() { 
    int loc = 0; 
    int max = Integer.MIN_VALUE; 
    for (int i = 0; i < choice.length; i++) { 
     if (scoreArray[i] > max) { 
      max = scoreArray[i]; 
      loc = choice[i]; 
     } 
    } 
    return loc; 
} 

public void testAI() { 
    int[] x = {1,0,0,-1,1,0,-1,0,0}; 
    board = x; 
    printBoard(); 
    minimax(x,COMPUTER); 
    printBoard(); 
    System.out.println(getMaxChoice(); 
    int[] y = set(x,getMaxChoice(),COMPUTER); 
    board = y; 
    printBoard(); 
} 

private int score(int[] board2) { 
    if (checkForWin(board2, COMPUTER)) { 
     return 10; 
    } else if (checkForWin(board2, HUMAN)) { 
     return -10; 
    } else { 
     return 0; 
    } 
} 

private int minimax(int[] board2, int player) { 
    //System.out.println("In here!!"); 
    int oppPlayer = 0; 


    if (player == COMPUTER) { 
     oppPlayer = HUMAN; 
    } else { 
     oppPlayer = COMPUTER; 
    } 

    if (isGameOver(board2) || checkForWin(board2, COMPUTER) || checkForWin(board2, HUMAN)) { 
     return score(board2); 
    } 

    int amt = 0; // find the amount of possible moves 
    for (int i = 0; i < board2.length; i++) { 
     if (board2[i] == 0) { 
      amt++; 
     } 
    } 

    int[] scores = new int[amt]; 
    int[] moves = new int[amt]; 
    int count = 0; //the index of the moves array 
    for (int i = 0; i < amt; i++) { 
     if (board2[i] == 0) { //if the space is empty 
      moves[count] = i;// appends the index of the next empty space to the moves array 
      count++; 
     } 

     //int[] newBoard = set(board2, moves[count], player); //make a new board with each move 
     //scores[count] = minimax(newBoard, oppPlayer); 
    } 
    for (int i = 0; i < moves.length; i++) { 
     //int[] newBoard = set(board2, moves[i], player); //make a new board with each move 
     int[] newBoard = new int[board2.length]; 
     for (int m = 0; m < board2.length; m++) { 
      newBoard[m] = board2[m]; 
     } 
     newBoard = set(newBoard, moves[i], player); 
     scores[i] = minimax(newBoard, oppPlayer); //populate the scores array with the final score of each move 
    } 

    if (player == COMPUTER) { 
     int max = Integer.MIN_VALUE; 
     int indexOfMax = 0; 
     for (int i = 0; i < scores.length; i++) { 
      if (scores[i] > max) { 
       max = scores[i]; 
       indexOfMax = i; 
      } 
     } 
     choice[choiceCount] = moves[indexOfMax]; 
     scoreArray[choiceCount] = scores[indexOfMax]; 
     choiceCount++; 
     System.out.println(choice); 
     return max; 
    } else { 
     int min = Integer.MAX_VALUE; 
     int indexOfMin = 0; 
     for (int i = 0; i < scores.length; i++) { 
      if (scores[i] < min) { 
       min = scores[i]; 
       indexOfMin = i; 
      } 
     } 
     choice[choiceCount] = moves[indexOfMin]; 
     scoreArray[choiceCount] = scores[indexOfMin]; 
     choiceCount++; 
     return min; 
    } 
} 

public int getIndex(String r, String c) { 
    if (r.equals("a")) { 
     if (c.equals("a")) { 
      return 0; 
     } else if (c.equals("b")) { 
      return 1; 
     } else if (c.equals("c")) { 
      return 2; 
     } 
    } else if (r.equals("b")) { 
     if (c.equals("a")) { 
      return 3; 
     } else if (c.equals("b")) { 
      return 4; 
     } else if (c.equals("c")) { 
      return 5; 
     } 
    } else if (r.equals("c")) { 
     if (c.equals("a")) { 
      return 6; 
     } else if (c.equals("b")) { 
      return 7; 
     } else if (c.equals("c")) { 
      return 8; 
     } 
    } 
    return 0; 
} 

}

+0

Что такое «странные результаты»? Что вы узнали, когда запускаете это с помощью отладчика? –

+0

Мой вызов getMaxValue из функции testAi не возвращает правильное значение – Tyler

ответ

1
for (int i = 0; i < amt; i++) { 
    if (board2[i] == 0) { //if the space is empty 
     moves[count] = i;// appends the index of the next empty space to the moves array 
     count++; 
    } 
} 

shoudn't этот цикл запуска по всей плате? как

for (int i = 0; i < board2.length; i++) { 

(не знаю, если то ваша проблема, просто увидел, что и думал, что это может быть неправильно)

+0

Большое спасибо! – Tyler

+0

WOW! Я только что исправил эту часть своего кода, и выяснилось, что теперь все работает отлично! Это всегда маленькие, неосторожные ошибки, которые разрушают код, не так ли?) – Tyler

+0

@Tyler Да, и это всегда занимает много часов, чтобы найти эти глупые ошибки xD Проклятие информатики. –