C#中的暴力卡摇动方法

时间:2012-07-25 18:32:11

标签: 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; 
        }

问题在于,当我在卡片震动过程中没有暂停计算时,一些玩家将赢得很多游戏。例如

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个随机课程,而且我也试过只摇一次卡片。

2 个答案:

答案 0 :(得分:10)

当您创建Random类的新实例时,它将以当前时间播种,但其播种的当前时间仅为16毫秒,这意味着如果您创建新的{{1}在相同的16毫秒间隔内(类似于计算机的时间)的类,作为另一个实例,您将获得相同的随机数序列。

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

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

答案 1 :(得分:4)

拥有2个随机类并为另一个生成种子并不会改善随机性。

然后,不要在ShuffelCards中创建Random类。在ShuffelDeck中创建它并将其传递给ShuffelCards,或使其成为该类的成员。这应该有所帮助。