Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

I need to create a simple card game for class, but it needs to be smart enough to deal out random cards and only deal each individual card once. I have to do this with arrays, no other choice. I want to make this question as simple to answer as possible so here goes.

 

First, I want to take my predefined array and just having it be reordered. After that is done, I'd like to be able to deal out the top card (0) when I press a button, then the next (1) and so on, until I reach the final card (51).

 

I've searched all over this forum and the net, and there doesn't seem to be any simple way to just do this with a predefined array. Everything I find is more focused on creating random lists, rather than just reordering an existing list. Any help you guys could give would be greatly appreciated. Thanks.

Posted (edited)

An actual commercially used deck shuffling function:

 

private Card[] cards;

#region Enumerations

/// <summary>
/// Defines a card suit
/// </summary>
public enum Suit: int
{
	/// <summary>
	/// Clubs suit
	/// </summary>
	Clubs = 0,

	/// <summary>
	/// Diamonds suit
	/// </summary>
	Diamonds,


	/// <summary>
	/// Hearts suit
	/// </summary>
	Hearts,


	/// <summary>
	/// Spades suit
	/// </summary>
	Spades
}


/// <summary>
/// Defines a card rank
/// </summary>
public enum Rank: int
{
	/// <summary>
	/// Ace card
	/// </summary>
	Ace = 0,

	/// <summary>
	/// Two card
	/// </summary>
	Two = 1,

	/// <summary>
	/// Three card
	/// </summary>
	Three,

	/// <summary>
	/// Four card
	/// </summary>
	Four,

	/// <summary>
	/// Five card
	/// </summary>
	Five,

	/// <summary>
	/// Six card
	/// </summary>
	Six,

	/// <summary>
	/// Seven card
	/// </summary>
	Seven,

	/// <summary>
	/// Eight card
	/// </summary>
	Eight,

	/// <summary>
	/// Nine card
	/// </summary>
	Nine,

	/// <summary>
	/// Ten card
	/// </summary>
	Ten,

	/// <summary>
	/// Jack card
	/// </summary>
	Jack,

	/// <summary>
	/// Queen card
	/// </summary>
	Queen,

	/// <summary>
	/// King card
	/// </summary>
	King
}

	/// <summary>
	/// Randomizes the elements in the array
	/// </summary>
	public void Shuffle(int seed)
	{
		//first put cards back in order
		int current =0;

		for( int j=0; j < this.cards.Length/52; ++j )
		{
			for ( int y = 0; y < 4; ++y) 
			{
				for ( int x = 0; x < 13; ++x) 
				{
					cards[current++] = new Card( (Suit)y, (Rank)x);
				} //end for suit
			} //end for rank
		} //end for numberDecks

		//then shuffle from seed

		System.Random random = new Random(seed);
	
		// temp variable need to do the swaping
		int temp = 0;
		Card card;
		
		// for every card in the deck switch it with another
		for(int i = 0; i < cards.Length; ++i)
		{
			temp = random.Next(0,cards.Length);
			card = (Card)cards[temp];
			cards[temp] = cards[i];
			cards[i] = card;
		} //end for

		this.currentCard = -1;
	}

 

Card class should be something like:

 

/// <remarks>
/// Represents a card
/// </remarks>
public class Card
{
	#region Private Variables

	private Suit suit;
	private Rank rank;

	// contains the value of the card in bits 
	// the first 2 bit contain value of the suit
	// the last 4 contain the rank.
	// IE 2 of Hearts is
	// 10 0010 = 18
	private int cardValue;

	#endregion 

	#region ctor
	/// <summary>
	/// Initializes a new instance of the Card Class.		
	/// </summary>
	public Card(Suit cardSuit, Rank cardRank)
	{
		this.suit = cardSuit;
		this.rank = cardRank;

		cardValue = (int)suit;
		cardValue <<= 4;
		cardValue += (int)cardRank;
	}

	#endregion 

Edited by Diesel
Posted

I should have mentioned that I'm using VB.NET.

 

What I tried doing was creating a parallel array, a boolean that would keep track of whether a card was dealt or not. So I ended up generating a random number between 0 and 51. Once a card was dealt, the boolean was changed from false to true. This does work, but it gets VERY slow. Anyone else here have any ideas?

Posted

hmm should you shuffle 7 times?

http://www.bbc.co.uk/radio4/science/another52.shtml

 

first thing that came into my head:

 

   Dim pack(51) As Integer

   Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
       ' fill pack with cards
       For i As Integer = 0 To 51
           pack(i) = i
       Next
       ' shuffle
       Dim shuffler As New shuffle
       Array.Sort(pack, shuffler)
       'display result
       For i As Integer = 0 To 51
           Debug.WriteLine(pack(i))
       Next
   End Sub

   Private Class shuffle
       Implements IComparer
       Dim rand As Random

       Sub New()
           rand = New Random
       End Sub

       Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements System.Collections.IComparer.Compare
           'return -1, 0 or 1 which determines if x or y comes first (or if they are equal)
           'as it is random it will shuffle.
           Return rand.Next(-1, 2)
       End Function

   End Class

 

You would normally use Icomparer to sort things, but if you randomly sort it seems as good as shuffling.

Posted

What the ****! **** VB.NET. It's all the ****ing Same! Learn to program you dumbass!

 

If you can't use my code, your ****ing useless.

 

This is the last time I help a retard!

 

I practically wiped your *** for you! What else can I do?

  • Leaders
Posted (edited)

Diesel, you really need to relax. Even if he wasn't learning, not everyone should be expected to have the same skill set as you. To someone who has never programmed in a language with C syntax, C# would probably look like Chinese. But, hey, ultimately, it all means the same stuff, so if you can't understand Chinese, learn to read, right? Don't mistake that as blatant sarcasm, I'm just trying to make an analogy.

 

Onto a happier note:

 

There are already some good ideas out there, and I like the IComparer trick. Thought I would throw out the first two things that came to me anyways.

 

Last time I made a card shuffling routine I made two arrays as well. The program picked a number from 0 to 51, seeked through the cards (array 1) to the number picked and added that card to the deck (array 2). A card taken is marked, for example, by changing it's rank to zero. Then, we pick a random number from 0 to 50, seek to the nth card, skipping over those marked as taken (i.e. have a rank of zero). Then pick a random number 0 to 49... until you get to the last card.

 

Seeking thought the deck instead of picking random numbers until you find an untaken card eliminates the hit or miss issue that will waste a lot of CPU.

 

A quick and dirty solution would be to populate an ArrayList with all the cards, and transfer randomly picked cards to another ArrayList until none remain. Easy as pie to code, not very CPU-usage friendly.

 

Unless you need to shuffle a very large number of decks, my first method should be quite adequate (although implementing IComparer would certainly involve less code).

Edited by snarfblam
[sIGPIC]e[/sIGPIC]
Posted
Diesel, you really need to relax. Even if he wasn't learning, not everyone should be expected to have the same skill set as you. To someone who has never programmed in a language with C syntax, C# would probably look like Chinese. But, hey, ultimately, it all means the same stuff, so if you can't understand Chinese, learn to read, right? Don't mistake that as blatant sarcasm, I'm just trying to make an analogy.

 

Onto a happier note:

 

There are already some good ideas out there, and I like the IComparer trick. Thought I would throw out the first two things that came to me anyways.

 

Last time I made a card shuffling routine I made two arrays as well. The program picked a number from 0 to 51, seeked through the cards (array 1) to the number picked and added that card to the deck (array 2). A card taken is marked, for example, by changing it's rank to zero. Then, we pick a random number from 0 to 50, seek to the nth card, skipping over those marked as taken (i.e. have a rank of zero). Then pick a random number 0 to 49... until you get to the last card.

 

Seeking thought the deck instead of picking random numbers until you find an untaken card eliminates the hit or miss issue that will waste a lot of CPU.

 

A quick and dirty solution would be to populate an ArrayList with all the cards, and transfer randomly picked cards to another ArrayList until none remain. Easy as pie to code, not very CPU-usage friendly.

 

Unless you need to shuffle a very large number of decks, my first method should be quite adequate (although implementing IComparer would certainly involve less code).

 

Thanks. I have gotten my program to work after going through the ideas on this thread. Thanks all, even Diesel :D .

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...