5

ゲームでいくつかのカード戦術をテストできるボットを作成しています。ボットは機能しますが、問題が 1 つあります。私のカードシェイク方法はあまり良くありません。私はこのようにカードを振る:

        public void ShuffelDeck()
        {
            for (int i = 0; i < 5; i++)
                Cards = ShuffelCards(Cards);
        }

        private ArrayList ShuffelCards(ArrayList Cards)
        {
            ArrayList ShuffedCards = new ArrayList();

            Random SeedCreator = new Random();
            Random RandomNumberCreator = new Random(SeedCreator.Next());

            while (Cards.Count != 0)
            {
                int RandomNumber = RandomNumberCreator.Next(0, Cards.Count);
                ShuffedCards.Insert(ShuffedCards.Count, Cards[RandomNumber]);
                Cards.RemoveAt(RandomNumber);
            }

            return ShuffedCards; 
        }

問題は、カード シェイク プロセスの間に一時停止せずに計算すると、少数のプレイヤーが多くのゲームに勝つことです。例えば

Player 1: 8 games
Player 2: 2 games
Player 3: 0 games
Player 4: 0 games

しかし、カード シェイク プロセスの前にダイアログを追加すると、勝利がプレイヤーに分散されます。

Player 1: 3 games
Player 2: 2 games
Player 3: 1 game
Player 4: 4 games

ランダムクラスは、このようなブルー​​トフォースには十分ではないと思います. このような問題なくカードをシャッフルするにはどうすればよいでしょうか?

更新: 私はすでに 1 つのランダム クラスを使用しようとしました。また、カードを 1 回だけ振ろうとしました。

4

2 に答える 2

10

クラスの新しいインスタンスを作成するRandomと、現在の時刻がシードされますが、シードされる現在の時刻の精度は 16 ミリ秒までしかありRandomませ。コンピューターの場合) 別のインスタンスとして、同じ乱数シーケンスを取得します。

良い解決策の 1 つは、新しい をあまり作成しないようにすることですRandoms。一度作成してシャッフル カード メソッドに渡すか、多くの場所でアクセス可能な静的ランダムを作成します (スレッド セーフではないことに注意してください)。

補足として、実際のシャッフル アルゴリズムについては、かなり優れています。ただし、1 つの改善を行うことができます。選択した要素を最後に追加して中央から削除するのではなく、最後にある要素を中央にある要素と交換するだけです。リストの途中からの削除は効率的な操作ではないため、これはより効率的です。さらに、0 とサイズの間の乱数を選択するのではなく、0 と (サイズから現在の反復回数を引いた値) の間の数値を選択します。アルゴリズムの詳細については、件名に関するウィキペディアの記事を参照してください。

于 2012-07-25T18:45:47.973 に答える
4

2 つの Random クラスがあり、一方のシードをもう一方のクラスで生成しても、ランダム性は向上しません。

次に、ShuffelCards 内に Random クラスを作成しないでください。ShuffelDeck で作成し、ShuffelCards に渡すか、クラスのメンバーにします。これは役立つはずです。

于 2012-07-25T18:46:08.533 に答える