azumakazuma
azumakazuma

Reputation: 63

Determining probability of 4 of a kind in a 5 card poker hand Matlab

I am supposed to determine the probability of 4 of a kind in a 5 card poker draw using Matlab. I understand the first thing I have to do is generate a deck and shuffle the cards, then draw 5 cards. I am having trouble with determining whether the hand is 4 of a kind or not. I have written the code below, which works for shuffling the deck and drawing 5 cards. I have tried to use an if statement to determine if the hand is a 4 of a kind or not, but it does not work. My reasoning behind the if statement was that if I already had a sorted vector, the only two possibilities would be the first 4 or the last 4 numbers should all equal each other

Ex. AAAA_

_2222

Any advice on how to determine 4 of a kind would be very helpful :)

DECK = ['AH';'2H';'3H';'4H';'5H';'6H';'7H';'8H';'9H';'TH';'JH';'QH';'KH'; ...
    'AS';'2S';'3S';'4S';'5S';'6S';'7S';'8S';'9S';'TS';'JS';'QS';'KS'; ...
    'AD';'2D';'3D';'4D';'5D';'6D';'7D';'8D';'9D';'TD';'JD';'QD';'KD'; ...
    'AC';'2C';'3C';'4C';'5C';'6C';'7C';'8C';'9C';'TC';'JC';'QC';'KC'];
%deck of 52 cards
total_runs=10000;
n=0;
for i=1:total_runs
  index=randperm(52);
  shuffle=DECK(index);
%shuffles the 52 columns 
  b=shuffle(1:5);
%chooses the first 5 cards
d=sort(b);

 if d(1)==d(2)==d(3)==d(4)||d(2)==d(3)==d(4)==d(5)
   %attempt to determine 4 of a kind
   disp(d);
   n=n+1;
 end
end
 prob=n/total_runs

Upvotes: 1

Views: 2038

Answers (3)

TimK
TimK

Reputation: 11

I was wracking my head about this for the last 30 minutes, and I began to wonder, why do we need to specify the suit? He can simply get a vector of [1 through 13 ... 1 through 13] with size 1x52 and use randperm(52,5). Or as follows:

DECK = [1 2 3 4 5 6 7 8 9 10 11 12 13 1 2 3 4 5 6 7 8 9 10 11 12 13 ...
1 2 3 4 5 6 7 8 9 10 11 12 13 1 2 3 4 5 6 7 8 9 10 11 12 13];
draw = randperm(52,5);
for k = 1:5;
   hand(k) = DECK(draw(k));
end

Then you can check the first two indices of hand() and compare to hand; or:

for i=1:2
   if sum(hand(i)==hand) == 4
      n = n+1;
   end
end

I think this way is short enough, though it would be more ideal to compare column or row values. This takes about 1 second to run N=100,000 iterations on an i5 5th gen. When I set it for 10 million iterations, I'm getting about 0.04% success, which is quite higher than the theoretical 0.02401%. My first attempt comes out likes this:

hand = randperm(52,5);
for k=1:5
   match = 0;
   for i=1:3
      if sum(hand(k)+13*i == hand) > 0
         match = match+1;
      end
   end
   if match == 3
      four = four +1;
   end
end
prob = four/N;

I like this one because I don't need to waste space with a large vector; however, it takes more processing power because of the 15 loops/more comparisons. I'm getting about 0.024% success over N=100,000 iterations for this one, which is almost on-the-dot with theory. The idea with the inner-most loop is that one of the cards in a four-of-a-kind will be equal to another card when you add 13*a to it, where a = 1,2,3. This method took me almost an hour to write since I was getting a little deep with the loops. Please met me know of any concerns with the code, it's greatly appreciated.

edit: Haha I just realized that I am replicating results with my first script. Let's do it like this:

for i=1:2
   if sum(hand(i)==hand) == 4
      n = n+1;
   end
end

should be:

if sum(hand(1)==hand) == 4
   n = n+1;
elseif sum(hand(2)==hand) == 4
   n = n+1;
end

something like that.

Upvotes: 1

Anoop
Anoop

Reputation: 5720

Thanks for posting an interesting question.

I somewhat find mixing strings and integers bit awkward to work with in MATLAB. However this problem is solvable if we consider only integers from 1 to 52.

% 1 through 52
% ['AH';'2H';'3H';'4H';'5H';'6H';'7H';'8H';'9H';'TH';'JH';'QH';'KH'; ...
%     'AS';'2S';'3S';'4S';'5S';'6S';'7S';'8S';'9S';'TS';'JS';'QS';'KS'; ...
%     'AD';'2D';'3D';'4D';'5D';'6D';'7D';'8D';'9D';'TD';'JD';'QD';'KD'; ...
%     'AC';'2C';'3C';'4C';'5C';'6C';'7C';'8C';'9C';'TC';'JC';'QC';'KC'];
%deck of 52 cards . . from wikipedia
total_runs=2598960;
n=0;
for i=1:total_runs
  index=randperm(52,5);
  value = mod(index-1, 14);

 if length(unique(value)) == 2
   %attempt to determine 4 of a kind
   n=n+1;
 end
end
 prob=n/total_runs

EDIT:

corrected to length(unique(value)) == 2 The probability that this gave is between 0.1% and 0.2%.Which seems reasonable.

However it should not be mod 13, because we want 13 distinct values for each color right .

Upvotes: -1

Ben Voigt
Ben Voigt

Reputation: 283783

You can't chain comparisons like that. You wrote:

d(1)==d(2)==d(3)==d(4)

But d(1) == d(2) evaluates to a logical, either true or false. That won't be equal to d(3).

Since they're sorted, you can just test

d(1)==d(4) || d(2)==d(5)

Upvotes: 1

Related Questions