• 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

    • Similar to what started me on the path to switching to Linux... for the first 6mo of Win10 it was installing an AMD GPU driver that broke audio over HDMI which was essential to me. Driver from AMDs site was fine.
    • I have avoided many deer, a few moose, and other smaller animals during my years of driving and have managed just fine with only ABS and ESP, both of which can also be problematic depending on circumstance. I have never feared driving and I live in a rural area with a lot of deer and other animals. Winter or summer, heavy rain or sunshine, night or day, I always prefer and like to drive myself, and I drive constantly in my job. People die in accidents and they always will, that is a fact of life. Something like self-driving busses I can advocate for because they can be set to drive on static routes that always stay the same - i.e. those routes can be specially designed and maintained for them. I've already seen enough idiots doing random idiotic things with their Tesla autodrives that I would rather see them crash and burn because of their own stupidity instead of their "computer failing". I've also been a PC and tech enthusiast of over 25 years so I I'm fine with tech but I want to be the one who uses it, and decides how much of it I use. I also do not want it to make my hands, feet and brain obsolete. For me it's not really about if a computer can do it but about people not having to do things themselves (responsibly). I think that basic driving education should be done with a manual car and these "automatic only" cards should not exist (yes, I'm European and we drive a lot of manual cars, I even prefer them). If a person doesn't have enough coordination to manage a steering wheel, shitfer and pedals, how on Earth are they able to react to any unforseen situation on the road? And giving them autodrive doesn't make me feel any better if the person behind the wheel can't manage even basic driving themselves. One of the things I hate most in today's society (in general) is how pretty much everything that is considered even a bit dangerous is eliminated instead of educating people to assess risks and avoid problems themselves. Instead we make brains obsolete by building systems that do everything for us.
    • I know, I was just speaking about people in general.
    • I would say that's a purely subjective opinion, Phaseman.
  • Recent Achievements

    • One Month Later
      KynanSEIT earned a badge
      One Month Later
    • One Month Later
      gowtham07 earned a badge
      One Month Later
    • Collaborator
      lethalman went up a rank
      Collaborator
    • Week One Done
      Wayne Robinson earned a badge
      Week One Done
    • One Month Later
      Karan Khanna earned a badge
      One Month Later
  • Popular Contributors

    1. 1
      +primortal
      681
    2. 2
      ATLien_0
      274
    3. 3
      Michael Scrip
      220
    4. 4
      +FloatingFatMan
      170
    5. 5
      Steven P.
      161
  • Tell a friend

    Love Neowin? Tell a friend!