C# Poker hands.

Hello, I have a working script in c# unity that draws a 5 card hand for the player but i cant really think of a way to check hands, example pair, straight… Can someone help me out how i would give each card a value and how i would check it? Here is source,
Thanks alot!

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RandomCard : MonoBehaviour {

     public Texture2D pic0;
     public Texture2D pic1;
     public Texture2D pic2;
     public Texture2D pic3;
     public Texture2D pic4;
     public Texture2D pic5;
     public Texture2D pic6;
     public Texture2D pic7;
     public Texture2D pic8;
     public Texture2D pic9;
     public Texture2D pic10;
     public Texture2D pic11;
     public Texture2D pic12;
     public Texture2D pic13;
     public Texture2D pic14;
     public Texture2D pic15;
     public Texture2D pic16;
     public Texture2D pic17;
     public Texture2D pic18;
     public Texture2D pic19;
     public Texture2D pic20;
     public Texture2D pic21;
     public Texture2D pic22;
     public Texture2D pic23;
     public Texture2D pic24;
     public Texture2D pic25;
     public Texture2D pic26;
     public Texture2D pic27;
     public Texture2D pic28;
     public Texture2D pic29;
     public Texture2D pic30;
     public Texture2D pic31;
     public Texture2D pic32;
     public Texture2D pic33;
     public Texture2D pic34;
     public Texture2D pic35;
     public Texture2D pic36;
     public Texture2D pic37;
     public Texture2D pic38;
     public Texture2D pic39;
     public Texture2D pic40;
     public Texture2D pic41;
     public Texture2D pic42;
     public Texture2D pic43;
     public Texture2D pic44;
     public Texture2D pic45;
     public Texture2D pic46;
     public Texture2D pic47;
     public Texture2D pic48;
     public Texture2D pic49;
     public Texture2D pic50;
     public Texture2D pic51;


     public int card1;
     public int card2;
     public int card3;
     public int card4;
     public int card5;
     Texture2D[] pics;
     int i;
     void Start () {
         pics = new Texture2D[52];
         pics [0] = pic0;
         pics [1] = pic1;
         pics [2] = pic2;
         pics [3] = pic3;
         pics [4] = pic4;
         pics [5] = pic5;
         pics [6] = pic6;
         pics [7] = pic7;
         pics [8] = pic8;
         pics [9] = pic9;
         pics [10] = pic10;
         pics [11] = pic11;
         pics [12] = pic12;
         pics [13] = pic13;
         pics [14] = pic14;
         pics [15] = pic15;
         pics [16] = pic16;
         pics [17] = pic17;
         pics [18] = pic18;
         pics [19] = pic19;
         pics [20] = pic20;
         pics [21] = pic21;
         pics [22] = pic22;
         pics [23] = pic23;
         pics [24] = pic24;
         pics [25] = pic25;
         pics [26] = pic26;
         pics [27] = pic27;
         pics [28] = pic28;
         pics [29] = pic29;
         pics [30] = pic30;
         pics [31] = pic31;
         pics [32] = pic32;
         pics [33] = pic33;
         pics [34] = pic34;
         pics [35] = pic35;
         pics [36] = pic36;
         pics [37] = pic37;
         pics [38] = pic38;
         pics [39] = pic39;
         pics [40] = pic40;
         pics [41] = pic41;
         pics [42] = pic42;
         pics [43] = pic43;
         pics [44] = pic44;
         pics [45] = pic45;
         pics [46] = pic46;
         pics [47] = pic47;
         pics [48] = pic48;
         pics [49] = pic49;
         pics [50] = pic50;
         pics [51] = pic51;

         i=card1;
         while(i==card1){
         card1=Random.Range(0,52);}

         i=card2;
         while(i==card2){
         card2=Random.Range(0,52);}

         i=card3;
         while(i==card3){
         card3=Random.Range(0,52);}

         i=card4;
         while(i==card4){
         card4=Random.Range(0,52);}

         i=card5;
         while(i==card5){
         card5=Random.Range(0,52);}
    }
     void OnGUI(){

         GUI.DrawTexture (new Rect (Screen.width/2 - 62, Screen.height/2 - 90, 125, 181), pics [card1]);
         GUI.DrawTexture (new Rect (Screen.width/2 + 67, Screen.height/2 - 90, 125, 181), pics [card2]);
         GUI.DrawTexture (new Rect (Screen.width/2 + 196, Screen.height/2 - 90, 125, 181), pics [card3]);
         GUI.DrawTexture (new Rect (Screen.width/2 + 326, Screen.height/2 - 90, 125, 181), pics [card4]);
         GUI.DrawTexture (new Rect (Screen.width/2 + 456, Screen.height/2 - 90, 125, 181), pics [card5]);
}
}

Poker hands don’t have much in common with each other, so there won’t be much you can do except brute force each hand.

Start with the most valuable hand and work your way down, stop as soon as one is valid. That way you won’t claim a pair when you have a three of a kind and so on.

want to explain how i do that? Im really new to this. I have been using unity3d for years but this coding side is quite new. please give me a example? Thanks

A more generalized solution to storing what card is what is to assign the cards in your deck values from 0 to 51, and then pre-populate an integer array with those values.

Now apply your shuffle to change the order. Google for a basic swap card shuffle.

Now take the first five cards for your hand. You will have 5 unique integers from 0 to 51.

Now make helper functions that return the rank and the suit of a card based on the 0 to 51 value.

int Rank( int cardno)
{
  return cardno % 13;
}

and

int Suit( int cardno)
{
  return cardno / 13;
}

Now as @Kiwasi says above, start from the most-valuable hand and see if you have one of those, and work your way down to the least-valuable.

