## 131 - The Psychic Poker Player

Moderator: Board moderators

C8H10N4O2
Experienced poster
Posts: 137
Joined: Wed Feb 27, 2002 2:00 am

### 131 The Psychic Poker Player

[cpp]
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <algorithm>

using namespace std;

void main()
{
char SB;
int i,j,k;
vector<vector<char> > Cards(10,vector<char>(2,' '));
vector<vector<char> > Hand;
vector<int> FaceValue(14,0);
vector<int> SuitValue(4,0);
int Evaluation;
while(scanf("%s",SB)!=EOF)
{
Cards=SB;
Cards=SB;
for(i=1;i<10;i++)
{
scanf("%s",SB);
Cards=SB;
Cards=SB;
}
printf("Hand: ");
for(i=0;i<5;i++)
{
printf("%c%c ",Cards,Cards);
}
printf("Deck: ");
for(i=5;i<10;i++)
{
printf("%c%c ",Cards,Cards);
}
printf("Best hand: ");
Evaluation=0;
for(i=0;i<1<<5;i++)
{
Hand.clear();
for(j=0;j<5;j++)
{
if(i&1<<j)
{
Hand.push_back(Cards[j]);
}
}
for(j=Hand.size(),k=5;j<5;j++,k++)
{
Hand.push_back(Cards[k]);
}
fill(FaceValue.begin(),FaceValue.end(),0);
fill(SuitValue.begin(),SuitValue.end(),0);
for(j=0;j<Hand.size();j++)
{
switch(Hand[j])
{
case 'A':
FaceValue++;
break;
case 'T':
FaceValue++;
break;
case 'J':
FaceValue++;
break;
case 'Q':
FaceValue++;
break;
case 'K':
FaceValue++;
break;
default:
FaceValue[Hand[j]-'1']++;
}
switch(Hand[j])
{
case 'H':
SuitValue++;
break;
case 'C':
SuitValue++;
break;
case 'S':
SuitValue++;
break;
case 'D':
SuitValue++;
break;
}
}
if(count(FaceValue.begin(),FaceValue.end(),4)>0)
{
Evaluation|=1<<7;
}
if(count(FaceValue.begin(),FaceValue.end(),3)>0&&count(FaceValue.begin(),FaceValue.end(),2)>0)
{
Evaluation|=1<<6;
}
if(count(SuitValue.begin(),SuitValue.end(),5)>0)
{
Evaluation|=1<<5;
}
if(count(FaceValue.begin(),FaceValue.end(),3)>0)
{
Evaluation|=1<<3;
}
if(count(FaceValue.begin(),FaceValue.end(),2)>1)
{
Evaluation|=1<<2;
}
if(count(FaceValue.begin(),FaceValue.end(),2)>0)
{
Evaluation|=1<<1;
}
FaceValue=FaceValue;
for(j=0;j<10;j++)
{
if(FaceValue[j]&&FaceValue[j+1]&&FaceValue[j+2]&&FaceValue[j+3]&&FaceValue[j+4])
{
Evaluation|=1<<4;
}
}
}
if((Evaluation&(1<<4|1<<5))==(1<<4|1<<5))
{
printf("straight-flush");
}
else if((Evaluation&(1<<7))==(1<<7))
{
printf("four-of-a-kind");
}
else if((Evaluation&(1<<6))==(1<<6))
{
printf("full-house");
}
else if((Evaluation&(1<<5))==(1<<5))
{
printf("flush");
}
else if((Evaluation&(1<<4))==(1<<4))
{
printf("straight");
}
else if((Evaluation&(1<<3))==(1<<3))
{
printf("three-of-a-kind");
}
else if((Evaluation&(1<<2))==(1<<2))
{
printf("two-pairs");
}
else if((Evaluation&(1<<1))==(1<<1))
{
printf("one-pair");
}
else
{
printf("highest-card");
}
printf("\n");
}
}
[/cpp]

C8H10N4O2
Experienced poster
Posts: 137
Joined: Wed Feb 27, 2002 2:00 am
Stefan Pochmann...take a break from TC and come help:)

