0

I have an array named mainDeck which holds the values for a deck of playing cards. What I have to do next is distribute the cards within that array to two separate arrays named playerDeck and computerDeck and each deck must contain a unique card.

The problem I have is distributing the cards with a unique value - 26 cards per deck. I have tried a few different approaches and the coding at the bottom in comments is the last remnant of what I was trying to do before I had to leave for class which isn't finished.

To note: My programming skills are limited to please explain your answer rather then just give a solution as that doesn't further my understanding.

static void Main(string[] args)
{
        // 1 = Ace , 13 = King : 0 = Hearts, 1 = Diamonds, 2 = Clubs, 3 = Spades
        int[] mainDeck = new int[52];
        FillDeck(mainDeck);

        int[] playerDeck = new int[26];
        int[] computerDeck = new int[26];
        // Check mainDeck elements
        foreach (int number in mainDeck)
        {
            Console.WriteLine(number);
        }

    }
    public static void FillDeck(int [] mainDeck)
    {
        int cardType = 1;
        List<int> deck = new List<int>();            

        // Add cards to a list
        for (int x = 0; x < 13; x++)
        for(int y = 0; y < 4; y++)
        {
            deck.Add(cardType);
            if (y == 3)
                ++cardType;
        }

        // Insert deck list into a new Array
        int[] cards = deck.GetRange(0, 52).ToArray();

        // Add cards array to mainDeck
        for (int x = 0; x < 52; ++x)
        {
            mainDeck[x] = cards[x];
        }
    }
    //public static void Distribute()
    //{
    //    RandomNumber number = new RandomNumber();
    //    int value = number.RandomNum;

    //    List<int> playerCards = new List<int>();
    //    for (int x = 0; x < 2; ++x)
    //    {
    //        Console.WriteLine(number.RandomNum);
    //    }
    //}
}
//class RandomNumber
//{
//    private int randomNum;
//    Random ranNumberGenerator;

//    public RandomNumber()
//    {
//        ranNumberGenerator = new Random();
//    }

//    public int RandomNum
//    {
//        get
//        {
//            randomNum = ranNumberGenerator.Next(1, 26);
//            return randomNum;
//        }
//    }
//}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
JRoy
  • 25
  • 1
  • 1
  • 4
  • See this for how best to shuffle: http://stackoverflow.com/questions/273313/randomize-a-listt-in-c-sharp – weston Nov 28 '12 at 13:53

5 Answers5

2

If you're trying to distribute the cards randomly like you would in a typical card game here is an article on shuffling an array. - http://www.dotnetperls.com/shuffle - It should do what you want.

After you shuffle the mainDeck array you just loop through it alternately assigning cards to player and computer decks in the same manner you would deal cards in real life.

evanmcdonnal
  • 46,131
  • 16
  • 104
  • 115
2

The common solution for a card game deck

  1. Create the deck with all available cards
  2. Shuffle the deck
  3. Get cards from the top

so the code :)

public enum CardColor
{
  Hearts = 0,
  Diamonds = 1,
  Clubs = 2,
  Spades = 3
}

public enum CardValue
{
  Ace = 1,
  Two,
  Three,
  Four,
  Five,
  Six,
  Seven,
  Eight,
  Nine,
  Ten,
  Jack,
  Queen,
  King
}

public class Card
{
  public Card(CardValue value, CardColor color)
  {
    Value = value;
    Color = color;
  }

  public readonly CardValue Value;
  public readonly CardColor Color;
}

public class Deck
{
  private Queue<Card> deckInternal;

  public Deck()
  {
    var deck = new List<Card>();
    for(int index = 0; index < 52; index++)
    {
      var cardValue = (CardValue)(index % 4) + 1;
      var cardColor = (CardColor)index / 4;
      dec.Add(new Card(cardValue, cardColor));
    }

    var rand = new Random();
    dec = dec
      .OrderBy(c => rand.Next(52))
      .ToList();

    deckInternal = new Queue<Card>(deck);
  }

  public Card GetCard()
  {
    return deckInternal.Dequeue();
  }
}

to get deck and split it you can do next

var deck = new Deck();

var player = new List<Card>();
var computer = new List<Card>();

for(int index = 0; index < 52; index++)
{
  if(index % 2 == 0)
  {
    player.Add(deck.GetCard());
  }
  else
  {
    computer.Add(deck.GetCard());
  }
}
Viacheslav Smityukh
  • 5,652
  • 4
  • 24
  • 42
1

You have two options for keeping the values unique within the deck here. You can either create a new class representing a card, which has properties for the Rank and Suit, or if you want to keep it simple (from a compiler standpoint, anyway) you can use the value to indicate both rank and suit, whereas you're using 1 through 13 to indicate rank only.

For the latter solution, you would want to use the numbers 0 through 12 to indicate Ace through King of Hearts, 13 through 25 to indicate Ace through King of Diamonds, and so on. To get the rank of any card you'd use card % 13 and to get the suit of the card you'd use card / 4.

I would prefer the former solution, though, and would create a class like this (you could also replace the int properties with Enums for even more readability):

public class Card
{
    public int Rank { get; set; }
    public int Suit { get; set; }
}

after that you could create a loop that runs until the main deck is empty and picks a random card from the main deck to put into the other two decks. In pseudo-code it might look like:

while (mainDeck has any elements)
    num = random number between 0 and elements in mainDeck - 1, inclusive
    deckToAddTo = alternate between playerDeck and computerDeck
    remove card num from mainDeck and insert into deckToAddTo
jfren484
  • 960
  • 10
  • 13
  • @Jay - The OP specified a deck of 52 cards, therefore, no jokers. My former solution would work just fine with jokers. Rank would include joker (either as a value of 14, or an additional enum value) and Suit would be NA or something like that. – jfren484 Jul 16 '12 at 16:45
  • Oops, should have been "value of 13" not 14) – jfren484 Jul 16 '12 at 16:53
0

Give player the first 26 cards.

playerDeck = mainDeck.Take(26).ToArray();

Skip player's cards and get the next 26 cards.

computerDeck = mainDeck.Skip(26).Take(26).ToArray();
Chuck Savage
  • 11,775
  • 6
  • 49
  • 69
0
Random  rnd = new Random();
// you can Shuffle Array and Take random 26 items using Linq as below
int[] playerDeck = mainDeck.OrderBy(x => rnd.Next()).Take(26).ToArray();
// get rest of the items using Except linq method 
int[] computerDeck = mainDeck.Except(playerDeck).ToArray();
Damith
  • 62,401
  • 13
  • 102
  • 153