井字游戏中Minimax算法的错误

我目前正在自学Minimax算法,并尝试在井字游戏中用Java实现它。然而,我的算法中存在一个错误,我无法找出是什么原因导致的。

以下是完整的源代码(抱歉代码量有点大!):

public class TicTacToe {    private static boolean gameEnded = false;    private static boolean player = true;    private static Scanner in = new Scanner(System.in);    private static Board board = new Board();    public static void main(String[] args){        System.out.println(board);        while(!gameEnded){            Position position = null;            if(player){                position = makeMove();                board = new Board(board, position, PlayerSign.Cross);            }else{                board = findBestMove(board);            }                           player = !player;                System.out.println(board);                evaluateGame();        }    }    private static Board findBestMove(Board board) {        ArrayList<Position> positions = board.getFreePositions();        Board bestChild = null;        int previous = Integer.MIN_VALUE;        for(Position p : positions){            Board child = new Board(board, p, PlayerSign.Circle);            int current = max(child);            System.out.println("Child Score: " + current);            if(current > previous){                bestChild = child;                previous = current;            }        }        return bestChild;    }    public static int max(Board board){        GameState gameState = board.getGameState();        if(gameState == GameState.CircleWin)            return 1;        else if(gameState == GameState.CrossWin)            return -1;        else if(gameState == GameState.Draw)            return 0;        ArrayList<Position> positions = board.getFreePositions();        int best = Integer.MIN_VALUE;        for(Position p : positions){            Board b = new Board(board, p, PlayerSign.Cross);            int move = min(b);            if(move > best)                best = move;        }               return best;    }    public static int min(Board board){        GameState gameState = board.getGameState();        if(gameState == GameState.CircleWin)            return 1;        else if(gameState == GameState.CrossWin)            return -1;        else if(gameState == GameState.Draw)            return 0;        ArrayList<Position> positions = board.getFreePositions();        int best = Integer.MAX_VALUE;        for(Position p : positions){            Board b = new Board(board, p, PlayerSign.Circle);            int move = max(b);            if(move < best)                best = move;        }        return best;    }    public static void evaluateGame(){        GameState gameState = board.getGameState();        gameEnded = true;        switch(gameState){            case CrossWin :                 System.out.println("Game Over! Cross Won!");                break;            case CircleWin :                 System.out.println("Game Over! Circle Won!");                break;            case Draw :                 System.out.println("Game Over! Game Drawn!");                break;            default : gameEnded = false;                break;        }    }    public static Position makeMove(){        Position position = null;        while(true){            System.out.print("Select column(x-axis). 0, 1 or 2: ");            int column = getColOrRow();            System.out.print("Select row(y-axis). 0, 1 or 2: ");            int row = getColOrRow();            position = new Position(column, row);            if(board.isMarked(position))                System.out.println("Position already marked!");            else break;        }        return position;    }    private static int getColOrRow(){        int ret = -1;        while(true){            try{                ret = Integer.parseInt(in.nextLine());            } catch (NumberFormatException e){}            if(ret < 0 | ret > 2)                System.out.print("\nIllegal input... please re-enter: ");            else break;        }        return ret;    }}public enum PlayerSign{    Cross, Circle}public enum GameState {    Incomplete, CrossWin, CircleWin, Draw}public final class Position {    public final int column;    public final int row;    public Position(int column, int row){        this.column = column;        this.row = row;    }}public class Board {    private char[][] board; //e = empty, x = cross, o = circle.    public Board(){        board = new char[3][3];        for(int y = 0; y < 3; y++)            for(int x = 0; x < 3; x++)                board[x][y] = 'e'; //Board initially empty    }    public Board(Board from, Position position, PlayerSign sign){        board = new char[3][3];        for(int y = 0; y < 3; y++)            for(int x = 0; x < 3; x++)                board[x][y] = from.board[x][y];        board[position.column][position.row] = sign==PlayerSign.Cross ? 'x':'o';    }    public ArrayList<Position> getFreePositions(){        ArrayList<Position> retArr = new ArrayList<Position>();             for(int y = 0; y < 3; y++)            for(int x = 0; x < 3; x++)                if(board[x][y] == 'e')                    retArr.add(new Position(x, y));        return retArr;    }    public GameState getGameState(){            if(hasWon('x'))            return GameState.CrossWin;        else if(hasWon('o'))            return GameState.CircleWin;        else if(getFreePositions().size() == 0)            return GameState.Draw;        else return GameState.Incomplete;    }    private boolean hasWon(char sign){ //8 ways to win.        if(board[1][1] == sign){             if(board[0][0] == sign && board[2][2] == sign)                return true;            if(board[0][2] == sign && board[2][0] == sign)                return true;            if(board[1][0] == sign && board[1][2] == sign)                return true;            if(board[0][1] == sign && board[2][1] == sign)                return true;            }            if(board[0][0] == sign){                if(board[0][1] == sign && board[0][2] == sign)                    return true;                if(board[1][0] == sign && board[2][0] == sign)                    return true;            }            if(board[2][2] == sign){                if(board[1][2] == sign && board[0][2] == sign)                    return true;                if( board[2][1] == sign && board[2][0] == sign)                    return true;            }               return false;    }    public boolean isMarked(Position position){        if(board[position.column][position.row] != 'e')            return true;        return false;    }    public String toString(){        String retString = "\n";        for(int y = 0; y < 3; y++){            for(int x = 0; x < 3; x++){                if(board[x][y] ==  'x' || board[x][y] == 'o')                    retString += "["+board[x][y]+"]";                else                    retString += "[ ]";            }            retString += "\n";        }               return retString;    }   }

回答:

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注