简体   繁体   English

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

[英]Randomly generating from a dictionary and returning the key and value

This is a 2 part question, I am making a blackjack game and I am trying to randomly generate a key and value (KEY = string(card value eg Hearts2), And VALUE = int (Score for that specific card value)), and I would like to try and return the key and value. 这是一个分为两部分的问题,我正在制作二十一点游戏,并且尝试随机生成一个键和值(KEY =字符串(卡值,例如Hearts2),而VALUE = int(该特定卡值的分数)),以及我想尝试返回键和值。

I have a deck, dealer and player class. 我有一个套牌,发牌人和玩家类。 My Deck class has 2 methods, Deck() and Shuffel(), deck() is used to create the deck and shuffle90 well shuffles the deck(). 我的Deck类有2种方法,Deck()和Shuffel(),deck()用于创建甲板,并且shuffle90很好地洗牌了deck()。 I would like to send the random card to the dealer class to deal the cards. 我想将随机卡片发送给发牌者类别以处理卡片。 I am not sure if it is possible to return the key and value so the dealer class method (dealCards()) can receive a string and int as parameters. 我不确定是否可以返回键和值,以便发牌人类方法(dealCards())可以接收字符串和int作为参数。

Also I found a way to randomize my dictionary but it is returning the entire dictionary randomized, but I only need one card to be returned. 我也找到了一种使我的字典随机化的方法,但是它将随机返回整个字典,但是我只需要退回一张卡即可。

This is what I have so far for the Deck class... 这是我到目前为止为Deck班所拥有的...

This is my 这是我的

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;
}

As you can see I created 2 simple arrays and used for loops to iterate through them and add them to the dictionary. 如您所见,我创建了2个简单的数组,并用于循环遍历它们并将它们添加到字典中。

The last two lines, the first is declaring a new dictionary to hold the random card and reciving its value from the Shuffle() method,(is posted bellow) and I would like to know if there is a way to return ranCard.Key, ranCard.Value ? 最后两行,第一行是声明一个用于容纳随机卡的新字典,并从Shuffle()方法接收它的值(已在下面显示),我想知道是否有一种方法可以返回ranCard.Key, ranCard.Value so I can have my Dealer class method like this ( dealCard(string card, int score) )? 所以我可以有像这样的Dealer类方法( dealCard(string card, int score) )?

This is my Shuffle() method for my Deck class... 这是我的Deck类的Shuffle()方法...

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;
}

Now with this method The entire dictionary is randomized and I would like to just return one randome value if possible. 现在,使用这种方法,整个字典是随机的,如果可能的话,我只想返回一个randome值。 I tried to remove the parameters in the r.Next(**) but still the same. 我试图删除r.Next(**)中的参数,但仍然相同。

I am using vs2012. 我正在使用vs2012。

There are several issues here: 这里有几个问题:

  • Dictionaries aren't ordered - so the order in which the cards come out of OrderBy may not be reflected when you iterate over the dictionary later. 字典没有排序-因此,当您以后遍历字典时,可能不会反映出卡片从OrderBy出来的顺序。 I believe in the current implementation it may happen to do that, but fundamentally you shouldn't rely on it. 我相信,在目前的实现,可能会发生这样做,但你根本不应该依赖于它。
  • Your way of shuffling isn't good anyway - it's likely to make early items stay early, as if there are two items which get the same random "key", the earlier one will be emitted first. 无论如何,您的改组方式都不是很好-可能会使早期项目保留得早,就像有两个项目具有相同的随机“键”一样,较早的项目将首先发出。 Consider using a variant of a Fisher-Yates shuffle - there are several examples on SO, such as this one . 考虑使用Fisher-Yates改组的变体-SO上有几个示例,例如this
  • Your approach to keeping the card and score together as a dictionary key/value pair feels awkward to me... if you avoid that, you'll find a lot of other things drop out. 您将卡片与字典键/值对保持在一起并得分的方法对我来说很尴尬...如果避免这种情况,您会发现很多其他问题。

Basically, a deck of cards isn't a dictionary - it's a sequence of cards . 基本上,一副纸牌不是字典,而是一连串的纸牌 So you should be modelling a card: 因此,您应该对卡片进行建模:

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

How you choose to represent the face value and suit are up to you, but you should consider using enums given that there are natural sets of valid values here. 您如何选择代表面值和衣服的方式取决于您,但是鉴于此处存在自然的有效值集,因此您应该考虑使用枚举。

Once you've got a deck as a List<Card> (or a Queue<Card> ), you can easily shuffle that, and then just deal Card values to players. 一旦获得了List<Card> (或Queue<Card> )的套牌,就可以轻松地将其洗牌,然后将Card值分配给玩家。

First things first. 首先是第一件事。

The game rules require that you have state. 游戏规则要求您拥有状态。 What I mean is that you don't have a stateless random return value, but you MUST retain the state across the generation of random values, as the probabilities change. 我的意思是,您没有无状态的随机返回值,但是随着概率的变化,您必须在生成随机值时保留状态。 In layman's terms: you can't draw the same card more than n times because the game rules specify how the deck is composed. 用外行的话来说:同一张牌最多可以绘制n次,因为游戏规则指定了卡片组的组成方式。

That said, it is clear that one way or another you have to keep track of the cards in the deck. 也就是说,很明显,您必须以一种或另一种方式跟踪卡组中的卡。 In your code you shuffle the whole deck and return that. 在您的代码中,您将整个卡组洗牌并返回。 All you need now is an object that wraps it and keeps internally its state, like so: 现在您需要的只是一个包装它并在内部保持其状态的对象,如下所示:

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;
    }
}

There are many more ways to implement this, at least another 2 come to my mind, but the result is just the same. 还有很多方法可以实现这一点,我想至少还有另外两种,但是结果是一样的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM