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;
}
}
}