0

私はリバーシ/オセロ ゲームで 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 である WHITE に変更されて動きます。ツリー内で最適な動きを検索してから、1 つの動きを実行する必要があります。代わりに、いくつかの奇妙な動きを実行します。ブランチごとにボードの新しいコピーを作成する理由がわからないので、メインのゲームボードが変更される理由がわかりません。

何か案は?

4

1 に答える 1

2

オブジェクトのコピーを変更するとオリジナルに影響する場合。それが「浅いコピー」です。これは、データ構造オブジェクトのどこかが共有されていることを意味します。「ディープコピー」が必要です。

のコードを表示してくださいnew GameBoard(gb)

いくつかのオプション: ゲームボードとそれに含まれる (およびそれらに含まれる) すべてのオブジェクトのクローンを実装できます。または、ゲーム ボードに undo() 関数を実装します。ゲームボードのすべての動きを取り消す限り、その上で動きを実行できます。これにより、評価中にテスト移動を行うときに、メモリとオブジェクト作成のオーバーヘッドが節約されます..

于 2013-12-06T18:15:42.077 に答える