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.
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.
}
}
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.
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.
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.
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.