• 0

Having problems understanding how Dictionary is working in this program


Question

The Form has 4 classes Card, Deck , Player and Game, game being the class that runs everything

The form has 3 TextBox named textName, textBooks and textProgress , ListBox named listHand, 2 buttons named buttonStart and buttonAsk

 

Card

class Card
    {
        public Values Value { get; set; }
        public Suits Suit {get; set;}

    public Card (Suits suit, Values value)
    {
        this.Suit = suit;
        this.Value = value;
    }
    public string Name
    {
        get { return Value.ToString() + " of " + Suit.ToString(); }
    }
    public override string ToString()
    {
        return Name;
    }
       
            public static string Plural(Values value)
            {
                if (value == Values.Six)
                    return "Sixes";
                else
                    return value.ToString() + "s";
            }
        
    }
  

    enum Suits
    {
        Spades,
        Clubs,
        Hearts,
        Diamonds,
    }
    enum Values
    {
        Ace = 1,
        Two = 2,
        Three = 3,
        Four = 4,
        Five = 5,
        Six = 6,
        Seven = 7,
        Eight = 8,
        Nine = 9,
        Ten = 10,
        Jack = 11,
        Queen = 12,
        King = 13,
    }

 

Deck

 class Deck
    {
        private List<Card> cards;
        private Random random = new Random();

        public Deck()
        {
            cards = new List<Card>();
            for (int suit = 0; suit <= 3; suit++)
                for (int value = 1; value <= 13; value++)
                    cards.Add(new Card((Suits)suit, (Values)value));

        }
        public Deck(IEnumerable<Card> initialCards)
        {
            cards = new List<Card>(initialCards);
        }
        public int Count { get { return cards.Count; } }
        public void Add(Card cardToAdd)
        {
            cards.Add(cardToAdd);
        }

        public Card Deal(int index)
        {
            Card CardToDeal = cards[index];
            cards.RemoveAt(index);
            return CardToDeal;
        }
        public void Shuffle()
        {
            List<Card> NewCards = new List<Card>();
            while(cards.Count > 0)
            {
                int CardToMove = random.Next(cards.Count);
                NewCards.Add(cards[CardToMove]);
                cards.RemoveAt(CardToMove);
            }
            cards = NewCards;
        }
        public IEnumerable<string> GetCardNames()
        {
            string[] CardNames = new string[cards.Count];
            for (int i = 0; i < cards.Count; i++)
                CardNames[i] = cards[i].Name;
            return CardNames;
        }
        public void Sort()
        {
            cards.Sort(new CardComparer_bySuit());
        }
        public Card Peek(int cardNumber)
        {
            return cards[cardNumber];
        }
        public Card Deal()
        {
            return Deal(0);
        }
        public bool ContainsValue(Values value)
        {
            foreach (Card card in cards)
                if (card.Value == value)
                    return true;
            return false;
        }
        public Deck PullOutValues(Values value)
        {
            Deck deckToReturn = new Deck(new Card[] { });
            for (int i = cards.Count - 1; i >= 0; i--)
                if (cards[i].Value == value)
                    deckToReturn.Add(Deal(i));
            return deckToReturn;
        }
        public bool HasBook(Values value)
        {
            int NumberOfCards = 0;
            foreach (Card card in cards)
                if (card.Value == value)
                    NumberOfCards++;
            if (NumberOfCards == 4)
                return true;
            else
                return false;
        }

        public void SortByValue()
        {
            cards.Sort(new CardComparer_byValue());
        }


    }

    class CardComparer_bySuit : IComparer<Card>
    {
        public int Compare(Card x, Card y)
        {
            if (x.Suit > y.Suit)
                return 1;
            if (x.Suit < y.Suit)
                return -1;
            if (x.Value > y.Value)
                return 1;
            if (x.Value < y.Value)
                return -1;
            return 0;
        }
    }


    class CardComparer_byValue : IComparer<Card>
    {
        public int Compare(Card x, Card y)
        {
            if (x.Value < y.Value)
                return -1;
            if (x.Value > y.Value)
                return 1;
            if (x.Suit < y.Suit)
                return -1;
            if (x.Suit > y.Suit)
                return 1;
            return 0;
        }
    }

