0

I have string list of a deck of card the strings are as such, A-DIAMONDS, 2-CLUBS, etc.

I want to be able to generate 5 unique items from this list randomly.

I know how to do this in python with Random.sample(5) but in trying to find a solution in C#. everything seems to be generating a random, put it in a list, generate another random, check it against the list and it is working fine.

Is there a more compact way of doing this in C#?

Here is my full code after using Linq for shuffling.

    class Program
{
    static void Main(string[] args)
    {
        string [] cardValues = { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K" };
        string [] cardSuites = { "HEARTS", "CLUBS", "DIAMONDS", "SPADES" };
        List<string> deckOfCards = new List<string>();

        foreach(string cardsuit in cardSuites)
        {
            foreach(string cardvalues in cardValues)
            {
                deckOfCards.Add(cardvalues + "-" + cardsuit);
            }

        }

        for(int i = 0; i <= 10; i++)
        {
            List<string> pokerHand = new List<string>();
            Random rand = new Random();
            deckOfCards = deckOfCards.Select(x => new { card = x, rand = rand.Next() }).OrderBy(x => x.rand).Select(x => x.card).ToList();
            for(int x = 0; x < 5; x++)
            {
                pokerHand.Add(deckOfCards[x]);
            }
            Console.WriteLine(String.Join(", ", pokerHand));
        }


        Console.ReadLine();
    }
}

}

3 Answers3

4

Here is one way to shuffle using linq. The 5 random cards are the first 5 items in the list. :

    class Program
    {
        static void Main(string[] args)
        {
            List<string> deck = new List<string>() {
                "S2", "S3", "S4", "S5", "S6", "S7", "S8", "S9", "ST", "SJ", "SQ", "SK", "SA",
                "H2", "H3", "H4", "H5", "H6", "H7", "H8", "H9", "HT", "HJ", "HQ", "HK", "HA",
                "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "CT", "CJ", "CQ", "CK", "CA",
                "D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "DT", "DJ", "DQ", "DK", "DA"
            };

            Random rand = new Random();

            deck = deck.Select(x => new { card = x, rand = rand.Next() }).OrderBy(x => x.rand).Select(x => x.card).ToList();
        }
    }
jdweng
  • 33,250
  • 2
  • 15
  • 20
  • I think that could work. So your shuffling the list, then you can just grab the first 5 cards because it will then be random. Never thought about it like that.I am new to C# so i need to research what some of those methods do so i have a better understanding but i like it. Thank you very much – Jimmy COttom Apr 13 '19 at 13:17
  • Randomly picking a card you have to check if you picked same card twice. It is much easier just to assign a random number to each card and then sort by the random number. – jdweng Apr 13 '19 at 13:33
  • So your selecting all the elements, assigning a random number to each, then sorting the random number, then adding the elements back to the list in the random number sorted order? – Jimmy COttom Apr 13 '19 at 13:50
  • Exactly correct. I'm using the linq anonymous method to create a two dimensional array {card, random number} then at end removing just the card from the two dimensional array to create a one dimensional string array. – jdweng Apr 13 '19 at 14:00
1

You could use MoreLINQ. Simply install it from NuGet. MoreLINQ gives you a Shuffle method. So you can do something like the following:

List<Card> deck = GetDeck();
List<Card> randomFiveCards = deck.Shuffle().Take(5).ToList();
user2877820
  • 287
  • 4
  • 19
  • can you elaborate on this a little more, what is GetDeck – Jimmy COttom Apr 13 '19 at 15:39
  • This would be your method that fills your `deckOfCards` list with items. You will have to replace `GetDeck()` with your own logic to create a deck. Sorry if that confused you. – user2877820 Apr 15 '19 at 06:32
0

A valid and efficient algorithm is to pick a random index between 0 and n-1 (where n is the number of cards), exchange the last card with the card at that index. Then pick a random index between 0 and n-2 and exchange second-last card with the card at that index.

Repeat other three times with n-3, n-4 and n-5 and your five randomly chosen cards will be at the end of the array.

6502
  • 112,025
  • 15
  • 165
  • 265