井字游戏中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

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

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