C#中的暴力卡摇动方法

Lau*_*nce 5 c# windows bots

我正在制作一个机器人,可以在游戏中测试一些卡片策略,机器人可以工作,但我有一个问题.我的卡摇法不是很好.我这样摇动卡片:

        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; 
        }
Run Code Online (Sandbox Code Playgroud)

问题是,当我计算卡片震动过程之间没有暂停时,一些玩家将赢得很多游戏.例如

Player 1: 8 games
Player 2: 2 games
Player 3: 0 games
Player 4: 0 games
Run Code Online (Sandbox Code Playgroud)

但是当我在卡片摇动过程之前添加一个对话框时,胜利将分散在玩家身上:

Player 1: 3 games
Player 2: 2 games
Player 3: 1 game
Player 4: 4 games
Run Code Online (Sandbox Code Playgroud)

我猜那个随机类对于像这样的蛮力来说还不够好.如何在没有这样的问题的情况下洗牌?

更新:我已经尝试使用1个随机类,我也试过只摇一次卡.

Ser*_*rvy 10

当你创建一个Random类的新实例时,它会以当前时间播种,但是它所播种的当前时间只有16 ms的精度,这意味着如果你Random在相同的16毫秒间隔内创建一个新类(那很长一段时间)对于计算机而言,作为另一个实例,您将获得相同的随机数序列.

一个好的解决方案就是确保你没有创造出这么多新东西Randoms.创建一个,一次,并将其传递到shuffle卡方法,或创建一个只能在很多地方访问的静态随机(只记得它不是线程安全的).

另外,对于你的实际改组算法,它非常好.你可以做一个改进.您可以将末尾的元素与中间的元素交换,而不是将所选元素添加到末尾并从中间删除它.这样更有效,因为从List中间删除不是一种有效的操作.此外,不是选择介于0和大小之间的随机数,而是选择介于0和(大小减去当前迭代次数)之间的数字.有关该算法的更多详细信息,请参阅有关该主题维基百科文章.

  • @ user1201889:因为这与你目前正在做的没什么不同.您正在创建一组具有相同种子的随机对象,因此它们返回相同的序列.创建Random对象一次并使用它,直到您的应用程序退出(或类完成时).使它成为一个类级变量. (3认同)