public class Lesson5_GoFish_Pt1

{

void LetsPlayAGame()

{

It’s time to tackle a more complex assignment. We will start with a simple card game, “Go Fish.”


 

If you’ve never played, take a look at the directions at https://www.bicyclecards.com/how-to-play/go-fish/. We will be using a simple version of these rules to make our game. And if you would like to download or view the completed code project, go to https://github.com/TimPurdum/GoFish.

}
 

void ModelTheWorld()

{

Object-Oriented Programming is excellent for creating models of the real world, which, after all, is made up of objects. Let’s start by creating a model of a deck of cards. Actually, though, a deck of cards is just a collection of card objects, and we already know how to create collections! So, let’s start by creating a card object. What defines a card?

  • Suit – The color and symbol of the card. Hmm…maybe we need to represent suits as an object too. (In some other card games, the red suits are interchangeable, as are the black suits, so color might be important as well.)
  • Rank – The number or name of the card.

One simple way to create a list of value options is to create an enum. We will create two enums, one for Suit:

namespace GoFish
{
    public enum Suit
    {
        Hearts,
        Diamonds,
        Spades,
        Clubs
    }
}

 

And one for Rank:

namespace GoFish
{
    public enum Rank
    {
        Ace,
        Two,
        Three,
        Four,
        Five,
        Six,
        Seven,
        Eight,
        Nine,
        Ten,
        Jack,
        Queen,
        King
    }
}

 

In VS Code, go to File => New File, and add the code above for Suit. Save as Suit.cs, and then repeat and create Rank.cs. You should see these files added to your sidebar explorer, as well as the tabs at the top.

 

Now let’s create our Card file, saving it as Card.cs. Add the code below. Notice that this is now a class, out of which we can create all our cards. I’ve also created a property called PluralName so that I can return a string representation of the rank in its plural form.

namespace GoFish
{
    public class Card
    {
        public Suit Suit;
        public Rank Rank;
        
        public Card (Suit suit, Rank rank)
        {
            Suit = suit;
            Rank = rank;
        }


        public string PluralName
        {
            get
            {
                if (Rank == Rank.Six)
                {
                    return Rank + "es";
                }

                return Rank + "s";   
            }
        }
    }
}

 

Once we have the Card class, it is easy to build a collection of cards into a Deck. But instead of creating a collection by hand, I am using inheritance to create a special SubClass of List. Notice in the class declaration line, : List<Card>. This means that a Deck will inherit all the properties and methods of a List, such as Add and Remove. But in addition, we can add our own methods, like Shuffle and Draw.

using System;
using System.Collections.Generic;
using System.Linq;

namespace GoFish
{
    public class Deck : List
    {
        readonly Suit[] suits =
        {
            Suit.Hearts,
            Suit.Clubs,
            Suit.Diamonds,
            Suit.Spades
        };

        public Deck()
        {
            for (var i = 0; i < 13; i++)
            {
                foreach (var suit in suits)
                {
                    Add(new Card(suit, (Rank)i));
                }
            }
        }


        public void Shuffle()
        {
            var rnd = new Random();
            for (var i = 0; i < Count - 1; i++)
            {
                Swap(i, rnd.Next(i, Count));
            }
        }


        public void Deal(List players, int numberOfCards)
        {
            foreach (var player in players)
            {
                player.Hand = new List();
                Draw(player, numberOfCards);
            }
        }


        public void Draw(Player player, int numberOfCards = 1)
        {
            for (var cardNum = 0; cardNum < numberOfCards; cardNum++)
            {
                player.Hand.Add(this.First());
                RemoveAt(0);
            }
        }


        public Card Peek()
        {
            return this.First();
        }


        void Swap(int a, int b)
        {
            var temp = this[a];
            this[a] = this[b];
            this[b] = temp;
        }
    }
}

}
 

void ReadyPlayerOne()

{

We will create one more data model class, to signify a Player. Very simply, each player needs to have a Hand and Sets, or laid down 4-of-a-kind matches. Rather than create subclasses like we did for Deck, Hand uses the default List<Card> definition. Sets, however, is a List of a List, which allows you to track multiple groups of cards.

using System.Collections.Generic;

namespace GoFish
{
    public class Player
    {
        public List Hand { get; set; }
        
        public List> Sets { get; } = new List>();
    }
}

 

In our next post, we will explore how to lay out the action of the game!

}

}

Leave a Reply

Your email address will not be published. Required fields are marked *