using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Drawing;
public enum CardSuit
{
Hearts, Diamonds, Clubs, Spades
}
public enum CardFace
{
Ace, Two, Three, Four, Fiv, Six, Seven, Eight, Nine, Ten, Jack, Queen, King
}
public class Card : Control
{
// Constructors not public as we only want creation through a Deck.
protected internal Card(int value) : this(value, (CardSuit)(value % 4), (CardFace)(value / 4)) { }
protected internal Card(CardSuit suit, CardFace face) : this((int)suit * (int)face, suit, face) { }
// Both of the above constructors call this one.
private Card(int value, CardSuit suit, CardFace face)
{
if (value < 0 || value > 51)
throw new ArgumentException("The card's value must be between 0 and 51 inclusive.");
this.Value = value;
this.Suit = suit;
this.Face = face;
SetDisplayProperties();
}
protected virtual void SetDisplayProperties()
{
this.BackColor = Color.White;
this.Text = this.ToString();
this.Size = new Size(110, 20);
}
// Read only properties as we do not want the card's value to change once it's been created.
public CardSuit Suit { get; private set; }
public CardFace Face { get; private set; }
public int Value { get; private set; }
// Return a friendly card name, i.e. "Ace of Spades".
public override string ToString()
{
return Enum.GetName(typeof(CardFace), Face) + " of " + Enum.GetName(typeof(CardSuit), Suit);
}
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.DrawString(this.ToString(), this.Font, new SolidBrush(this.ForeColor), 3, 3);
}
}
public static class Deck
{
private static List<Card> cards = new List<Card>() {
new Card(0), new Card(1), new Card(2), new Card(3), new Card(4), new Card(5),
new Card(6), new Card(7), new Card(8), new Card(9), new Card(10), new Card(11),
new Card(12), new Card(13), new Card(14), new Card(15), new Card(16), new Card(17),
new Card(18), new Card(19), new Card(20), new Card(21), new Card(22), new Card(23),
new Card(24), new Card(25), new Card(26), new Card(27), new Card(28), new Card(29),
new Card(30), new Card(31), new Card(32), new Card(33), new Card(34), new Card(35),
new Card(36), new Card(37), new Card(38), new Card(39), new Card(40), new Card(41),
new Card(42), new Card(43), new Card(44), new Card(45), new Card(46), new Card(47),
new Card(48), new Card(49), new Card(50), new Card(51)};
private static int cardsDealt;
public static void Reset()
{
Shuffle();
cardsDealt = 0;
}
private static Card CardFromPosition(int position)
{
return cards[position];
}
public static Card GetNextCard()
{
cardsDealt++;
return CardFromPosition(cardsDealt - 1);
}
public static void Shuffle()
{
Shuffle(500);
}
public static void Shuffle(int iterations)
{
Card cardPlaceHolder;
Random random = new Random();
for (int i = 0; i < iterations; i++)
{
int position1 = random.Next(0, 51);
int position2 = random.Next(0, 51);
// Make sure the positions are different
while (position1.Equals(position2))
{
position2 = random.Next(0, 51);
}
cardPlaceHolder = cards[position1];
cards[position1] = cards[position2];
cards[position2] = cardPlaceHolder;
}
}
public static int CardsRemaining()
{
return cards.Count - cardsDealt;
}
public static Card Peek()
{
return Peek(1);
}
public static Card Peek(int depth)
{
if (depth < 1 || depth > CardsRemaining())
throw new ArgumentException(string.Format("There are {0} cards remaining. You cannot peek to a depth of {1}.", CardsRemaining().ToString(), depth.ToString()), "depth");
return CardFromPosition(cardsDealt + (depth-1));
}
}