【问题标题】:Brute force Card shake method in C#C#中的蛮力摇卡方法
【发布时间】:2012-07-24 06:32:43
【问题描述】:

我正在制作一个可以在游戏中测试一些卡牌战术的机器人,该机器人可以工作,但我有一个问题。我的抽卡方法不是很好。 我这样摇牌:

        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

我猜 Random 类对于像这样的蛮力来说还不够好。我怎样才能洗牌而不出现这样的问题?

更新: 我已经尝试过使用 1 个 Random 类,并且我也尝试过只摇一次牌。

【问题讨论】:

  • 有什么理由你还在使用ArrayList 而不是List&lt;T&gt;
  • 每次有人用ArrayList 编写新代码时,都会有一只小狗死去。
  • @pstrjds:嗯,它可能是一只小狗。它可能是一只小猫。它可能只是一个字符串。没有办法知道。当然,如果你有List&lt;Puppy&gt;,那就不一样了……
  • @JonSkeet A List 绝对是个坏主意。没有比拳击更能让猫开心的方法了!
  • @hometoast 该算法已经等同于 Fisher-Yates,除了它不是原地改组

标签: c# windows bots


【解决方案1】:

当您创建 Random 类的新实例时,它会使用当前时间播种,但当前时间的播种精度仅为 16 毫秒,这意味着如果您在与另一个实例相同的 16 毫秒间隔(对于计算机来说这是一个 时间),您将获得相同的随机数序列。

一个好的解决方案是确保您没有创建太多新的Randoms。创建一个,一次,然后将其传递给 shuffle cards 方法,或者创建一个在很多地方都可以访问的静态随机数(请记住它不是线程安全的)。

附带说明,对于您的实际洗牌算法,它非常好。不过,您可以进行一项改进。无需将所选元素添加到末尾并从中间删除,您只需将末尾的元素与中间的元素交换即可。这更有效,因为从 List 中间删除不是一个有效的操作。此外,不要在 0 和大小之间选择一个随机数,而是选择一个介于 0 和(大小减去当前迭代次数)之间的数字。有关该算法的更多详细信息,请参阅wikipedia article on the subject

【讨论】:

  • 已经试过了,有 1 个随机类它也会得到很多相同的值。
  • @user1201889:因为这与您当前所做的没有什么不同。您正在创建一堆具有相同种子的随机对象,因此它们返回相同的序列。创建一次 Random 对象并使用它,直到您的应用程序退出(或当类完成它时)。使其成为类级别的变量。
【解决方案2】:

拥有 2 个随机类并为其中一个生成种子并不能提高随机性。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-11
    • 1970-01-01
    相关资源
    最近更新 更多