【问题标题】:Randomly distributing cards with constraints随机分配有约束的卡片
【发布时间】:2014-04-05 01:24:29
【问题描述】:

我正在开发一款纸牌游戏 AI。

玩家只知道自己的牌,需要将看不见的牌随机分配给对手。

一些对手将有 0% 的机会拥有一些牌(这是必须的)。

对手比其他人更有可能拥有一些牌(这很好,但我的主要问题是解决之前提出的情况)。

现在的问题是这种卡片分配必须在很短的时间内发生很多次,所以随机分配它直到 0% 机会的卡片不在有 0% 机会拥有它们的对手手中不可行。

如果我想解决这个问题,你会建议什么方法:

  1. 确保没有对手有一张他有 0% 几率拥有的牌,同时确保其他牌均匀分布(并且另一个对手将拥有这张牌)

  2. (在某些玩家有 10%、40% 等的机会拿到牌的情况下)

    确保卡片根据其重量分布。 例如:玩家必须选择 3 张牌,他有 2% 的机会拥有 A、K 或 Q,所以他不能只有这 3 张牌可供选择(他最终可能会得到 n 个不同花色的高牌)

如果您能帮我解决第 1 种情况(用任何语言,或者指点我一个算法),我会非常感激。

谢谢!

编辑:我应该澄清一下,虽然一些对手可能有 0% 的机会拥有一张牌,但其他对手可能有正常的机会拥有它们(而且肯定有人必须拥有它)。

EDIT2:这意味着如果我们继续随意分发卡片,我们最终可能只会得到最后一个玩家拿走的禁止卡片(这不可能发生)。

【问题讨论】:

  • 如果有 0% 的机会拥有一张特定的卡片,请从分发中删除该卡片。您仍然可以在用户界面中声明一副牌中有 52 张牌。但是,如果说其中有 5 张牌永远无法使用,那么你实际上只有 47 张牌在牌组中。至少,当您分发时,您只能从 52 张卡片中选择要分发的卡片。 (类似于cards.Where(c => c.Probability > 0)
  • @David:我编辑澄清。这种情况是在我们知道一个对手没有给定花色而其他人 100% 肯定有花色时分配牌。
  • 顺便说一句,您是使用现有的手部评估器还是自己编写的?
  • @AShelly:我没有使用手部评估器,我使用 ISMCTS 来模拟游戏并在达到残局时查看最终得分。
  • 你仍然是一个评估者,要牵手弄清楚谁赢了,不是吗?

标签: c# performance random probability


【解决方案1】:

我在另一个网站上发现了一个类似的问题,但它实际上并没有得到关于如何解决我的问题的简单部分的答案。

如果其他人有兴趣,链接是:

https://math.stackexchange.com/questions/220606/n-piles-of-hidden-cards-of-known-marginal-probability-distribution-then-a-card

编辑: 我最终利用一些没有花色的对手的限制来分配所有的牌。当一个对手没有他可以选择的牌时,他会尝试从牌堆中交换一张他没有用的牌,而另一个对手可以拿走这张牌。作为交换,那个对手给了他一张他可以拿的牌。这不是最好的解决方案,但在 99.9% 的情况下都有效。

【讨论】:

    【解决方案2】:

    对于 #1,如果您将一张“禁止”牌发到手上,只需将其洗回牌组即可。
    对于#2,您可能可以使用"Cumulative Distribution Function"

    我认为this question 可能是相关的。

    【讨论】:

    • 问题是我们最终可能会在牌组中只有被禁止的牌供最后一名玩家选择。
    • 按限制最多到最少的顺序进行交易。如果这副牌真的是随机洗牌,那么给玩家 A 5 张牌,然后给 B 5 张牌等与循环发牌没有统计差异。
    • 这可能是朝着正确方向迈出的一步,但仍然存在一些边缘情况,即您没有牌可发。这是一个有点困难的问题! (两个人可以拿 2 个花色,他们拿走了可以拿 3 个花色的人需要的所有牌,因为他们拿了太多的一种花色)
    【解决方案3】:
    1. 确保没有人拥有他有 0% 机会拥有的卡,同时确保其他人平均分配

    要使某些牌的发牌几率为 0%,只需将这些牌作为选项移除即可。例如

    IList<int> cardOptions = Enumerable.Range(1, 52).ToList();
    // all 52 cards in this deck represented as integers
    // remove some:
    cardOptions.Remove(5);
    cardOptions.Remove(42);
    // when you randomly select from cardOptions,
    // each remaining card has a 1/50 probability of being chosen
    

    2.(在某些玩家有 10%、40% 等的机会拿到牌的情况下)

    确保卡片根据其重量分布。例如:玩家必须选择 3 张牌,他有 2% 的机会拥有 A、K 或 Q,这是他唯一可以选择的牌(从 2 种不同的花色中选择)

    这听起来与typical weighted random 分发不同。您可以执行以下操作(伪代码):

    double probabilityOfHavingCertainCard = 0.4;
    int thatCard = 52;
    if (randomDoubleBetween0and1 < probabilityOfHavingCertainCard)
        cardResults.Add(thatCard);
    
    cardOptions.Remove(thatCard);
    while (cardResults.Count < 5)
        cardResults.Add(random from cardOptions, not previously chosen);
    

    也就是说,它将加权卡视为一种特殊情况,而不是普通洗牌的一部分。

    【讨论】:

    • 我更改了您第一个引用中的文字以使其更加明确。第二个不会那么容易工作,因为我们最终可能只会得到最后一个玩家有 0% 机会拥有的牌,所以他不能拥有它们。
    猜你喜欢
    • 2018-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-06
    • 2014-12-08
    • 2016-08-25
    • 2023-03-29
    • 2013-08-29
    相关资源
    最近更新 更多