Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/EmptyTag/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 什么';这个极小极大算法怎么了?_Java_Tic Tac Toe_Minimax - Fatal编程技术网

Java 什么';这个极小极大算法怎么了?

Java 什么';这个极小极大算法怎么了?,java,tic-tac-toe,minimax,Java,Tic Tac Toe,Minimax,所以我试图学习游戏算法,并编写了这个简单的井字游戏。游戏本身运行得非常好,我创建了一个虚拟的“AI”,开始玩随机移动,但现在我正在研究一个极大极小算法,使我的程序无与伦比。问题是,我花了几个小时试图使这个算法工作,但我无法让它工作/找到一个好地方来解释如何正确地实现它。我做错了什么?谢谢:) public static int minimax(String[]newBoard,String player)抛出异常{ 如果(isGameOver(newBoard).equals(player)){

所以我试图学习游戏算法,并编写了这个简单的井字游戏。游戏本身运行得非常好,我创建了一个虚拟的“AI”,开始玩随机移动,但现在我正在研究一个极大极小算法,使我的程序无与伦比。问题是,我花了几个小时试图使这个算法工作,但我无法让它工作/找到一个好地方来解释如何正确地实现它。我做错了什么?谢谢:)

public static int minimax(String[]newBoard,String player)抛出异常{
如果(isGameOver(newBoard).equals(player)){return-10;}//玩家获胜
else if(isGameOver(newBoard).equals(computer)){return 10;}//计算机获胜
ArrayList AvailableSpot=空点(新板);
if(availableSpots.size()==0){return 0;}//tie
int index=0,maxScore=-100;
//int[]moveScores=新int[availableSpots.size()];
对于(int i=0;i最大分数){
maxScore=温度;
指数=i;
}
}
收益指数;
}
}
以下是完整的代码供参考: TicTacToeAI.java

package TicTacToeAI;

import java.util.Scanner;
import java.util.ArrayList;
import TicTacToeAI.randomPlayer;

