dinsdag 20 november 2007

Card Masquerade

I've found some interesting resources on the Internet on evaluating Poker hands. I chose to use Cactus Kev's method. He uses a single 32 bit int to store the cards rank bitmap, suit, rank and rank prime number. See the site itself for the surprising details!

I had to adjust the Card class to accomodate for the int though. Luckily we have unit tests in place to quickly review the changes. The exported members have not changed, but the internals have been rewritten to directly write to and read from the int bitmask. This way we can quickly implement the hand evaluator.

I will not tire you with the bitwise operations I do, just download the solution below and take a peek at the Card class. If you think what I do could be done better, feel free and let me know :).

For the hand evaluator itself I have found some articles on combinatorial operations and permutations, for that is exactly what we need. Who said Poker is a simple game?

Download entire solution

zondag 18 november 2007

Dealing The Cards

One of the most important tasks of the dealer is to deal the cards to either the board or the players. Every player gets one card from the dealer and after the first card is dealt to every player at the table, the same procedure is repeated. This way we end up each player having two pocket cards.

Before the flop, turn and river is dealt, a card has to be burned. This means that we remove the top card from the deck. The flop consists of three cards, unlike the turn and the river which are only one card.

What information can we extract from these rules? Obviously, we need to create a Player class and a Board class. Hierarchically the Board and Player classes both have a list of Card classes. The Board class has a list of Player classes. The dealer is the head of the Board class.

Besides that, it should be possible for the Dealer class to burn a card and deal cards in various stages of the hand.

I'll not explain every addition and change, but take some excerpts from the changes. To see every change, download the entire solution below.

First of all, I will show you the cardburning mechanism. It's no complicated matter, just remove the first item in the list:
private void BurnCard()
{
if (cards == null)
{
throw new InvalidOperationException();
}

cards.RemoveAt(0);
}

To make the dealer the head of the board, I have changed the constructor of the Dealer class to accept the Board class. Also I have encorporated an enum for defining the stage of the hand in de Dealer class.

Below I will show you how to deal the cards to the players and the board:
public void Deal(StageEnum stage)
{
if (cards == null)
{
throw new InvalidOperationException();
}

if (board == null)
{
throw new InvalidOperationException();
}

if (board.Players == null || board.Players.Count < 2)
{
throw new InvalidOperationException();
}

int iCardsToDeal = 0;
switch (stage)
{
case StageEnum.PreFlop:
Deal(board.Players, 2);
break;

case StageEnum.Flop:
Deal(board, 3);
break;

case StageEnum.Turn:
Deal(board, 1);
break;

case StageEnum.River:
Deal(board, 1);
break;
}
}

private void Deal(List players, int cardCount)
{
for (int i = 0; i < cardCount; i++)
{
foreach (Player p in players)
{
p.Cards.Add(cards[0]);
cards.RemoveAt(0);
}
}
}

private void Deal(Board board, int cardCount)
{
BurnCard();
board.Cards.AddRange(cards.GetRange(0, cardCount));
cards.RemoveRange(0, cardCount);
}

That was easy :-). In the next post I will discuss how to evaluate the hands and determine the winner!

Download entire solution

donderdag 15 november 2007

Revamped Looks

Hi, I have nothing much to add today, but the fact that I revamped the looks of the blog :). Hope you like it!

woensdag 14 november 2007

Shuffle Things Up

From this day forward I will post the changes in source in a zip file. This is much easier if you are confused about the code. Scroll down to the end of this entry to find the link.

Also, I would like to mention that the usage of this code is restricted for personal and educational purposes, unless you give me credit for it.

Today I have implemented the Dealer service. This class has the responsibility to hold the Card classes, shuffle the deck and distribute the Cards to either the players or the board.

Create a new Class Library and call it Poker.Services. Add a new class called Dealer. Implement the next two functions in the Dealer class to initialize the deck of cards and shuffle.
private void InitializeCards()
{
cards = new List<Card>();
for (int i = 0; i < 13; i++)
{
for (int j = 0; j < 4; j++)
{
cards.Add(new Card((Card.SuitEnum)j, (Card.ValueEnum)i));
}
}
}

private void ShuffleCards()
{
List<Card> c = new List<Card>();

Random rnd = new Random();
for (int i = 0; i < 52; i++)
{
int cpos = rnd.Next(0, cards.Count);
c.Add(cards[cpos]);
cards.RemoveAt(cpos);
}

cards = c;
}