Player

 class Player
    {
        private string name;
        public string Name { get { return name; } }
        private Random random;
        private Deck cards;
        private TextBox textBoxOnForm;
        public Player(String name, Random random, TextBox textBoxOnForm)
        {
            this.name = name;
            this.random = random;
            this.textBoxOnForm = textBoxOnForm;
            this.cards =new Deck(new Card[]{ });
            textBoxOnForm.Text += name + "has joined the game" + Environment.NewLine; 
        }
        public IEnumerable<Values> PullOutBooks()
        {
            List<Values> books = new List<Values>();
            for (int i = 1; i<= 13; i++)
            {
                Values value = (Values)i;
                int howMany = 0;
                for (int card = 0; card < cards.Count; card++)
                    if (cards.Peek(card).Value == value)
                        howMany++;
                if(howMany == 4)
                {
                    books.Add(value);
                    for (int card = cards.Count - 1; card >= 0; card--)
                        cards.Deal(card);
                }
            }
            return books;
        }

        public Values GetRandomValue()
        {
            Card randomCard = cards.Peek(random.Next(cards.Count));
            return randomCard.Value;
        }

        public Deck DoYouHaveAny(Values value)
        {
            Deck cardsIHave = cards.PullOutValues(value);
            textBoxOnForm.Text += Name + "has" + cardsIHave.Count + "" + Card.Plural(value) + Environment.NewLine;
            return cardsIHave;
        }

        public void AskForACard(List<Player> players, int myIndex,Deck stock)
        {
            Values randomValue = GetRandomValue();
            AskForACard(players, myIndex, stock, randomValue);
        }

        public void AskForACard(List<Player>players, int myIndex, Deck stock, Values value)
        {
            textBoxOnForm.Text += Name + "asks if anyone has a " + value + Environment.NewLine;
            int totalCardsGiven = 0;
            for(int i = 0; i<players.Count; i++)
            {
                if(i != myIndex)
                {
                    Player player = players[i];
                    Deck CardsGiven = player.DoYouHaveAny(value);
                    totalCardsGiven += CardsGiven.Count;
                    while (CardsGiven.Count > 0)
                        cards.Add(CardsGiven.Deal());
                }
            }
            if(totalCardsGiven == 0)
            {
                textBoxOnForm.Text += Name + "must draw from teh stock." + Environment.NewLine;
                cards.Add(stock.Deal());
            }
        }
        public int CardCount { get { return cards.Count; } }
        public void TakeCard(Card card) { cards.Add(card); }
        public IEnumerable<string> GetCardNames() { return cards.GetCardNames(); }
        public Card Peek(int cardNumber) { return cards.Peek(cardNumber); }
        public void SortHand() { cards.SortByValue(); }

    }

