I didn’t find this problem particularly difficult, but it certainly is quite tedious.
On the Project Euler site, it is rated as a 10% difficulty problem.
I’ve never made a poker-style game before, but determining who wins according to poker rules is the most important part of a poker game. Everything else is just the interface.
This problem is quite long.
Ultimately, the main point is to determine how many times the first player wins based on the given cards.
In fact, creating this kind of judging system isn’t just about brute force. The challenge for a programmer is to figure out how to make it more efficient. Even if you do create a brute-force implementation in a poker-style game, it’s not like it will be significantly slower than an efficient version. The code size might be smaller and it might run a bit faster, but in a graphical game, you would never notice such performance differences. We’re talking about a difference of maybe 0.00001 seconds—minuscule compared to graphical resource loads.
In a way, trying to build a more efficient logic might just be a programmer’s pride or obsession.
What I did was to first determine what kind of hand the player has in poker, then assign a score based on that type. If the hand types are different, the one with the higher-ranked hand wins. If they are the same, the one with the higher score wins. A brute-force implementation would be longer, but I tried to write it relatively concisely.
//------------------------------------------------
// Project Euler #54 - Poker Hands
// - by Aubrey Choi
// - created at 2015-03-31
//------------------------------------------------
#include <stdio.h>
#include <string.h>
#define FN "p054_poker.txt"
struct Cards
{
int numbers;
int straight;
int suits[4];
int flush;
int pairs[14];
int paircount;
int triple;
int pairbit;
int kind;
};
int GetScore(Cards &c);
int main()
{
int win = 0;
int number[128];
int suit[128];
const char *res[10] = { "", "HIGH", "ONEP", "TWOP", "TRIP", "STRA", "FLUS", "FULL", "FOUR", "STFL" };
for( int i = 2 ; i < 10 ; i++ ) number[i+'0'] = i-1;
number['T'] = 9; number['J'] = 10; number['Q'] = 11; number['K'] = 12;
number['A'] = 13;
suit['S'] = 0; suit['D'] = 1; suit['H'] = 2; suit['C'] = 3;
FILE *fi = fopen(FN, "r");
char line[128];
while( fgets(line, 128, fi) )
{
Cards cards[2];
memset(cards, 0, sizeof(cards));
char *tok = strtok(line, " \n\r");
for( int i = 0 ; i < 10 ; i++, tok = strtok(0, " \n\r") )
{
printf("%s ", tok);
int n = number[*tok], s = suit[*(tok+1)];
cards[i/5].numbers |= 1<<n; if( n == 13 ) cards[i/5].numbers |= 1;
cards[i/5].suits[s]++;
cards[i/5].pairs[n]++;
}
int score1 = GetScore(cards[0]);
int score2 = GetScore(cards[1]);
printf("%s, %s, %d %d\n", res[cards[0].kind], res[cards[1].kind], score1, score2);
if( cards[0].kind > cards[1].kind ) win++;
else if( cards[0].kind == cards[1].kind && score1 > score2 ) win++;
}
fclose(fi);
printf("ans = %d\n", win);
}
int GetScore(Cards &c)
{
for( int i = 1 ; i <= 13 ; i++ ) if( ((c.numbers>>i) & 0x1f) == 0x1f ) c.straight = i+4;
for( int i = 0 ; i < 4 ; i++ ) if( c.suits[i] == 5 ) c.flush = 1;
if( c.straight && c.flush ) { c.kind = 9; return c.straight; }
for( int i = 1 ; i <= 13 ; i++ )
{
if( c.pairs[i] == 4 ) { c.kind = 8; return i; }
else if( c.pairs[i] == 3 ) { c.triple = i; c.numbers &= ~(1<<i); }
else if( c.pairs[i] == 2 ) { c.paircount++; c.pairbit |= 1<<i; c.numbers &= ~(1<<i); }
}
if( c.triple && c.pairbit ) { c.kind = 7; return c.triple; }
if( c.flush ) { c.kind = 6; return c.numbers; }
if( c.straight ) { c.kind = 5; return c.straight; }
if( c.triple ) { c.kind = 4; return c.triple; }
if( c.paircount == 2 ) { c.kind = 3; return (c.pairbit<<12) + (c.numbers>>1); }
if( c.paircount == 1 ) { c.kind = 2; return (c.pairbit<<12) + (c.numbers>>1); }
c.kind = 1; return c.numbers;
}
Here is a part of the result from running the program.
'Programming > Project Euler' 카테고리의 다른 글
[C++/Python] Project Euler #56 - Powerful Digit Sum (0) | 2025.05.03 |
---|---|
[C++/Python] Project Euler #55 - Lychrel Numbers (0) | 2025.04.23 |
[C/C++] Project Euler #53 - Combinatoric Selections (0) | 2025.04.18 |
[C/C++] Project Euler #52 - Permuted Multiples (0) | 2025.04.04 |
[C/C++] Project Euler #51 - Prime Digit Replacements (0) | 2025.03.30 |