To initialize the class, create this constructor:
private List<Card> cards = null;

public List<Card> Cards
{
get { return this.cards; }
set { this.cards = value; }
}

public Dealer()
{
InitializeCards();
ShuffleCards();
}

To test the Dealer service, we have to create a new instance of the Dealer class and count the cards. Also, there should be four cards of each value: one for every suit. Create a new Class Library called Poker.Services.Tests and add a new class DealerTests. Add a reference to the nunit.framework assembly and mark the DealerTests class with [TestFixture].

Create a new function TestDeckConsistency which accepts a generic List of type Card:
public void TestDeckConsistency(List<Card> c)
{
Assert.AreEqual(52, c.Count);

for (int i = 0; i < 13; i++)
{
int counter = 0;
for (int j = 0; j < 52; j++)
{
if (c[j].Value == (Card.ValueEnum)i)
{
counter++;
}
}

Assert.AreEqual(4, counter);
}
}

Add a new test function to call this with a list of cards:
[Test]
public void Dealer_NewCardDeck_52Cards4OfEachValue()
{
Dealer d = new Dealer();
TestDeckConsistency(d.Cards);
}

Done. We now have a working dealer, which shuffles the cards. Click on the link below to download the entire solution, which includes a modified version of the form: it displays the shuffled cards.

Download entire solution

Using Cards.dll or CardGames.dll

It is possible to use the cards.dll for drawing the cards. See Code Project - Drawing Cards with Cards.dll by Mike Kitchen for details.

The reason why I don't use this dll is that I work on Windows Vista. Windows Vista does not have the dll mentioned. I found another possibility, CardGames.dll in the Windows System32 folder, but I could not find how to use it, nor does it export functions?

As far as I can see the CardGames.dll is a resource container and does not have any functionality embedded but behavior XML of each cardgame shipped with Windows Vista.

If any of you know how to use the latter dll, please let me know.

UPDATE: I have unraveled the mysteries around CardGames.dll, read CardGames.dll Demystified!

dinsdag 13 november 2007

A First Look At The Cards

On a website [url: CPSC 124, Spring 2006 - Lab 12: Arrays] I have found a picture of the playing cards we can use. It consists of one picture with 13 playing cards in a row, starting with the Ace and ending with the King. Every row has a distinct suit. An extra row was added with the back of the card and two jokers.

To support this image I had to refactor the Card class we created in the last post. This was done in 5 minutes, thanks to the unit testing.

The two enums have been changed to inherently support the image:
public enum SuitEnum
{
Clubs
, Diamonds
, Hearts
, Spades
}

public enum ValueEnum
{
Ace
, _2
, _3
, _4
, _5
, _6
, _7
, _8
, _9
, _10
, Jack
, Queen
, King
}

Also, the ToString() function was modified to support the changes:
public override string ToString()
{
string tempString = string.Empty;

switch (this.value)
{
case ValueEnum._10:
tempString = "T";
break;

case ValueEnum.Jack:
tempString = "J";
break;

case ValueEnum.Queen:
tempString = "Q";
break;

case ValueEnum.King:
tempString = "K";
break;

case ValueEnum.Ace:
tempString = "A";
break;

default:
tempString = ((int)this.value + 1).ToString();
break;
}

switch (this.suit)
{
case SuitEnum.Clubs:
tempString += "c";
break;

case SuitEnum.Diamonds:
tempString += "d";
break;

case SuitEnum.Hearts:
tempString += "h";
break;

case SuitEnum.Spades:
tempString += "s";
break;
}

return tempString;
}

Run the unit tests, and see: the tests succeed!

Next, create a new C# Windows Application called Poker.WinApp, add a reference to Poker.Common and add the image to the file. Click the image to view the properties and make the Build Action: Embedded Resource.

Add a new function to the form:
private Bitmap getCard(Card c)
{
Assembly a = Assembly.GetExecutingAssembly();
using (Image img = Image.FromStream(a.GetManifestResourceStream("Poker.WinApp.cards.png")))
{
using (Bitmap bmp = new Bitmap(img))
{
int w = bmp.Width / 13;
int h = bmp.Height / 5;
int posX = (int)c.Value * w;
int posY = (int)c.Suit * h;

return bmp.Clone(new Rectangle(posX, posY, w, h), System.Drawing.Imaging.PixelFormat.DontCare);
}
}
}

