C#: deck of cards
Deck of cards
Some time ago I wrote a post detailing how I tried to simulate a deck of cards in PowerShell using its classes and objects.
I've been learning C# recently, and I thought that this would be the perfect on-ramp, seeing as classes and objects is what C# is all about.
Things I learned:
- Most syntax (e.g. inheritance by Child : Parent) is similar across PowerShell and C#
- Using .NET classes like List makes it easier to move across from PowerShell to C# and vice versa
- Refactoring (e.g. moving a class into its own separate file) is made very easy in Visual Studio
- Sometimes, C# will allow you to omit curly braces and use indentation instead to execute script blocks (e.g. in
if ... else ...constructions, and inforeach, making them look oddly like Python).
Here it is:
Code
Enums
namespace DeckOfCards
{
enum Suit
{
Spades = 0,
Hearts = 1,
Clubs = 2,
Diamonds = 3
}
}
namespace DeckOfCards
{
enum CardValue
{
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
}
}
Classes
namespace DeckOfCards
{
internal class Card
{
public Suit suit;
public CardValue value;
public string symbol;
private string[] symbols = new string[4] { "♠", "♥", "♣", "♦" };
private string[] indeces = new string[] { "0", "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K" };
public Card(Suit suit, CardValue value)
{
this.suit = suit;
this.value = value;
this.symbol = $"{this.indeces[(int)value]}{this.symbols[(int)suit]}";
}
public string Elaborate()
{
return $"{this.value} of {this.suit}";
}
}
}
using System.Collections.Generic;
namespace DeckOfCards
{
// a hand and a deck are all "stacks"
internal class Stack
{
public List<Card> cardList;
public Stack()
{
this.cardList = new List<Card> { };
}
public int Count()
{
return this.cardList.Count;
}
public Card Deal(int i)
{
Card dealtCard = this.cardList[i];
this.cardList.RemoveAt(i);
return dealtCard;
}
public void Receive(Card card)
{
this.cardList.Add(card);
}
}
}
using System;
using System.Collections.Generic;
namespace DeckOfCards
{
internal class Deck : Stack
{
public Deck()
{
foreach (Suit suit in Enum.GetValues(typeof(Suit)))
foreach (CardValue value in Enum.GetValues(typeof(CardValue)))
this.Receive(new Card(suit, value));
}
public Card Deal()
{
int deckCount = this.Count();
int randomNumber;
if (deckCount > 1)
randomNumber = new Random().Next(deckCount);
else
randomNumber = 0;
Card dealCard = this.Deal(randomNumber);
return dealCard;
}
public List<Card> DealMany(int numberOfCards)
{
List<Card> dealtCards = new List<Card>();
for (int i = 0; i < numberOfCards; i++)
dealtCards.Add(this.Deal());
return dealtCards;
}
}
}
using System;
using System.Collections.Generic;
namespace DeckOfCards
{
internal class Hand : Stack
{
public List<Card> Draw(Deck pile, int numberOfCards)
{
List<Card> drawnCards = new List<Card> { };
for (int i = 0; i < numberOfCards; i++)
{
Card drawnCard = pile.Deal();
this.Receive(drawnCard);
drawnCards.Add(drawnCard);
}
return drawnCards;
}
public void Elaborate()
{
Console.WriteLine("Cards in hand:");
for (int i = 1; i <= this.cardList.Count; i++)
{
Console.Write($"{i}: ");
Console.Write(this.cardList[i - 1].Elaborate());
Console.Write("\n");
}
}
public Card Discard()
{
Console.WriteLine("Discard which card?");
this.Elaborate();
int choice = int.Parse(Console.ReadLine());
int discardIndex = choice - 1;
Card discardedCard = this.cardList[discardIndex];
this.cardList.RemoveAt(discardIndex);
Console.WriteLine($"Discarded {discardedCard.Elaborate()}");
Console.WriteLine("Card remaining in hand:");
this.Elaborate();
return discardedCard;
}
}
}