|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
IntroductionThis is a simple version of the card game HiLow that includes a high score table. BackgroundIn 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 gameThe 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 classThe first change to the cards.dll wrapper class is that it now implements /// <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 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' if( cardDrawing != null )
{
cardDrawing.Dispose();
}
New featuresOne 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 A simple deck classThis 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 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 codeWhilst 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
Enjoy the game! History
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||