public class TicTacToeAI {
  public static String[] board = {" ", " ", " "," ", " ", " "," ", " ", " "};
  /* ^^ we make the array with spaces here because 
   * 1. initializing it with a for loop kinda sounds stupid, this isn't hard
   * 2. makes formatting easier
   */
  public static Scanner in = new Scanner(System.in); 
  public static String computer = "", player = "";
  public static void main (String [] args) throws Exception {
    // welcome
    System.out.println("Welcome to Tic Tac Toe!");
    player = choosePieces();
    computer = opposite(player);  
    String turn = "X";
    while (isGameOver(board).equals("N")) {
      System.out.println(turn + " to move:");
      if (turn.equals(computer)) {
        board[randomPlayer.makeRandomMove(board)] = computer;
        printBoard();
      } else {
        System.out.println("It's your turn!");
        printBoard();
        makeMove(player);
      }
      System.out.println("MINIMAX RETURNS " + minimax(board, turn)); // ------------------------------ DEBUG ------------------
      turn = opposite(turn);
    }
    // the game is now over. print the final board
    printBoard();
    String result = isGameOver(board);
    if (result.equalsIgnoreCase(computer)) {
      System.out.println("Computer (" + computer + ") wins! Hooray!");
    } else if (result.equalsIgnoreCase("T")) {
      System.out.println("It's a tie!");
    } else {
      System.out.println("Human (" + player + ") wins! Congratulations!");
    }
  }
  public static void printBoard() {
    for (int i = 0; i < 3; i++) {
      for (int j = 0; j < 3; j++) {
        System.out.print(board[i*3 + j] + "|");
      }
      System.out.print("\n");
    }
    System.out.print("\n"); // for spaced out formatting
  }
  public static String choosePieces() {
    System.out.println("Would you like to play as X or O? (X is first)");
    String piece = in.nextLine();
    while (!(piece.equalsIgnoreCase("X") || piece.equalsIgnoreCase("O"))) {
      System.out.println("Invalid input! Please enter X or O:");
      piece = in.nextLine();
    }
    return piece.toUpperCase();
  }
  public static String opposite(String piece) {
    if (piece.equalsIgnoreCase("X")) { return "O"; }
    return "X";
  }
  public static String isGameOver(String[] b) { // b for board
    /* String because we can transmit both wether or not the game is over
     * (empty as long as game isn't over), who's the winner (by making it equal to the winner's piece),
     * AND wether or not it is a tie ("T" for tie) */
    for (int i = 0; i < 3; i++) {
      // check horizontally
      if (b[3*i].equals(b[3*i + 1]) && b[3*i].equals(b[3*i + 2]) && !b[3*i].equals(" ")) {
        return b[3*i];
      }
      // check vertically
      if (b[i].equals(board[i+3]) && b[i].equals(b[i+6]) && !b[i].equals(" ")) {
        return b[i];
      }
    }
    // check diagonally
    if (b[0].equals(b[4]) && b[4].equals(b[8])  && !b[0].equals(" ")) {
      return b[0];
    }
    if (b[2].equals(b[4]) && b[2].equals(b[6]) && !b[2].equals(" ")) {
      return b[2];
    }
    // check for tie
    for (int i = 0; i < b.length; i++) {
      if (b[i] == " ") { return "N"; } // not a tie, game isn't over
    }
    return "T"; // a tie (no winner found, and no spots left)
  }
  public static void makeMove(String piece) {
    System.out.println("Please enter a move location (1-9):");
    int location = in.nextInt() - 1;
    /* make sure location is valid
     * NOTE: This will not cause an index out of bounds error as if it is, 
     * the first two conditionals will catch it ;)
     */
    while (location < 0 || location > 8 || !board[location].equals(" ")) {
      System.out.println("Invalid move location! Please enter a valid move location 1-9:");
      location = in.nextInt() - 1;
    }
    board[location] = piece;
  }
  public static String[] makeNewMove(String piece, int location) throws Exception {
    // same as above method but without output or verification. for computer's use only
    String[] newBoard = board.clone();
    try {
      newBoard[location] = piece;
    } catch (Exception e) {
      System.out.println("Invalid computer input.");
    }
    return newBoard;
  }
  public static ArrayList<Integer> emptySpots(String[] board) {
    // returns arraylist with index values of empty (" ") spots
    ArrayList<Integer> emptySpots = new ArrayList<Integer>();
    for (int i = 0; i < board.length; i++) {
      if (board[i].equals(" ")) { emptySpots.add(i); }
    }
    return emptySpots;
  }
  public static int getBestMove() {
    return 0; //minimax algorithm to be implemented here
  }
  public static int minimax(String[] newBoard, String player) throws Exception {

    if (isGameOver(newBoard).equals(player)) { return -10; } // player wins
    else if (isGameOver(newBoard).equals(computer)) { return 10; } // computer wins
    ArrayList<Integer> availableSpots = emptySpots(newBoard);
    if (availableSpots.size() == 0) { return 0; } // tie

    int index = 0, maxScore = -100;
    //int[] moveScores = new int[availableSpots.size()];

    for (int i = 0; i < availableSpots.size(); i++) {
      int temp = minimax(makeNewMove(opposite(player), availableSpots.get(i)), opposite(player));
      if (temp > maxScore) {
        maxScore = temp;
        index = i;
      }
    }

    return index;
  }
}
package TicTacToeAI;

import java.util.Random;
import java.util.ArrayList;