Game

 class Game
    {
        private List<Player> players;
        private Dictionary<Values, Player> books;
        private Deck stock;
        private TextBox textBoxOnForm;
        public Game(string playerName, IEnumerable<string> opponentNames, TextBox textBoxOnForm)
        {
            Random random = new Random();
            this.textBoxOnForm = textBoxOnForm;
            players = new List<Player>();
            players.Add(new Player(playerName, random, textBoxOnForm));
            foreach (string player in opponentNames)
                players.Add(new Player(player, random, textBoxOnForm));
            books = new Dictionary<Values, Player>();
            stock = new Deck();
            Deal();
            players[0].SortHand();
        }
        private void Deal()
        {
            stock.Shuffle();
            for (int i = 0; i < 5; i++)
                foreach (Player player in players)
                    player.TakeCard(stock.Deal());
            foreach (Player player in players)
                PullOutBooks(player);
        }
        public bool PlayOneRound(int selectedPlayerCard)
        {
            Values cardToAskFor = players[0].Peek(selectedPlayerCard).Value;
            for(int i = 0; i < players.Count; i++)
            {
                if (i == 0)
                    players[0].AskForACard(players, 0, stock, cardToAskFor);
                else
                    players[i].AskForACard(players, i, stock);
                if (PullOutBooks(players[i]))
                {
                    textBoxOnForm.Text += players[i].Name + "drew a new hand" + Environment.NewLine;
                    int card = 1;
                    while(card <=5 && stock.Count > 0)
                    {
                        players[i].TakeCard(stock.Deal());
                        card++;
                    }
                }
                players[0].SortHand();
                if(stock.Count == 0)
                {
                    textBoxOnForm.Text = "The stock is out of cards.Game over!" + Environment.NewLine;
                    return true;
                }
            }
            return false;
        }

        public bool PullOutBooks(Player player)
        {
            IEnumerable<Values> booksPulled = player.PullOutBooks();
            foreach (Values value in booksPulled)
                books.Add(value, player);
            if (player.CardCount == 0)
                return true;
            return false;
        }

        public string DescribeBooks()
        {
            string whoHasWhichBooks = "";
            foreach (Values value in books.Keys)
                whoHasWhichBooks += books[value].Name + "has a book of" + Card.Plural(value) + Environment.NewLine;
            return whoHasWhichBooks;
        }

        public string GetWinnerName()
        {
            Dictionary<string, int> winners = new Dictionary<string, int>();
            foreach (Values value in books.Keys)
            {
                string name = books[value].Name;
                if (winners.ContainsKey(name))
                    winners[name]++;
                else
                    winners.Add(name, 1);
            }
            int mostBooks = 0;
            foreach (string name in winners.Keys)
                if (winners[name] > mostBooks)
                    mostBooks = winners[name];
            bool tie = false;
            string winnerList ="";
                foreach(string name in winners.Keys)
                if(winners[name]== mostBooks)
                {
                    if(!string.IsNullOrEmpty(winnerList))
                    {
                        winnerList += "and";
                        tie = true;
                    }
                    winnerList += name;
                }
            winnerList += "with" + mostBooks + "books";
            if (tie)
                return "A tie between" + winnerList;
            else
                return winnerList;
        }

        public IEnumerable<string> GetPlayerCardNames()
        {
            return players[0].GetCardNames();
        }

        public string DescribePlayerHands()
        {
            string description = "";
                for (int i= 0; i < players.Count; i++)
            {
                description += players[i].Name + "hase" + players[i].CardCount;
                if (players[i].CardCount == 1)
                    description += "card." + Environment.NewLine;
                else
                    description += "cards." + Environment.NewLine;
            }
            description += "The stock has" + stock.Count + "cards left.";
            return description;
        }
    }

The Program

 public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private Game game;

        private void buttonStart_Click(object sender, EventArgs e)
        {
            if (String.IsNullOrEmpty(textName.Text))
            {
                MessageBox.Show("Please enter your name", " Can't start the game yet");
                return;
            }
            game = new Game(textName.Text, new List<string> { "Joe", "Bob" }, textProgress);
            buttonStart.Enabled = false;
            textName.Enabled = false;
            buttonAsk.Enabled = true;
            UpdateForm();
        }

        private void UpdateForm()
        {
            listHand.Items.Clear();
            foreach (String cardName in game.GetPlayerCardNames())
                listHand.Items.Add(cardName);
            textBooks.Text = game.DescribeBooks();
            textProgress.Text += game.DescribePlayerHands();
            textProgress.SelectionStart = textProgress.Text.Length;
            textProgress.ScrollToCaret();
        }

        private void buttonAsk_Click(object sender, EventArgs e)
        {
            textProgress.Text = "";
            if(listHand.SelectedIndex < 0)
            {
                MessageBox.Show("Please select a card");
                return;
            }
            if (game.PlayOneRound(listHand.SelectedIndex))
            {
                textProgress.Text += "The winner is..." + game.GetWinnerName();
                textBooks.Text = game.DescribeBooks();
                buttonAsk.Enabled = false;
            }
            else
                UpdateForm();
        }
    }

The Game runs fine, but my question here is , I can't understand how the method GetWinnerName( ) in the class Game is working

 

