从字典中随机生成并返回键和值

时间:2014-08-22 09:11:17

标签: c#

这是一个2部分的问题,我正在进行二十一点游戏,我正在尝试随机生成一个键和值(KEY =字符串(卡片值,例如Hearts2),而VALUE = int(该特定卡片值的分数) ),我想尝试返回密钥和值。

我有一个套牌,经销商和球员类。我的Deck类有2个方法,Deck()和Shuffel(),deck()用于创建甲板,shuffle90可以很好地改组甲板()。我想将随机卡发送到经销商类来处理卡片。我不确定是否可以返回键和值,因此经销商类方法(dealCards())可以接收字符串和int作为参数。

此外,我找到了一种随机化我的字典的方法,但它将整个字典随机返回,但我只需要返回一张卡片。

这是我到目前为止甲板课程的目的......

这是我的

public static Dictionary<string, int> deck()
{
    string[] Suite = new string[4] { "Spades", "Clubs", "Hearts", "Diamonds" };
    string[] FaceValue = new string[13] { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K" };
    int score;

    Dictionary<string, int> deckOfCards = new Dictionary<string, int>();

    for (int s = 0; s < 4; s++)
    {
        string sute = Suite[s];

        for (int f = 0; f < 13; f++)
        {
           string fV = FaceValue[f];

            if (f == 0)
            {
                score = 0;
            }
            else if (f >= 9)
            {
                score = 10;
            }
            else
            {
                score = (f + 1);
            }

            string card = (sute + fV);

            deckOfCards.Add(card, score);
        }
    }


    Dictionary<string, int> ranCard = deckOfCards.Shuffle();

    return ranCard;
}

正如您所看到的,我创建了2个简单数组并用于循环迭代它们并将它们添加到字典中。

最后两行,第一行是声明一个新的字典来保存随机卡并从Shuffle()方法中恢复它的值(发布在下面),我想知道是否有办法返回ranCard.Key, ranCard.Value?所以我可以使用这样的经销商类方法(dealCard(string card, int score))?

这是我的Shuffle()类的Deck方法...

public static Dictionary<TKey, TValue> Shuffle<TKey, TValue>(this Dictionary<TKey, TValue> Cards)
{
    Random r = new Random();
    Cards = Cards.OrderBy(x => r.Next(0, Cards.Count)).ToDictionary(item => item.Key, item => item.Value);
    return Cards;
}

现在使用此方法整个字典是随机的,我想尽可能返回一个randome值。 我试图删除r.Next(**)中的参数但仍然相同。

我正在使用vs2012。

2 个答案:

答案 0 :(得分:1)

这里有几个问题:

  • 字典不是有序的 - 因此,当您稍后迭代字典时,可能无法反映出来自OrderBy的卡的顺序。我相信当前的实现可能发生来做到这一点,但从根本上说你不应该依赖它。
  • 无论如何,你的洗牌方式并不好 - 它可能会使早期物品保持早期,好像有两个物品获得相同的随机“钥匙”,较早的物品将首先发出。考虑使用Fisher-Yates shuffle的变体 - 在SO上有几个例子,例如this one
  • 你把卡片和乐谱作为字典键/值对保持在一起的方法对我来说感觉很尴尬......如果你避免这种情况,你会发现很多其他的事情都会消失。

基本上,一副纸牌不是字典 - 它是一系列。所以你应该为卡片建模:

public sealed class Card
{
    // Fields for face value and suit, and a property to compute the score
}

你如何选择代表面值和套装取决于你,但你应该考虑使用枚举,因为这里有自然的有效值集。

一旦你将牌组作为List<Card>(或Queue<Card>),你可以轻松地将其改组,然后将Card值交给玩家。

答案 1 :(得分:1)

首先要做的事情。

游戏规则要求您拥有州。我的意思是你没有无状态的随机返回值,但随着概率的变化,你必须保持随机值生成的状态。通俗地说:你不能在 n 次以上绘制同一张牌,因为游戏规则规定了牌组的组成方式。

也就是说,很明显,你必须以这种或那种方式跟踪卡片中的牌。在你的代码中,你将整个套牌洗牌并返回。你现在需要的只是一个包装它并在内部保持其状态的对象,如下所示:

class Dealer
{
    private List<Card> shuffledCards; // keep state of the current shuffle

    public Dealer(...)
    {
        shuffledCards = Shuffle(...); // use your method to get the shuffled cards
    }

    public Card Deal() // remove the first card from the deck and hand it out
    {
        Card c;

        c = shuffledCards[0];
        shuffledCards.RemoveAt(0);

        return c;
    }
}

还有很多方法可以实现这一点,至少还有另外两种方法,但结果却是一样的。