Page 1 of 3
131 The Psychic Poker Player
Posted: Thu Jun 06, 2002 11:42 pm
by C8H10N4O2
Please help! I don't know poker well. Can someone tell me why this WAs?
[cpp]
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <algorithm>
using namespace std;
void main()
{
char SB[100];
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[0][0]=SB[0];
Cards[0][1]=SB[1];
for(i=1;i<10;i++)
{
scanf("%s",SB);
Cards[0]=SB[0];
Cards[1]=SB[1];
}
printf("Hand: ");
for(i=0;i<5;i++)
{
printf("%c%c ",Cards[0],Cards[1]);
}
printf("Deck: ");
for(i=5;i<10;i++)
{
printf("%c%c ",Cards[0],Cards[1]);
}
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][0])
{
case 'A':
FaceValue[0]++;
break;
case 'T':
FaceValue[9]++;
break;
case 'J':
FaceValue[10]++;
break;
case 'Q':
FaceValue[11]++;
break;
case 'K':
FaceValue[12]++;
break;
default:
FaceValue[Hand[j][0]-'1']++;
}
switch(Hand[j][1])
{
case 'H':
SuitValue[0]++;
break;
case 'C':
SuitValue[1]++;
break;
case 'S':
SuitValue[2]++;
break;
case 'D':
SuitValue[3]++;
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[13]=FaceValue[0];
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]
Posted: Mon Jun 10, 2002 10:58 pm
by C8H10N4O2
Stefan Pochmann...take a break from TC and come help:)
Posted: Tue Jun 11, 2002 12:07 am
by Stefan Pochmann
By your command, master.
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?
Posted: Tue Jun 11, 2002 2:25 am
by C8H10N4O2
Thank you!
I am both a horrible programmer and a horrible card player at the same time:)
Posted: Tue Jun 11, 2002 5:28 am
by Stefan Pochmann
I see you got it right... what was the mistake? Btw, I thought Caesum had posted an answer, too. Did he delete it?
Posted: Tue Jun 11, 2002 9:13 am
by C8H10N4O2
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
Posted: Tue Jun 11, 2002 7:02 pm
by Caesum
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.
131 - The Psychic Poker Player
Posted: Tue Aug 13, 2002 10:44 pm
by zoho ho
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[10][3], test_data[5][3] ;
long ans ;
void readdata(){
long i ;
if(scanf("%s", pile[0]) == EOF) exit(1) ;
for(i=1 ; i<10 ; i++) scanf("%s", pile
) ;
}
void deal(char hand[5][3]){
long i ;
for(i=0 ; i<5 ; i++) {
switch(hand[0]){
case 'A' : hand[0] = 'a' ; break ;
case '2' : hand[0] = 'b' ; break ;
case '3' : hand[0] = 'c' ; break ;
case '4' : hand[0] = 'd' ; break ;
case '5' : hand[0] = 'e' ; break ;
case '6' : hand[0] = 'f' ; break ;
case '7' : hand[0] = 'g' ; break ;
case '8' : hand[0] = 'h' ; break ;
case '9' : hand[i][0] = 'i' ; break ;
case 'T' : hand[i][0] = 'j' ; break ;
case 'J' : hand[i][0] = 'k' ; break ;
case 'Q' : hand[i][0] = 'l' ; break ;
case 'K' : hand[i][0] = '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[5][3]){
if((hand[0][0]==hand[1][0])&&(hand[0][0]==hand[2][0])&&(hand[0][0]==hand[3][0]))
return 1 ;
if((hand[4][0]==hand[3][0])&&(hand[4][0]==hand[2][0])&&(hand[4][0]==hand[1][0]))
return 1 ;
return 0 ;
}
long t6(char hand[5][3]){
if((hand[0][0]==hand[1][0])&&(hand[0][0]==hand[2][0]))
if(hand[3][0]==hand[4][0])
return 1 ;
if((hand[4][0]==hand[3][0])&&(hand[4][0]==hand[2][0]))
if(hand[0][0]==hand[1][0])
return 1 ;
return 0 ;
}
long t5(char hand[5][3]){
long i ;
char ch=hand[0][1] ;
for(i=1 ; i<5 ; i++) if(hand[i][1]!=ch) return 0 ;
return 1 ;
}
long t4(char hand[5][3]){
long i, judge ;
for(i=judge=1 ; i<4 ; i++){
if(hand[i][0]+1 != hand[i+1][0]) judge = 0 ;
if(judge==0) return 0 ;
}
if(judge){
if(hand[0][0]+1 == hand[1][0]) return 1 ;
if((hand[0][0]=='a')&&(hand[4][0]=='m')) return 1 ;
}
return 0 ;
}
long t3(char hand[5][3]){
if((hand[0][0]==hand[1][0])&&(hand[0][0]==hand[2][0]))
return 1 ;
if((hand[4][0]==hand[3][0])&&(hand[4][0]==hand[2][0]))
return 1 ;
return 0 ;
}
long t2(char hand[5][3]){
long i, num ;
for(num=i=0 ; i<4 ; i++){
if(hand[i][0]==hand[i+1][0]){
i++ ;
num++ ;
}
}
if(num==2) return 1 ;
else return 0 ;
}
long t1(char hand[5][3]){
long i, num ;
for(num=i=0 ; i<4 ; i++){
if(hand[i][0]==hand[i+1][0]){
i++ ;
num++ ;
}
}
if(num==1) return 1 ;
else return 0 ;
}
long t8(char hand[5][3]){
long i ;
if(t5(hand)) {
if(hand[0][0]=='a')
if(hand[1][0]=='j')
if(hand[2][0]=='k')
if(hand[3][0]=='l')
if(hand[4][0]=='m')
return 1 ;
}
return 0 ;
}
void examine(){
long i, j ;
char hand[5][3] ;
for(i=0 ; i<5 ; i++) strcpy(hand[i], test_data[i]) ;
for(i=0, j=5 ; i<5 ; i++) if(hand[i][0]=='\0') strcpy(hand[i], pile[j++]) ;
/******************************/
deal(hand) ;
qsort(hand, 5, sizeof(hand[5]), 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 ;}
}
void discard(long num, long pos){
long i ;
if(num==0) examine() ;
for(i=pos ; (i<5)&&(num>0) ; i++){
test_data[i][0] = '\0' ;
discard(num-1, i+1) ;
strcpy(test_data[i], pile[i]) ;
}
}
void count(){
long i ;
ans = 0 ;
for(i=0 ; i<5 ; i++) strcpy(test_data[i], pile[i]) ;
discard(0, 0) ;
for(i=0 ; i<5 ; i++) strcpy(test_data[i], pile[i]) ;
discard(1, 0) ;
for(i=0 ; i<5 ; i++) strcpy(test_data[i], pile[i]) ;
discard(2, 0) ;
for(i=0 ; i<5 ; i++) strcpy(test_data[i], pile[i]) ;
discard(3, 0) ;
for(i=0 ; i<5 ; i++) strcpy(test_data[i], pile[i]) ;
discard(4, 0) ;
for(i=0 ; i<5 ; i++) strcpy(test_data[i], pile[i]) ;
discard(5, 0) ;
}
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){
readdata() ;
count() ;
output() ;
}
}
[/cpp]
Posted: Wed Aug 14, 2002 5:31 pm
by dawynn
I haven't looked through your entire code, but the following snippet seems wrong:
case 'A' : hand[0] = 'a' ; break ;
case '2' : hand[0] = 'b' ; break ;
case '3' : hand[0] = 'c' ; break ;
case '4' : hand[0] = 'd' ; break ;
case '5' : hand[0] = 'e' ; break ;
case '6' : hand[0] = 'f' ; break ;
case '7' : hand[0] = 'g' ; break ;
case '8' : hand[0] = 'h' ; break ;
case '9' : hand[0] = 'i' ; break ;
case 'T' : hand[0] = 'j' ; break ;
case 'J' : hand[i][0] = 'k' ; break ;
case 'Q' : hand[i][0] = 'l' ; break ;
case 'K' : hand[i][0] = '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
Posted: Wed Aug 14, 2002 5:52 pm
by dawynn
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.
Posted: Thu Aug 15, 2002 4:35 am
by zoho ho
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.
Posted: Thu Aug 15, 2002 3:25 pm
by dawynn
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
Posted: Fri Aug 16, 2002 4:57 am
by zoho ho
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

but thanks for your help
Posted: Fri Aug 16, 2002 3:36 pm
by dawynn
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.
Posted: Fri Aug 16, 2002 3:38 pm
by PMNOX
is A-K-Q-J-10 STRAIGHT