Using Rank() and Suit() functions like above, you can analyze your 5 cards in order to quickly see, “Do I have all Spades?” for instance, or “Are all of my cards precisely one distant from the next, meaning I have a straight?”, etc.

Obviously it is entirely up to you what integer maps to what suit, such as suit 0 is spades, etc., and of course what integer maps to what rank, such as 0 is ace, 1 is 2, etc. up to 12 is king. Whatever you choose, write it down and make sure you stick by that as you work.

1 Like

Sure. So to look for a flush you would do something like this

bool CheckForFlush(){
    suit firstSuit = playerHand[0].suit;
    foreach (Card card in playerhand){
        if (card.suit != firstSuit) return false;
    }
    return true;
}

You’ll need to create a custom method for each hand. Note that there is some overlap, for example the straight flush could be done like this.

bool CheckForStraighFlush () {
    return CheckForFlush() && CheckForStraight();
}

For simplicity in coding I would probably make a card class (or struct). Coding by convention is always risky.

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

public class Card {
    public Suit suit {get; private set;}
    public int rank {get; private set;}

    public Card (int cardNo) {
        this.suit = (Suit)(cardno / 13);
        this.rank = cardno % 13 + 1; // +1 here so that rank matches the face value.
    }
}

is it possible to use if randomcard?

int randomcard = Random.Range(1,4);
if(randomcard == 3){ ... }

Sure.

Card randomCard = new Card(Random.Range (0,52);

Although I would do this the way @Kurt-Dekker suggested and create the entire deck of cards at once.

List<Card> deck = new List<Card>(52);

for (int i = 0; i ++; i< 52) {
    deck.Add(new Card(i));
}

One last question haha, you have been a big help.
How do you list items in a if statment?
example what i mean;

if(handcard1 == 4 , handcard2 == 3){
Debug.Log(“Hit”);
}

Broadly speaking, an if statement tests one thing for true or false.

However you can create a compound statement that contains multiple true/false terms and then combines them using logical operators such as AND and OR.

AND is written with && and OR is written with II

So here would be an example:

if ((suit == 0) && (rank == 0))
{
 Debug.Log( "You have the ace of spades.");
}

thank you. i really appreciate your guys help! @Kiwasi @Kurt-Dekker

1 Like

For a good shuffled deck, shuffle at least 7 times.

???

You can produce a statistically perfect shuffle on the first attempt with the right shuffle algorithm. By which I mean you can guarantee each card has an equal probability of being drawn. The only benefit to doing seven shuffles is to warm up the room slightly.

But if increasing the entropy of the universe is your goal, there are more efficient ways to do it.

1 Like

No thats impossible, no algorithm does that. When plotted for time vs Randomness no algorithm can compute a good enough shuffle in 1 go. It has to be done at least 7 times. The NSA says a good shuffling algorithm should be done at least 7 times.

When you go to a casino the dealer shuffles the deck using a shuffling algorithm 7 times, its not a coincidence its based on statistics. Show me an algorithm that can shuffle a deck in 1 go where it cannot be broken.

I believe @Kiwasi is correct. The well-known “shuffle 7 times” rule refers in particular to the random riffle shuffle, which is what most people use in real life (reference). Obviously with this shuffle algorithm you can’t apply it just once, because the top card after the shuffle has a 50% chance of being the same card that was on top before (etc.).

But computers don’t do a random riffle shuffle. They have no problem doing whatever algorithm you can dream up, and there are good and bad ones.

The MiniScript built-in shuffle method uses the Fisher-Yates algorithm described above. Here’s a version of the same thing that works as a List extension method:

    private static System.Random shuffleRnd = new System.Random();
    public static void Shuffle(List<Vector2> list) {   
        for (int i = list.Count; i > 1; i--) {
            int pos = shuffleRnd.Next(i);
            var x = list[i - 1];
            list[i - 1] = list[pos];
            list[pos] = x;
        }
    }

Another simple approach is to simple draw without replacement, i.e., start with your list of 52 cards, draw any one at random (by picking a number from 0 to the number of cards left), and stick that onto a deck. Repeat until your source deck is empty. This is equivalent to Fisher-Yates, but easier to understand: it should be obvious that this produces all sequences of cards with equal probability (assuming a sufficiently random PRNG, of course).

So when using any of those good algorithms, there really is no point in doing it more than once. If you have a reference for that NSA claim, I’d love to see it.

1 Like

Rubbish. Fisher-Yates, which is a fairly basic shuffle algorithm, will create all permutations with equal likelihood (assuming your random number generator is half way decent). In a single pass. Repeating Fisher-Yates will in no way improve the randomness of the shuffle.

The casino dealer is generally using a shuffle algorithm constrained by physics. If you could implement Fisher-Yates with real cards, it will perform perfectly in a single pass.

Just noticed this in your code:

         i=card1;
         while(i==card1){
         card1=Random.Range(0,52);}
         i=card2;
         while(i==card2){
         card2=Random.Range(0,52);}
         i=card3;
         while(i==card3){
         card3=Random.Range(0,52);}
         i=card4;
         while(i==card4){
         card4=Random.Range(0,52);}
         i=card5;
         while(i==card5){
         card5=Random.Range(0,52);}

This will allow for duplicate cards. And I mean up to 5 duplicate cards.

Do what @Kiwasi suggested about having a Card class and I would suggest useing a List to store cards, so you can remove them from the deck(List) when you pick a random one. This will do away with duplicates. Then you just need to initalize the deck for every game and you’re golden.

1 Like

can you give me simple project poker please :frowning:

You’ll never learn if we do all the work for you.

okey thank u :slight_smile: