Click here to Skip to main content
Click here to Skip to main content

HiLow Card Game

, 14 May 2007
Rate this:
Please Sign up or sign in to vote.
An article on creating a simple card game with C#, using updated card.dll wrapper class.

HiLow Card Game

Introduction

This is a simple version of the card game HiLow that includes a high score table.

Background

In 2003, when I started to program with C#, I was interested in writing a card game. After some time, I found enough information to write a wrapper class to use the cards.dll that ships with Windows. This prompted me to write an article about the DLL that can be found here. Since then, I have been gradually improving it to a point where I feel it is now in a good enough state to be resubmitted. If you want to see the history of how I got to where the class is now, you can see this on my website.

HiLow game

The game is simply based on guessing whether the next random card is higher or lower than the currently shown card. Each game costs 10 points, and if you guess four correct cards, you win 20 points. After playing for a while, guessing four correct cards is not as easy as it seems.

When you have either guessed four correct cards or you have lost the game, then the "Play Again" button appears.

The wrapper class

The first change to the cards.dll wrapper class is that it now implements IDisposable. This is to make sure that the graphics device context is cleaned up properly, as the class now has its own graphics surface to draw upon.

/// <summary>
/// .NET Graphics surface used for drawing.
/// </summary>
private Graphics graphicsSurface;

/// <summary>
/// Win32 HDC surface use for Win32 drawing.
/// </summary>
private IntPtr graphicsDC;

In order to now use the class, we call Begin before any cards are drawn, and End when we have finished drawing our cards.

protected override void OnPaint(PaintEventArgs e)
{
  // Allocate graphics device context
  cardDrawing.Begin( e.Graphics );

  // Do Card drawing
  . . .

  // Release graphics device context
  cardDrawing.End();

  // Draw anything else

  base.OnPaint(e);
}

Also, we need to ensure that the cards' Dispose method is called from the form.

if( cardDrawing != null )
{
  cardDrawing.Dispose();
}

New features

One of the nice new features of the class is the ability to draw a card rotated at any angle. So in order to draw the King of Hearts rotated at 90 degrees anti-clockwise from the top-left corner of the card, we would use the following line of code:

cardDrawing.DrawRotatedCard( new Point(120,120), 90, 
       Card.ToCardIndex( CardSuit.Hearts, CardRank.King ) );

where cardDrawing is an instance of the Card class.

A simple deck class

This application uses a simple class to represent a deck of cards. Rather than having an array of cards, we only need an array of integers, because the Card class only draws cards and nothing else.

public class Deck
{
  private int[] CardArray = new int[52];

  /// <summary>
  /// Initializes deck with the 52 integers.
  /// </summary>
  public Deck()
  {
    // Deck uses RankCollated cards 0 - 51
    for( int i = 0; i < 52; i++ )
    {
      CardArray[i] = i;
    }
  }
}

This makes it easy to implement a shuffle routine, which is very random in nature.

/// <summary>
/// Randomly rearrange integers
/// </summary>
public void Shuffle()
{
  int[] newArray = new int[52];
  bool[] used = new bool[52];

  for( int j = 0; j < 52; j++ )
  {
    used[j] = false;
  }

  Random rnd = new Random();
  int iCount = 0;
  int iNum;

  while( iCount < 52 )
  {
    iNum = rnd.Next( 0, 52 ); // between 0 and 51

    if( used[iNum] == false )
    {
      newArray[iCount] = iNum;
      used[iNum] = true;
      iCount++;
    }
  }

  // Load original array with shuffled array
  CardArray = newArray;
}

Finally, the current integer stored in our array is accessed to know which card to draw.

/// <summary>
/// Obtains a card number from the deck.
/// </summary>
public int GetCard( int arrayNum )
{
  if (arrayNum >= 0 && arrayNum <= 51)
    return CardArray[arrayNum];
  else
    throw (new System.ArgumentOutOfRangeException("arrayNum", arrayNum,
      "Value must be between 0 and 51."));
}

Reusing code

Whilst making this game, I decided that I wanted a high score table. Rather than re-inventing the wheel so to speak, I have incorporated the HighScore class from my Yahtzee game submitted previously.

High Score Table

Enjoy the game!

History

  • 10th May 2007 - Updated source code for .NET 2.0
  • 14th May 2007 - Updated article posted to The Code Project

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Mike Kitchen
Software Developer (Senior)
United Kingdom United Kingdom
No Biography provided

Comments and Discussions

 
GeneralMy vote of 3 Pinmembervipana4-Sep-10 18:50 
Generaldraw rotated back PinmemberChip02265030-May-08 12:29 
GeneralCards as a PictureBox for dragging Pinmembershastaou81231-Oct-07 9:58 
GeneralCode Error PinmemberMike Kitchen15-May-07 1:00 
GeneralPInvoke error PinmemberCmarsha25-Apr-06 8:16 
The Cards class included here had some issues with VS 2005. Turns out the color variable in the interface was defined as long, where it should be int. Perhaps this is specific to certain versions of the cards.dll.
 
Anyway, if you are getting a PInvoke error this is what fixed it for me:
 
[DllImport("cards.dll")]
public static extern bool cdtDraw( IntPtr hdc,
int x,
int y,
int card,
int mode,
int color );
 
[DllImport("cards.dll")]
public static extern bool cdtDrawExt( IntPtr hdc,
int x,
int y,
int dx,
int dy,
int card,
int type,
int color );


GeneralRe: PInvoke error Pinmembercheeks863-Apr-07 17:16 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.140709.1 | Last Updated 14 May 2007
Article Copyright 2004 by Mike Kitchen
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid