Произвольная генерация из словаря и возврат ключа и значения

1

Это вопрос из 2 частей, я делаю игру в блэкджек, и я пытаюсь случайным образом генерировать ключ и значение (KEY = строка (значение карты, например Hearts2), и VALUE = int (оценка для этой конкретной стоимости карты)) и Я хотел бы попытаться вернуть ключ и значение.

У меня есть класс колоды, дилера и игрока. Класс My Deck имеет 2 метода: Deck() и Shuffel(), deck() используется для создания колоды, а shuffle90 хорошо перемещает колоду(). Я хотел бы отправить случайную карточку в класс дилера, чтобы разобрать карты. Я не уверен, что можно вернуть ключ и значение, чтобы метод класса торгов (dealCards()) мог получить строку и int в качестве параметров.

Также я нашел способ рандомизировать мой словарь, но он возвращает весь словарь рандомизированным, но мне нужна только одна карта, которую нужно вернуть.

Это то, что я имею до сих пор для класса Deck...

Это мой

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? поэтому я могу использовать метод класса Dealer (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 ответа

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

Есть еще много способов реализовать это, по крайней мере, еще 2 пришли мне на ум, но результат тот же.

  • 0
    Это очень хороший пример, спасибо, но я должен сохранить словарь в своем классе колод, который я заменяю на класс карт, или также сохранить его в виде списка?
  • 0
    Если вам нужен список внутри класса, сохраните также список, но вам придется управлять им соответствующим образом. Если вы можете обойтись без вас, может быть лучше не иметь список. Помните, что вы должны держать его рядом со словарем и «в тайне», потому что это деталь реализации и не должна быть представлена остальной части приложения. Таким образом, вы можете позже изменить реализацию, не ставя под угрозу другие классы.
1

Здесь есть несколько вопросов:

  • Словари не упорядочены - поэтому порядок, в котором карты выходят из OrderBy может не отображаться, когда вы позже перебираете словарь. Я считаю, что в нынешней реализации это может произойти, но в принципе вы не должны полагаться на это.
  • В любом случае, ваш способ перетасовки - это нехорошо - скорее всего, ранние предметы будут оставаться на ранней стадии, как будто есть два предмета, которые получают один и тот же случайный "ключ", первый из которых будет выпущен первым. Подумайте об использовании варианта Shuffle Fisher-Yates - на SO есть несколько примеров, таких как этот.
  • Ваш подход к сохранению карты и счету в качестве пары слова/значения слова для меня чувствует неудобство... если вы этого не сделаете, вы обнаружите, что многое другое выпадает.

В принципе, колода карт - это не словарь - это последовательность карт. Поэтому вы должны моделировать карту:

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

Как вы решаете представить номинал и костюм, зависит от вас, но вы должны подумать об использовании перечислений, учитывая, что здесь есть естественные наборы действительных значений.

После того, как у вас есть колода в виде List<Card> (или в Queue<Card>), вы можете легко перетасовать это, а затем просто Card значения Card игрокам.

  • 0
    Привет, Джон, где было бы лучшее место для подсчета очков? в классе карт, после того как случайная карта была выбрана из списка <>, затем рассчитать ее счет и вернуть случайную карту и ее счет дилеру?
  • 1
    @JodyStocks: Если это естественная часть одной карты (основанная только на атрибутах карты), то сама карта может это сделать.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню