Click here to Skip to main content
15,907,281 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi ,
I want to make playing cards game . I give every card a number from 1 to 52
now I need give cards to 4 players (every player has 13 cards) . so how I can make random 4 groups (every groups contain with 13 number ) and number from 1-52 and no group has the same number ?
Posted

The easiest way is to emulate a real deck of cards:
Take your "deck" as a list of integers:
C#
private List<int> deck = new List<int>();
private const int cardsCount = 52;
private Random rand = new Random();

Then fill it with all the numbers:
C#
deck.AddRange(Enumerable.Range(1, cardsCount));

Then write a shuffle method:
C#
List<int> shuffled = new List<int>();
for (int i = 0; i < cardsCount; i++)
    {
    int index = rand.Next(deck.Count);
    shuffled.Add(deck[index]);
    deck.RemoveAt(index);
    }
deck = shuffled;

You can then deal the "cards" off the top and get guaranteed random and unique values.

(I'd probably create a Card class so that the number translated to a suit and value better, but that's up to you)
 
Share this answer
 
The trick is here: "Random extraction of 5 cards from a deck"[^] (C++ code, sorry).

In your case, it should work this:

Initalization
  • Assign an array this way: c(0)=1, c(1)=2, .., c(51)=52.


then
  • pick a random number between 0 and 51 (included) say r.
  • swap c(r) with c(51)..

The first card assigned to player 1, is c(51).

then
  • pick a random number (r) between 0 and 50 (included).
  • swap c(r) with c(50).

The second card assigned to player 1 is c(50).

and so on...
 
Share this answer
 
v2
It probably is irrelevant for a game, but OriginalGriff's Solution 1 is doing a lot of extra work (moving the list contents above the removed element at each iteration). Using an array instead of a list the Fisher-Yates shuffle[^] can be done in O(n) using the "inside-out" version.
C#
private const int cardsCount = 52;
private Random rand = new Random();
private static int[] deck = Enumerable.Range(1, cardsCount).ToArray();

private static int[] Shuffle(int[] deck)
{
  int[] shuffled = new int[deck.Length];
  shuffled[0] = deck[0];
  for (int i = 1; i < deck.Length; i++)
  {
    int j = rand.Next(i + 1);
    if (j != i)
      shuffled[i] = shuffled[j];
    shuffled[j] = deck[i];
  }
  return shuffled;
}

Use like:
C#
int[] shuffled = Shuffle(deck);

=============
Edit: 2016-14-6 MTH
This is a bit old, but it's worth noting:
If avoiding bias in the resultant "shuffles" is important, pay particular attention to the Fisher-Yates shuffle: Potential sources of bias in the Wikipedia article.
(For example, to have the possibility of producing all possible shufflings of a 52 card deck the pseudo random number generator must have at least 226 bits of internal state!)
 
Share this answer
 
v4
Thank you Matt T Heffron , I use .Net 2.0 and have error and when I use .Net 3.5 I solve the error.
but it I have 3 list box .
I use VB.net
How I can fill them with 13 card for each list ? in other words how I can use it ?

I use this code :

VB
Private shuffled(cardsCount - 1) As Integer
   Private deck() As Integer
   Private Const cardsCount As Integer = 52
   Private rand As New Random()
   Public Function Shuffle(ByVal deck() As Integer) As Integer()
       On Error Resume Next
       shuffled(0) = deck(0)
       For i As Integer = 1 To deck.Length - 1
           Dim j As Integer = rand.Next(i + 1)    '[edit by Matt] changed parameter value
           If j <> i Then
               shuffled(i) = shuffled(j)
           End If
           shuffled(j) = deck(i)
       Next i
       Return shuffled

   End Function
  Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

       Shuffle(deck)
       ListBox1.Items.AddRange(shuffled)
   End Sub


But I have problem in ListBox1.Items.AddRange(shuffled)

Now How I can fill ListBox1 with cards ?
I also try this

VB
ListBox1.Items.Clear()
      Dim j As Integer
      Dim lst As ListBox
      For i As Integer = 1 To 52
          j = rand.Next(1, 53)
          lst.Items.Add(i)
          ListBox1.Items.Add(j)
      Next i


but I have a problem! the function reiterate some numbers (like I have 3 number with value 17)
 
Share this answer
 
v4
Comments
Matt T Heffron 31-Jan-14 12:55pm    
I just "stumbled" across this...If you had used the "Have a Question or Comment?" button on my Solution I'd have gotten an email.

Yes, my solution is using Linq which requires .Net 3.5.

OK,
At this point there is the int array shuffled.
So you can either deal the elements of the array to the listboxes (i.e., element at index i goes to player i % 4 (players numbered 0-3))
OR
you can just take the first 13 elements and give them to player 0, the next 13 to player 1, etc.
KosayHatem 31-Jan-14 14:04pm    
I use it with

Dim shuffled() As Integer = Shuffle(deck)

but error in deck
Matt T Heffron 31-Jan-14 14:40pm    
What was the error?
How did you define deck?
KosayHatem 31-Jan-14 15:10pm    
I use this
Private deck As New List(Of Integer)()
Matt T Heffron 31-Jan-14 16:24pm    
Did you define the Shuffle() to take a List(Of Integer) or an array?
Did you pre-fill it with the values 1 to 52?
Please use the "Improve solution" on your "Solution 4" above, and show the relevant code.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900