• 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

    • Precisely. I didn't give Reddit permission to sell my posts to any AI vendor from any of my accounts. Since I've been on Reddit since before the current pseudo-AI existed, I don't think anyone did...
    • The character tech looks awful, like something from 10 years ago.
    • lol net-negative? They're worth $29 billion, so they aren't hurting. They're just money hungry and don't care at all about the free videos on their platform. They shouldn't be making money off of those, but they are. Those content creators that are uploading their videos they made aren't making anything, but YouTube is making tons of money off of them, along with being exorbitant. If they want to do what they did before and lock Premium videos in a paywall, then fine. But no one is going to put up with them strong-arming people into paying just to have an ad-free experience while watching super old videos uploaded by John Doe at 360p.
    • Sony unveil Marvel fighting game 'Tōkon: Fighting Souls' for PlayStation 5 and PC by Pulasthi Ariyasinghe Sony held a massive surprise in store for those who made to the end of its State of Play presentation today. Coming in as a collaboration between PlayStation Studios, Arc System Works, and Marvel Games, Tōkon: Fighting Souls is slated to be a tag team fighter featuring everyone's favorite heroes and villains from the Marvel comics universe. Watch the debut trailer above. Developer Arc System Works, which has previously worked on series like Guilty Gear and Blazblue, has revealed that the focus on this project was making sure it was easy to pick up and play by anyone. To put this into perspective, the studio says that while other fighting games require learning each character's moves to play them effectively, Tōkon will only have one way of playing for all available fighters. "From the beginning, we aimed to make MARVEL Tōkon: Fighting Souls a title that could be enjoyed by a wide variety of players," explains Game Director and Lead Battle Designer, Kazuto Sekine. "We have designed the mechanics in such a way that you can perform a variety of actions with either traditional fighting game inputs or simple inputs. With the press of a few buttons, multiple characters can appear on screen to provide backup or attack together – creating a new and exciting team VS battle experience." So far, Captain America, Iron Man, Spider-Man, Doctor Doom, Storm, Ms. Marvel, Star-Lord, and Ghost Rider (Robbie Reyes) have been revealed as playable characters, neatly filling the trailer's four versus four battle. Each character has a Japanese flair to them too, such as Iron Man's unique Gundam style for his armor. As for why the studio went with the 4v4 Tag Team battle solution, the team said that the team-up nature of superheroes was the inspiration for that, making sure that players can fill the screen with all sorts of powers they are familiar with. Tōkon: Fighting Souls is coming to both PlayStation 5 consoles as well as PC sometime in 2026. More announcements with reveals for characters, stages, gameplay modes, and online mechanics will be coming up until launch as well.
    • Nothing surprising there. Anyone expecting privacy on ANY social media platform is delusional at best. Let alone one controlled by the same creep that owns Tesla (a.k.a. facecrook on wheels), which blatantly violates user privacy with Tesla vehicles as reported by Louis Rossman. This action of his is just another prime example of why ANYTHING from him is trust-worthy as the same from Zuckerberg...i.e. not at all.
  • Recent Achievements

    • First Post
      James courage Tabla earned a badge
      First Post
    • Reacting Well
      James courage Tabla earned a badge
      Reacting Well
    • Apprentice
      DarkShrunken went up a rank
      Apprentice
    • Dedicated
      CHUNWEI earned a badge
      Dedicated
    • Collaborator
      DarkShrunken earned a badge
      Collaborator
  • Popular Contributors

    1. 1
      +primortal
      347
    2. 2
      snowy owl
      167
    3. 3
      +FloatingFatMan
      164
    4. 4
      ATLien_0
      162
    5. 5
      Xenon
      127
  • Tell a friend

    Love Neowin? Tell a friend!