Java - Minimax数值Tic Tac Toe Bug算法

时间:2016-05-05 17:08:51

标签: java algorithm libgdx minimax

我遇到了一个算法问题,我试图将其作为大学的作业来实现。我正在制作tic tac toe的数字版本。我的讲师给了我们班级他的标准游戏的Minimax算法版本,我们现在必须实现这个数字tic tac toe。他的标准实施如下:

public class MinimaxPlayer extends BasePlayer {

private Random randomGenerator;

public MinimaxPlayer(Board board, int symbol) {
    super(board, symbol);
    name = "MinimaxPlayer";

    skill = 5;  // skill is measure of search depth

    randomGenerator = new Random();
}

@Override
public int move () {
    return (int) minimax(mySymbol, opponentSymbol, 0);
}

private float minimax(int p_mySymbol, int p_opponentSymbol, int depth) {

    final float WIN_SCORE = 100;        
    final float DRAW_SCORE = 0;

    float score;
    float maxScore = -10000;
    int maxPos = -1;

    // for each board position
    for (int r=0; r<3; ++r) {
        for (int c=0; c<3; ++c) {

            // skip over used positions
            if (board.cells[r][c]!=board.EMPTY) continue;

            String indent = new String(new char[depth]).replace("\0", "  ");
            //Gdx.app.log(indent, "search ("+r+","+c+")");

            // place move 
            board.cells[r][c] = p_mySymbol;

            // evaluate board (recursively)
            if (board.hasWon(p_mySymbol, r, c)) {
                score = WIN_SCORE;
            } else if (board.isDraw()) {
                score = DRAW_SCORE;
            } else {
                if (depth<skill) {
                    score = -minimax(p_opponentSymbol, p_mySymbol, depth+1);
                } else {
                    score = 0;
                }
            }

            // update ranking

            if (Math.abs(score-maxScore)<1.0E-5 && randomGenerator.nextDouble()<0.1) {
                maxScore = score;
                maxPos = 3*r+c;

            } else if (score>maxScore) {    // clear 
                maxScore = score;
                maxPos = 3*r+c;
            } 

            //Gdx.app.log(indent, "Score "+score);

            // undo move 
            board.cells[r][c] = board.EMPTY;

        }
    }

    // on uppermost call return move not score
    return (depth==0? maxPos : maxScore);

};

}

我现在正在尝试调整此代码以适应我的数字tic tac toe游戏。到目前为止,我有这个:

public class MinimaxPlayer extends BasePlayer {

private Random randomGenerator;
//change constructor to take skill levels for depth search.
public MinimaxPlayer(Board board, Symbol symbol,int depth) {
    super(board, symbol);
    name = "MinimaxPlayer";

    // skill is measure of search depth
    skill = depth;

    randomGenerator = new Random();
}

@Override
public int move () {
    return  (int) minimax(board.currentPlayer.numbers, board.currentPlayer.opponent.numbers, 0);
}

private float minimax(List<Integer> myNumbers, List<Integer> opponentNumbers, int depth) {

    final float WIN_SCORE = 100;        
    final float DRAW_SCORE = 0;

    float score;
    float maxScore = -10000;
    int maxPos = -1;

    // for each board position
    for (int r=0; r<3; ++r) {
        for (int c=0; c<3; ++c) {
            for(Integer number : myNumbers){
                // skip over used positions
                if (board.cells[r][c]!=board.EMPTY) continue;

                // place move 
                board.cells[r][c] = number;
                System.out.println("Number placed :" + number);


                // evaluate board (recursively)
                if (board.hasWon(number, r, c)) {
                    score = WIN_SCORE;
                    System.out.println("This move has won with score: "+ score);
                } else if (board.isDraw()) {
                    score = DRAW_SCORE;
                    System.out.println("this move is a draw and score is: " + score);
                } else {
                    System.out.println("Depth is now: " + depth);
                    if (depth<skill) {
                        score = -minimax(opponentNumbers, myNumbers, depth+1);
                    } else {
                        score = 0;
                    }
                }

                System.out.println("Made it to update rankings");
                // update ranking
                if (Math.abs(score-maxScore)<1.0E-5 && randomGenerator.nextDouble()<0.1) {
                    currentNumber = number;
                    maxScore = score;
                    maxPos = 3*r+c;

                } else if (score>maxScore) {    // clear 
                    currentNumber = number;
                    maxScore = score;
                    maxPos = 3*r+c;
                } 

                //Gdx.app.log(indent, "Score "+score);
                System.out.println("Undone move");
                // undo move 
                board.cells[r][c] = board.EMPTY;
            }

        }
    }
    System.out.println("Depth:" + depth);
    System.out.println("MaxScore:" + maxScore);
    System.out.println("MaxPosition: "+ maxPos);
    // on uppermost call return move not score
    return (depth==0 ? maxPos : maxScore);

};

代码非常简单,我将算法参数替换为我可以玩的剩余数字以及我们可以玩的对手数字,并通过尝试每个棋盘位置中的每个数字递归尝试获得最佳移动给它一个分数。这同样适用于对手。然而,这个代码以无限循环结束,我发现很难调试,因为我是Libgdx的新手,因此打印到控制台。我认为问题是需要更改递归函数的基本情况,但我不太确定,如果你能指出我如何循环播放玩家数字并给予他们,我将不胜感激最好的位置和我写的地方&#39; currentNumber = number&#39;请注意,每个玩家都有一个当前号码,该号码是在玩板上的号码之前设置的,因为游戏具有拖放功能。所以在算法中的某个地方我需要将玩家数量设置为最佳数量。关于如何修复无限循环的一些指导和建议将非常感谢!

0 个答案:

没有答案