Stefan Pochmann
A great helper
Posts: 284
Joined: Thu Feb 28, 2002 2:00 am
Location: Germany
Contact:

There are two things I noticed:
+ My own solution says "straight flush" only if I got 10 to Ace, not for any other sequence.
+ What if you set (1<<5) with one hand and (1<<4) with a different one?

C8H10N4O2
Experienced poster
Posts: 137
Joined: Wed Feb 27, 2002 2:00 am
Thank you!

I am both a horrible programmer and a horrible card player at the same time:)

Stefan Pochmann
A great helper
Posts: 284
Joined: Thu Feb 28, 2002 2:00 am
Location: Germany
Contact:
I see you got it right... what was the mistake? Btw, I thought Caesum had posted an answer, too. Did he delete it?

C8H10N4O2
Experienced poster
Posts: 137
Joined: Wed Feb 27, 2002 2:00 am
You pinpointed the 2 exact mistakes. I was counting flushes and straights together and thus 2H 3H 4H 5H 7H 2S 3D 4S 5D 6S was being counted as a straight flush. Also, apparently your first rule was also correct. Only 10-A are counted as a straight flush. Go figure:p

Caesum
Experienced poster
Posts: 225
Joined: Fri May 03, 2002 12:14 am
Location: UK
Contact:
actually i did, but i realised that the precedence which i posted about was correct..... but personally i always bracket when messing with <<.

Also, my program does call any run and a flush a straight flush so I can't understand why you couldnt get it accepted doing that.

zoho ho
New poster
Posts: 4
Joined: Tue Aug 13, 2002 10:11 pm

### 131 - The Psychic Poker Player

My english is poor I see 130 again and again but I just can not
understand how to simulate it, if you know, please tell me.

/**********************/
and about 131 , do it have any special case or trap, I just get lots WA!

here is my code for 131
I use c but send c++ /*@judge_id: 9948XX 131 c++*/
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#include<search.h>

/*global*/
char pile, test_data ;
long ans ;

long i ;
if(scanf("%s", pile) == EOF) exit(1) ;
for(i=1 ; i<10 ; i++) scanf("%s", pile) ;
}

void deal(char hand){
long i ;
for(i=0 ; i<5 ; i++) {
switch(hand){
case 'A' : hand = 'a' ; break ;
case '2' : hand = 'b' ; break ;
case '3' : hand = 'c' ; break ;
case '4' : hand = 'd' ; break ;
case '5' : hand = 'e' ; break ;
case '6' : hand = 'f' ; break ;
case '7' : hand = 'g' ; break ;
case '8' : hand = 'h' ; break ;
case '9' : hand[i] = 'i' ; break ;
case 'T' : hand[i] = 'j' ; break ;
case 'J' : hand[i] = 'k' ; break ;
case 'Q' : hand[i] = 'l' ; break ;
case 'K' : hand[i] = 'm' ; break ;
}
}
}

int compare(const void *a, const void *b){
if(*(char*)a!=*(char*)b)
return *(char*)a - *(char*)b ;
else
return *((char*)a+1) - *((char*)b+1) ;
}

long t7(char hand){
if((hand==hand)&&(hand==hand)&&(hand==hand))
return 1 ;
if((hand==hand)&&(hand==hand)&&(hand==hand))
return 1 ;
return 0 ;
}

long t6(char hand){
if((hand==hand)&&(hand==hand))
if(hand==hand)
return 1 ;
if((hand==hand)&&(hand==hand))
if(hand==hand)
return 1 ;
return 0 ;
}

long t5(char hand){
long i ;
char ch=hand ;
for(i=1 ; i<5 ; i++) if(hand[i]!=ch) return 0 ;
return 1 ;
}

long t4(char hand){
long i, judge ;
for(i=judge=1 ; i<4 ; i++){
if(hand[i]+1 != hand[i+1]) judge = 0 ;
if(judge==0) return 0 ;
}
if(judge){
if(hand+1 == hand) return 1 ;
if((hand=='a')&&(hand=='m')) return 1 ;
}
return 0 ;
}