In this loop

 foreach (Values value in books.Keys)
            {
                string name = books[value].Name; 
                if (winners.ContainsKey(name)) //What is ContainsKey ?
                    winners[name]++; // What is happening here ?
                else
                    winners.Add(name, 1); // What is happening here ?
            }

 

 

2 answers to this question

Recommended Posts

  • 0

A System.Collections.Generic.Dictionary is a Hash table. It can be seen as a collection of keys each mapping to a particular value, allowing for fast (usually O(1)) retrieval of the associated value given the key, using a hash of the key (hence why every object in .NET has a GetHashCode() method).

 

As the name suggests, ContainsKey is a method that returns true if the Dictionary contains the specified key and false otherwise.

 

On this line,

winners[name]++

The value associated with the key name is retrieved and then incremented by one.

 

And here:

winners.Add(name, 1); 

The key-value pair [name, 1] is added to the collection. So now if you access it at name, you get 1 back.

  • 0
  On 23/04/2017 at 01:24, Andre S. said:

A System.Collections.Generic.Dictionary is a Hash table. It can be seen as a collection of keys each mapping to a particular value, allowing for fast (usually O(1)) retrieval of the associated value given the key, using a hash of the key (hence why every object in .NET has a GetHashCode() method).

 

As the name suggests, ContainsKey is a method that returns true if the Dictionary contains the specified key and false otherwise.

 

On this line,

winners[name]++

The value associated with the key name is retrieved and then incremented by one.

 

And here:

winners.Add(name, 1); 

The key-value pair [name, 1] is added to the collection. So now if you access it at name, you get 1 back.

Expand  

Thank you

This topic is now closed to further replies.
  • Posts

    • The first link on the github page gives me a very, very red page warning me about phishing........
    • Hey Nick! 👋 No worries at all — you're not alone in this, and it's great you're asking for help. Let me walk you through a simple, step-by-step fix using the tool mentioned on that AOMEI Partition Assistant guide — it really does the trick for many people with this exact issue! ✅ Here’s how to restore your USB back to full 256GB on Windows 11: Download & Install AOMEI Partition Assistant Go to the link you shared: AOMEI Partition Assistant and click the Download Freeware button. Insert your USB stick (Sandisk Ultra 256GB) Make sure it's properly connected. Wait for the system to detect it. Launch AOMEI Partition Assistant Once open, you'll see all your connected drives listed. Locate your USB Drive Look for the one that says something like Disk X – Removable and shows only 3.1GB or so. Right-click on your USB Drive’s Partition Then select Delete Partition → confirm the deletion. Now, right-click on the unallocated space (it should now show full unallocated capacity) Choose Create Partition → format it as FAT32 or exFAT (recommended for larger drives) → click OK. Click “Apply” in the top left corner Then hit Proceed to execute the pending operations. Wait a bit... and boom! 🎉 Your USB should now be restored to its full 256GB capacity!
    • When Facebook bought Beat Saber, they promised exactly this would never happen. Facebook can’t not lie.
    • Depends on what you mean by "this data". Nvidia can show you quite a few of those as well in their performance overlay, and I guess they might've assumed that if anyone wants to see more, they'll just use Afterburner as the de facto standard. As for real framerate vs framegen framerate, I don't think they exactly want you to know, given that their marketing has been strongly focused on hiding the real framerate and pretending the generated one is all that matters...
  • Recent Achievements

    • First Post
      Fuzz_c earned a badge
      First Post
    • First Post
      TIGOSS earned a badge
      First Post
    • Week One Done
      slackerzz earned a badge
      Week One Done
    • Week One Done
      vivetool earned a badge
      Week One Done
    • Reacting Well
      pnajbar earned a badge
      Reacting Well
  • Popular Contributors

    1. 1
      +primortal
      713
    2. 2
      ATLien_0
      279
    3. 3
      Michael Scrip
      209
    4. 4
      +FloatingFatMan
      201
    5. 5
      Steven P.
      131
  • Tell a friend

    Love Neowin? Tell a friend!