To test this, add a button and a picturebox to the form and add the following code to the Click event of the button:
Card c = new Card(Card.SuitEnum.Diamonds, Card.ValueEnum._6);
this.pictureBox1.Image = getCard(c);

Start the WinApp, click the button and voila!

maandag 12 november 2007

Fractals Are Beauty

Hi, I know this site is about C#, but I couldn't resist publishing this site: Fractals are Beauty

The Card Class

Let us first create the card class. The most common class of all the classes in our object space: this is what it is all about :-). I do not have a lot of time available today, so I'll just ramble down to the details. I assume you already have some experience with C# here... If you don't, please write me a comment below!

Also, if anything is plain wrong (remember, I am just starting in C#) or when something is not very clear, please let me know.

Lets get down to business... Create a new Class Library called Poker.Common and add a new class, Card.cs:
public class Card
{
}

Add a few enums in the class called SuitEnum and ValueEnum. These enums define the properties of the cards in the deck. I use enums because I like classes to be specific: other developers will have no trouble using these.
public enum SuitEnum
{
Hearts
, Diamonds
, Clubs
, Spades
}

public enum ValueEnum
{
_2
, _3
, _4
, _5
, _6
, _7
, _8
, _9
, _10
, Jack
, Queen
, King
, Ace
}

After that we can define our private members:
private SuitEnum suit;
private ValueEnum value;

Now lets do some real work. The suit of the card is accessible through a property. In the property setter we check for the value which was passed to it before applying it to the private members. This way we ensure the state of the card object is valid.
public SuitEnum Suit
{
get { return this.suit; }
set
{
if (value == SuitEnum.Clubs
value == SuitEnum.Diamonds
value == SuitEnum.Hearts
value == SuitEnum.Spades)
{
this.suit = value;
}
else
{
throw new ArgumentOutOfRangeException();
}
}
}

Next, it should be possible to access the value of the card a property:
public ValueEnum Value
{
get { return this.value; }
set
{
if ((int)value <> 12)
{
throw new ArgumentOutOfRangeException();
}

this.value = value;
}
}

The only way to construct the card class will be by specifying it's suit and value, as shown next:
public Card(SuitEnum suit, ValueEnum value)
{
this.Suit = suit;
this.Value = value;
}

Before I proceed to the unit test for the Card class, I override the ToString() function:
public override string ToString()
{
string tempString = string.Empty;

if ((int)this.value >= 0 && (int)this.value <= 7)
tempString = ((int)this.value + 2).ToString();

switch (this.value)
{
case ValueEnum._10:
tempString = "T";
break;

case ValueEnum.Jack:
tempString = "J";
break;

case ValueEnum.Queen:
tempString = "Q";
break;

case ValueEnum.King:
tempString = "K";
break;

case ValueEnum.Ace:
tempString = "A";
break;
}

switch (this.suit)
{
case SuitEnum.Clubs:
tempString += "c";
break;

case SuitEnum.Diamonds:
tempString += "d";
break;

case SuitEnum.Hearts:
tempString += "h";
break;

case SuitEnum.Spades:
tempString += "s";
break;
}

return tempString;
}

To setup the unit tests, create a new project called Poker.Common.Tests. Notice that the name is exactly like above, with .Tests appended. This ensures other developers won't be surprised about what the heck you are doing.

Add a reference to the nunit.framework assembly in the .Tests project. This assembly is part of the NUnit framework. Also add a reference to the Poker.Common project we created above.

Create a new class called CardTests in the .Tests project. Make the CardTests public and add a TestFixture attribute to it. The TestFixture marks the class as testable by NUnit. Also add some namespace imports on top to NUnit.Framework and Poker.Common.

The class now looks like this:
[TestFixture]
public class CardTests
{
}

When unit testing, there are a few testing scenarios. First of all, you have to cover the border tests. These are tests designed to ensure the minimum and maximum values are covered. Add the following to the testing class and run the tests, by right clicking on the class name and selecting Run Test(s). This command is available after installing the TestDriven.net framework.
[Test]
public void Card_ConstructorFilled2Clubs_ToString2c()
{
Card c = new Card(Card.SuitEnum.Clubs, Card.ValueEnum._2);
Assert.AreEqual("2c", c.ToString());
}

[Test]
public void Card_ConstructorFilledAceSpades_ToStringAs()
{
Card c = new Card(Card.SuitEnum.Spades, Card.ValueEnum.Ace);
Assert.AreEqual("As", c.ToString());
}

Also, we have a crossing point in the class: when the value of the card exceeds 9, suddenly the string representation will be alphanumeric:
[Test]
public void Card_ConstructorFilled9Clubs_ToString9c()
{
Card c = new Card(Card.SuitEnum.Clubs, Card.ValueEnum._9);
Assert.AreEqual("9c", c.ToString());
}

[Test]
public void Card_ConstructorFilled10Diamonds_ToStringTd()
{
Card c = new Card(Card.SuitEnum.Diamonds, Card.ValueEnum._10);
Assert.AreEqual("Td", c.ToString());
}

As you have seen before, we expect the class to throw an error when an invalid value is passed to either the Suit or Value property:
[Test, ExpectedException(typeof(ArgumentOutOfRangeException))]
public void Card_ConstructorSuitOutOfRange_ThrowsException()
{
Card c = new Card((Card.SuitEnum) 10, Card.ValueEnum._2);
}

[Test, ExpectedException(typeof(ArgumentOutOfRangeException))]
public void Card_ConstructorValueOutOfRange_ThrowsException()
{
Card c = new Card(Card.SuitEnum.Clubs, (Card.ValueEnum) 15);
}

Wrapping up, we have to check for the other suits and alphanumeric values to be correct.
[Test]
public void Card_ConstructorFilledJackHearts_ToStringJh()
{
Card c = new Card(Card.SuitEnum.Hearts, Card.ValueEnum.Jack);
Assert.AreEqual("Jh", c.ToString());
}

[Test]
public void Card_ConstructorFilledQueenSpades_ToStringQs()
{
Card c = new Card(Card.SuitEnum.Spades, Card.ValueEnum.Queen);
Assert.AreEqual("Qs", c.ToString());
}

[Test]
public void Card_ConstructorFilledKingSpades_ToStringKs()
{
Card c = new Card(Card.SuitEnum.Spades, Card.ValueEnum.King);
Assert.AreEqual("Ks", c.ToString());
}

Tada, there we have a fully testable card class! The unit tests assure that any refactoring in the future won't break the class and provides nice documentation to the developer.

Again, if anything in the above code is wrong or you don't understand a specific aspect, don't hestitate to mention it in a comment. I happily spent another blog entry to it.

zondag 11 november 2007

First Thoughts

Okay, I have done some thinking over the game. Maybe we will make it a mobile app which can connect to other mobile apps via BlueTooth which makes it possible to play poker against other people while travelling. But maybe we will make it a Windows app sitting on your desktop. Maybe we will just be doing it both ;-) to illustrate the endless possibilities of layered architecture: most of all this website is here to serve you develop yourself into a good programmer and for me to make the transition from Visual Basic .net to c#.

