• 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

    • Looking for a specific setting in Settings? Sorry, the option just doesn’t exist as you’d need to elevate for that. Want to do something quickly and efficiently? Nah, forced to use a “modern” interface which takes far longer to achieve what you’re looking to do. (Example: disable a NIC)
    • Yet the best laptop for all day battery life is a Mac, hands down, no contest. Windows is bloated and power management is rubbish. Search indexer. Defender. Malicious Software Removal Tool. Windows Update (+DISM). Office CTR. Telemetry. Disclaimer: I own a surface laptop studio, multiple gaming desktops, server, and a macbook pro.
    • And bring back taskbar deskbands which were removed, and full and total customization of notification area icons like earlier
    • This has all the markings of a thinly veiled mechanism for force users of older versions of Windows to upgrade...and trash perfectly good hardware. Microsoft, your history easily supports this line of reasoning.
    • Plasma 6.5 brings improved Emoji Selector, better performance in Activity manager, and more by David Uzondu This week saw the long-awaited release of KDE Plasma 6.4, bringing better window management and a whole lot of color management features. Apart from the release of 6.4, the KDE team was able to get other work done, and this was all outlined in the latest issue of This Week in Plasma, which details what is coming down the pipe for future versions. Looking ahead to Plasma 6.5, the developers are making some notable changes to improve performance and general usability. To prevent its database from growing endlessly and causing performance problems over time, the Activity Manager service will now only store the last four months of your history by default. The Emoji selector app is also getting a much-needed redesign that makes the window more compact and moves the sidebar button to the header for a cleaner look. Other little details for 6.5 are being polished up too. The unpopular vertical line separating the date and time on the horizontal Digital Clock widget is gone; if you want it back, you can add it yourself with a custom date format. The "Add New" button has also been moved to the top toolbar in the Shortcuts page within Settings, freeing up some valuable screen real estate. The devs also reduced the minimum size of custom tiling tiles, a small but significant fix for anyone with an ultrawide monitor. In addition to that, the Networks widget's captive portal banner now uses inline header styling, so it doesn't look like a bunch of frames stacked inside each other anymore. Of course, before we get to 6.5, the current release needs some attention. Plasma 6.4's first bug fix release, 6.4.1, addresses issues like broken item selection in the Folder View widget and a bug that could cause the system to lock or suspend faster than intended. Keyboard navigation in list views in Discover feels smoother now, and text is easier to read in certain list items in KRunner. The devs also cleaned up how list items look when you press or click them in Discover. 6.4.1 also fixes a bug where the clipboard history popup would fail to select the top item, and makes the Earth Science Picture of The Day wallpaper plugin work again after its data source changed. Here's the full list of fixes: Fixed several issues in the Folder View widget that caused selecting or opening items to not work when using certain non-default view settings, when the view was scrollable, or when using a touchscreen. Fixed a bug in the Meta+V clipboard popup that sometimes failed to pre-select the top-most item. The Clipboard settings window’s shortcuts page no longer shows columns for local shortcuts that don’t do anything, since the clipboard is global in scope. Fixed the Earth Science Picture of the Day wallpaper plugin after the source data changed formatting again. Made a few fixes to the “Missing Backends” section of Discover’s settings window that kept it from working properly. Fixed a bug that prevented direct scan-out (and its performance benefits) from activating on rotated screens. Fixed an issue where the system could lock or suspend sooner than expected after an app stopped blocking those actions. Installing a new wallpaper plugin no longer causes the plugin list combobox to appear blank. The team even went back to squash some bugs in the older 6.3.6, tackling an issue that could cause keyboard shortcuts to get lost during a system upgrade and fixing an overflow bug with KRunner's faded completion text. Plasma 6.4.1 is set to arrive on June 24th, with 6.3.6 following on July 8th.
  • Recent Achievements

    • One Month Later
      adxnksd42031 earned a badge
      One Month Later
    • Rising Star
      aphanic went up a rank
      Rising Star
    • Contributor
      GravityDead went up a rank
      Contributor
    • Week One Done
      BlakeBringer earned a badge
      Week One Done
    • Week One Done
      Helen Shafer earned a badge
      Week One Done
  • Popular Contributors

    1. 1
      +primortal
      664
    2. 2
      ATLien_0
      262
    3. 3
      Michael Scrip
      234
    4. 4
      Steven P.
      162
    5. 5
      +FloatingFatMan
      151
  • Tell a friend

    Love Neowin? Tell a friend!