public class randomPlayer {
  public static int makeRandomMove(String[] board) {
    Random rand = new Random();
    ArrayList<Integer> availableSpots = new ArrayList<Integer>();
    for (int i = 0; i < board.length; i++) {
      if (!(board[i].equalsIgnoreCase("X") || board[i].equalsIgnoreCase("O"))) {
        availableSpots.add(i);
      }
    }
    return availableSpots.get(rand.nextInt(availableSpots.size()));
  }
}
package-TicTacToeAI;
导入java.util.Scanner;
导入java.util.ArrayList;
导入TicTacToeAI.random播放器;
公共类Tictatcoaei{
公共静态字符串[]board={“”、“”、“”、“”、“”、“”、“”、“”、“”、“”、“”、“”};
/*^^我们在此处使用空格创建数组,因为
*1.用for循环初始化它听起来有点愚蠢,这并不难
*2.使格式化更容易
*/
公共静态扫描仪in=新扫描仪(System.in);
公共静态字符串计算机=”,播放器=”;
公共静态void main(字符串[]args)引发异常{
//欢迎光临
System.out.println(“欢迎来到Tic-Tac-Toe!”);
player=选择片段();
电脑=对方(玩家);
字符串turn=“X”;
while(isGameOver(board).equals(“N”)){
System.out.println(转动+”移动:);
if(圈数等于(计算机)){
棋盘[randomPlayer.makeRandomMove(棋盘)]=计算机;
印制板();
}否则{
System.out.println(“轮到你了!”);
印制板();
makeMove(玩家);
}
System.out.println(“MINIMAX返回”+MINIMAX(线路板,转弯));//------------------------------------调试------------------
转弯=反向(转弯);
}
//游戏现在结束了。打印最后的棋盘
印制板();
字符串结果=isGameOver(板);
if(结果等信号情况(计算机)){
System.out.println(“计算机(“+Computer+”)获胜!万岁!”);
}else if(result.equalsIgnoreCase(“T”)){
System.out.println(“打成平局了!”);
}否则{
System.out.println(“人类(“+player+”)获胜!祝贺你!”;
}
}
公共静态无效打印板(){
对于(int i=0;i<3;i++){
对于(int j=0;j<3;j++){
系统输出打印(板[i*3+j]+“|”);
}
系统输出打印(“\n”);
}
System.out.print(“\n”);//用于间隔格式
}
公共静态字符串选择器片段(){
System.out.println(“你想扮演X还是O?(X是第一个)”;
弦段=in.nextLine();
而(!(件号等信号情况(“X”)| |件号等信号情况(“O”)){
System.out.println(“输入无效!请输入X或O:”);
工件=in.nextLine();
}
返回件.toUpperCase();
}
公共静态对弦(弦段){
if(piece.equalsIgnoreCase(“X”){返回“O”}
返回“X”;
}
公共静态字符串isGameOver(字符串[]b){//b用于线路板
/*字符串,因为我们可以同时传输游戏是否结束
*(只要游戏还没结束就清空),谁是赢家(通过使其与赢家的棋子相等),
*不管是不是领带(“T”代表领带)*/
对于(int i=0;i<3;i++){
//水平检查
如果(b[3*i].equals(b[3*i+1])&&b[3*i].equals(b[3*i+2])&&&b[3*i].equals(“”){
返回b[3*i];
}
//垂直检查
如果(b[i].equals(board[i+3])&&b[i].equals(b[i+6])&&&b[i].equals(“”){
返回b[i];
}
}
//对角检查
如果(b[0].等于(b[4])&&b[4].等于(b[8])&&&!b[0].等于(“”){
返回b[0];
}
如果(b[2]。等于(b[4])&&b[2]。等于(b[6])&&&!b[2]。等于(“”){
返回b[2];
}
//检查领带
for(int i=0;i8 | |!线路板[位置]。等于(“”){
System.out.println(“移动位置无效!请输入有效的移动位置1-9:”);
location=in.nextInt()-1;
}
板[位置]=件;
}
公共静态字符串[]makeNewMove(字符串片段,int位置)引发异常{
//与上述方法相同,但无输出或验证。仅供计算机使用
字符串[]newBoard=board.clone();
试一试{
新板【位置】=件;
}捕获(例外e){
System.out.println(“无效的计算机输入”);
}
返回新板;
}
公共静态ArrayList空点(字符串[]板){
//返回索引值为空(“”)的arraylist
ArrayList emptySpots=新的ArrayList();
对于(int i=0;ipackage TicTacToeAI;

import java.util.Random;
import java.util.ArrayList;

public class randomPlayer {
  public static int makeRandomMove(String[] board) {
    Random rand = new Random();
    ArrayList<Integer> availableSpots = new ArrayList<Integer>();
    for (int i = 0; i < board.length; i++) {
      if (!(board[i].equalsIgnoreCase("X") || board[i].equalsIgnoreCase("O"))) {
        availableSpots.add(i);
      }
    }
    return availableSpots.get(rand.nextInt(availableSpots.size()));
  }
}
for (int i = 0; i < availableSpots.size(); ++i) {
    int currSpot = availableSpots.get(i);
    board[currSpot] = currentPlayer;
    int temp = minimax(board, opposite(currentPlayer));
    board[currSpot] = " ";
    //the rest of the loop code
}