I have been writing Visual Basic .net apps as a profession for the last five years, but I see the market more or less diverts to c#.

Now, what is a Poker game all about? To summarize: it is a card game, which consists of one deck of 52 shuffled cards. Each player receives two cards from the deck, issued by the dealer, which are not visible to the rest of the players. The two players to the left of the dealer have forced bets to start the action. After the cards have been dealt, the first betting round of a total of four starts. The players have the choice to either check, bet, call, raise or fold. When the first round finishes, all the bets are the same. One card will be burned and the first three community cards appear on the board. This is the flop which starts the second betting round. When the second betting round ends, the process repeats for the turn and the river, both one card from the deck. When only one player remains, this is the winner. When multiple players end the game, the showdown decides the winner. Both the players' cards and the community cards are combined to form the highest possible combination of five cards.

Hi Folks, We Will Be Writing a Poker Game!

Hello readers! I am very happy you have found this weblog. This weblog is about developing applications in c#. While I was thinking about the weblog when I was visiting TechEd Barcelona, I thought it would be nice to write a nice cardgame.

While No Limit Texas Hold'em Poker is currently a very popular cardgame, I thought up the idea to implement this. So the next couple of weeks, maybe months (depending on how much time I have available ;-), lots of code samples and sources become available for our Poker game.

The game will be writting in c# 2.0 and includes unit tests done with NUnit.

So please setup your box with the following prerequisites: