MiniMax可逆实现



我正试图在《逆转/奥赛罗》游戏中实现一个MiniMax算法,但我被卡住了,因为我编写的函数看起来非常正常,但我遇到了一些奇怪的动作,几次之后就崩溃了。以下是找到最佳移动的函数:

public Field findBestMove(GameBoard gb, int depth, int player) 
{       
    if(depth >= max_depth) return null;
    ArrayList <Field> moves = findAllPossibleMoves(gb, player);
    Field best_move = null;
    /** iterating over all possible moves, to find the best one */
    for (int i=0; i<moves.size(); i++)
    {
        /* board to simulate moves */
        GameBoard temp_board = new GameBoard(gb);
        Field move = moves.get(i);
        game.move(move, temp_board, player);
        int opposite_player = player == GameBoard.WHITE ? GameBoard.BLACK : GameBoard.WHITE;
        Field best_deep_move = findBestMove (temp_board, depth + 1, opposite_player);
        /** if the maximum depth is reached, we have a null, so we evaluate */
        if (best_deep_move == null)
        {
            /** we rate it according to the evaluation table */
            move.setRating(evaluate (temp_board, player));
        }
        else
        {
            move.setRating(best_deep_move.getRating());
        }
        if(best_move == null)
        {
            best_move = move;
        }
        else
        {   
            if (depth%2==0)
            {
                /** for us, we look for the maximum */
                if (best_move.getRating() < move.getRating()) best_move = move;
            }
            else
            {
                /** for the opponent, we look for the minimum */
                if (best_move.getRating() > move.getRating()) best_move = move;
            }
        }
    }
    return best_move;
}

每次移动后,激活的玩家都会发生变化。在GameView的onTouchEvent方法中,首先玩家进行移动,然后玩家被换成白色的AI,它进行移动。它应该在他的树上搜索最好的动作,然后执行一个动作,相反,他会做几个奇怪的动作。我不知道为什么,我为每个分支创建一个新的棋盘副本,所以我不知道主游戏棋盘为什么会被修改。

有什么想法吗?

如果更改对象的副本会影响原始副本。那么它就是一个"肤浅的复制品"。这意味着数据结构中的某个地方的对象是共享的。你想要一个"深度复制"。

给我们看new GameBoard(gb) 的代码

一些选项:你可以为你的游戏板和它包含的所有对象(以及它们包含的)实现克隆。或者,在游戏板中实现一个undo()函数。只要你撤消游戏板上的每一个动作,你就可以在上面执行动作。这将在评估过程中进行测试动作时节省内存和对象创建开销。。

相关内容

  • 没有找到相关文章

最新更新