long t3(char hand){
if((hand==hand)&&(hand==hand))
return 1 ;
if((hand==hand)&&(hand==hand))
return 1 ;
return 0 ;
}

long t2(char hand){
long i, num ;
for(num=i=0 ; i<4 ; i++){
if(hand[i]==hand[i+1]){
i++ ;
num++ ;
}
}
if(num==2) return 1 ;
else return 0 ;
}

long t1(char hand){
long i, num ;
for(num=i=0 ; i<4 ; i++){
if(hand[i]==hand[i+1]){
i++ ;
num++ ;
}
}
if(num==1) return 1 ;
else return 0 ;
}

long t8(char hand){
long i ;
if(t5(hand)) {
if(hand=='a')
if(hand=='j')
if(hand=='k')
if(hand=='l')
if(hand=='m')
return 1 ;
}
return 0 ;
}

void examine(){
long i, j ;
char hand ;
for(i=0 ; i<5 ; i++) strcpy(hand[i], test_data[i]) ;
for(i=0, j=5 ; i<5 ; i++) if(hand[i]=='\0') strcpy(hand[i], pile[j++]) ;
/******************************/
deal(hand) ;
qsort(hand, 5, sizeof(hand), compare) ;
if(ans < 8 ) if(t8(hand)) {ans=8 ; return ;}
if(ans<7) if(t7(hand)) {ans=7 ; return ;}
if(ans<6) if(t6(hand)) {ans=6 ; return ;}
if(ans<5) if(t5(hand)) {ans=5 ; return ;}
if(ans<4) if(t4(hand)) {ans=4 ; return ;}
if(ans<3) if(t3(hand)) {ans=3 ; return ;}
if(ans<2) if(t2(hand)) {ans=2 ; return ;}
if(ans<1) if(t1(hand)) {ans=1 ; return ;}
}

long i ;
if(num==0) examine() ;
for(i=pos ; (i<5)&&(num>0) ; i++){
test_data[i] = '\0' ;
strcpy(test_data[i], pile[i]) ;
}
}

void count(){
long i ;
ans = 0 ;
for(i=0 ; i<5 ; i++) strcpy(test_data[i], pile[i]) ;
for(i=0 ; i<5 ; i++) strcpy(test_data[i], pile[i]) ;
for(i=0 ; i<5 ; i++) strcpy(test_data[i], pile[i]) ;
for(i=0 ; i<5 ; i++) strcpy(test_data[i], pile[i]) ;
for(i=0 ; i<5 ; i++) strcpy(test_data[i], pile[i]) ;
for(i=0 ; i<5 ; i++) strcpy(test_data[i], pile[i]) ;
}

void output(){
long i ;
printf("Hand: ") ;
for(i=0 ; i<5 ; i++) printf("%s ", pile[i]) ;
printf("Deck: ") ;
for( ; i<10 ; i++) printf("%s ", pile[i]) ;
printf("Best hand: ") ;
switch(ans){
case 8 : printf("straight-flush\n") ; break ;
case 7 : printf("four-of-a-kind\n") ; break ;
case 6 : printf("full-house\n") ; break ;
case 5 : printf("flush\n") ; break ;
case 4 : printf("straight\n") ; break ;
case 3 : printf("three-of-a-kind\n") ; break ;
case 2 : printf("two-pairs\n") ; break ;
case 1 : printf("one-pair\n") ; break ;
case 0 : printf("highest-card\n") ; break ;
}
}

void main(){
while(1){
count() ;
output() ;
}
}
[/cpp]
I have not ICQ or any online Messenger
If you want tell me any private you can
send mail to
u89156@ice.ntnu.edu.tw
thank you !

dawynn
New poster
Posts: 47
Joined: Fri Jun 21, 2002 3:08 pm
I haven't looked through your entire code, but the following snippet seems wrong:
case 'A' : hand = 'a' ; break ;
case '2' : hand = 'b' ; break ;
case '3' : hand = 'c' ; break ;
case '4' : hand = 'd' ; break ;
case '5' : hand = 'e' ; break ;
case '6' : hand = 'f' ; break ;
case '7' : hand = 'g' ; break ;
case '8' : hand = 'h' ; break ;
case '9' : hand = 'i' ; break ;
case 'T' : hand = 'j' ; break ;
case 'J' : hand[i] = 'k' ; break ;
case 'Q' : hand[i] = 'l' ; break ;
case 'K' : hand[i] = 'm' ; break ;

It appears that you're trying to provide a comparable ranking of the various cards. Problem is, in Poker, Aces are always high, above the king. So, you should start by setting the '2's to 'a', '3's to 'b', all the way through 'K' = 'l' and 'A' = 'm'.

David

dawynn
New poster
Posts: 47
Joined: Fri Jun 21, 2002 3:08 pm
As far as problem 130 goes, try this for an idea.

Take the input data, start your counting at position 1 with the number of people listed, killing and shifting people as described. When your simulation gets down to one person, determine that person's starting position.

Now you want to shift the calculation so that you're in the right position. Since you can't change your position, you have to change the start position of the counting. I think the calculation should be something like (n + 1) - (survivor - 1) or n + 2 - survivor.

I would use an array, keeping track of the initial starting positions in the slots. The first 'k'th person gets replaced by the 2nd 'k'th person, and everyone from the second 'k'th person gets shifted down one slot in the array. Then starting from the first 'k'th person's slot again, count for 'k' and 2'k', etc. Keep track of the max size of the array, and mod when larger than the max.

I haven't tried this problem yet, but this would be my approach.

zoho ho
New poster
Posts: 4
Joined: Tue Aug 13, 2002 10:11 pm
in 131 I think Ace is biggest or smallest is not different ?

I have see article in here about 131..

They talk about straight-flush only in '10' to 'Ace', so I think I am not familiar about poker!
In my way to play poker straight-flush contain 2H 3H 4H 5H 6H ...
because that I maybe have some bug in algorithm!

thanks your help you are very warmhearted.
I have not ICQ or any online Messenger
If you want tell me any private you can
send mail to
u89156@ice.ntnu.edu.tw
thank you !

dawynn
New poster
Posts: 47
Joined: Fri Jun 21, 2002 3:08 pm
According to http://www.poker-rulez.com/poker-basics.html, Aces are always high. They can never be considered lower than a 2.

Yes, a straight could contain a 2, 3, 4, 5, 6 or 10, J, Q, K, A. But not A, 2, 3, 4, 5. Any series of consecutive numbers can be a straight. But since the Ace is always high, you could not create a 5-card straight that contains both an Ace and a 2.

The site http://www.poker-rulez.com/poker-hands.html provides an excellent description of each of the hands available in poker. The only hand described on that page that is not supported by problem 130 is the royal flush, but it is just a variation on the straight flush.

David

zoho ho
New poster
Posts: 4
Joined: Tue Aug 13, 2002 10:11 pm
sample in
AC 2D 9C 3S KD 5S 4D KS AS 4C
sample out
Hand: AC 2D 9C 3S KD Deck: 5S 4D KS AS 4C Best hand: straight
so the 'A' to '5' is straight, you maybe not read introduction carefully dawynn
New poster
Posts: 47
Joined: Fri Jun 21, 2002 3:08 pm
I stand corrected. Yes, I would go with the order they used in the introduction. This problem obviously needs review because they call it *poker* but don't follow the rules of *poker*. Back to square one.

Strangely, the introduction indicates that an 'A'ce should be considered less than a two, but the samples show that it can be considered either greater than a king (see the Straight Flush), or less than a two (see the Straight).

OK, some of the pointer logic confuses me, but it looks like you're performing some kind of a sort to get the cards in rank order. Assuming that, I still see the following issues:

It does look like your straight flush only allows for a royal flush.
Need a third case for the three-of-a-kind, where the 2nd, 3rd, and 4th cards match.

Good luck.

PMNOX
New poster
Posts: 49
Joined: Wed Feb 13, 2002 2:00 am
Location: Poland
Contact:
is A-K-Q-J-10 STRAIGHT