==== 소감 ==== 2005/03/02 Accepted 0:00.000 64 가까스로 버그를 잡았지만 난잡한 소스가 그다지 맘에 들지 않는다. 어떻게 하면 보다 효율적으로 포커패의 족보를 검사해 낼 수 있을까? ==== 코드 ==== {{{~cpp // no10315 - Poker Hands #include #include using namespace std; enum {HighCard, OnePair, TwoPairs, ThreeCard, Straight, Flush, FullHouse, FourCard, StraightFlush}; const int NONE = 0; const int TIED = 2; const int BLACK = -1; const int WHITE = 1; struct Poker { int value[5]; int rank[6]; }; inline int comp(const void *i,const void *j) { return *(int *)i-*(int *)j; }; int compare(Poker & b, Poker & w); void interpret(bool b, bool w, int & result); void rankCompare(Poker & b, Poker & w, int & result); void showResult(int & result); bool straightFlush(Poker & po); bool fourCard(Poker & po); bool fullHouse(Poker & po); bool flush(Poker & po); bool straight(Poker & po); bool threeCard(Poker & po); bool twoPair(Poker & po); bool onePair(Poker & po); bool highCard(Poker & po); int main() { Poker black, white; // 입력 char values[] = "23456789TJQKA"; char str[30], suit; int count, i, j; while(cin.getline(str, 30, '\n')) { for (i=0; i<6; i++) black.rank[i] = white.rank[i] = 0; count = 0; suit = str[1]; black.rank[0] = white.rank[0] = Flush; for (i=0; i<15; i+=2) { for (j=0; j<13; j++) { if (str[i] == values[j]) { black.value[count++] = j; i++; break; } } if (suit != str[i]) black.rank[0] = HighCard; } count = 0; suit = str[16]; for (i=15; i<30; i+=2) { for (j=0; j<13; j++) { if (str[i] == values[j]) { white.value[count++] = j; i++; break; } } if (suit != str[i]) white.rank[0] = HighCard; } // 소트 qsort(black.value, 5, sizeof(int), comp); qsort(white.value, 5, sizeof(int), comp); // 처리 int result = compare(black, white); showResult(result); } return 0; } int compare(Poker & b, Poker & w) { int result = false; if (!result) interpret(straightFlush(b), straightFlush(w), result); if (!result) interpret(fourCard(b), fourCard(w), result); if (!result) interpret(fullHouse(b), fullHouse(w), result); if (!result) interpret(flush(b), flush(w), result); if (!result) interpret(straight(b), straight(w), result); if (!result) interpret(threeCard(b), threeCard(w), result); if (!result) interpret(twoPair(b), twoPair(w), result); if (!result) interpret(onePair(b), onePair(w), result); if (!result) interpret(highCard(b), highCard(w), result); if (result == BLACK || result == WHITE) return result; else rankCompare(b, w, result); return result; } void interpret(bool b, bool w, int & result) { if (b && w) result = TIED; else if (b && !w) result = BLACK; else if (!b && w) result = WHITE; else result = NONE; } void rankCompare(Poker & b, Poker & w, int & result) { result = NONE; for (int i=0; i<6; i++) { if (b.rank[i] > w.rank[i]) { result = BLACK; break; } else if (b.rank[i] < w.rank[i]) { result = WHITE; break; } } if (result != BLACK && result != WHITE) result = TIED; } bool straightFlush(Poker & po) { if (flush(po) && straight(po)) { po.rank[0] = StraightFlush; po.rank[1] = po.value[4]; po.rank[2] = po.value[3]; po.rank[3] = po.rank[4] = po.rank[5] = 0; return true; } return false; } bool fourCard(Poker & po) { int count = 1; for (int i=0; i<4; i++) { if (po.value[i] == po.value[i+1]) count++; else count = 1; if (count == 4) break; } if (count == 4) { po.rank[0] = FourCard; if (po.value[0] =! po.value[1]) { po.rank[1] = po.value[1]; po.rank[2] = po.value[0]; } else { po.rank[1] = po.value[0]; po.rank[2] = po.value[4]; } po.rank[3] = po.rank[4] = po.rank[5] = 0; return true; } return false; } bool fullHouse(Poker & po) { int kind = 1; for (int i=0; i<4; i++) { if (po.value[i] != po.value[i+1]) kind++; } if (kind == 2) { po.rank[0] = FullHouse; if (po.value[1] != po.value[2]) { po.rank[1] = po.value[2]; po.rank[2] = po.value[1]; } else if (po.value[0] != po.value[1]) { po.rank[1] = po.value[1]; po.rank[2] = po.value[0]; } else { po.rank[1] = po.value[1]; po.rank[2] = po.value[4]; } po.rank[3] = po.rank[4] = po.rank[5] = 0; return true; } return false; } bool threeCard(Poker & po) { int count = 1; int i; for (i=0; i<4; i++) { if (po.value[i] == po.value[i+1]) count++; else count = 1; if (count == 3) break; } if (count == 3) { po.rank[0] = ThreeCard; if (i == 3) { po.rank[1] = po.value[2]; po.rank[2] = po.value[1]; po.rank[3] = po.value[0]; } else if (i == 2) { po.rank[1] = po.value[1]; po.rank[2] = po.value[4]; po.rank[3] = po.value[0]; } else if (i == 1) { po.rank[1] = po.value[0]; po.rank[2] = po.value[4]; po.rank[3] = po.value[3]; } po.rank[4] = po.rank[5] = 0; return true; } return false; } bool twoPair(Poker & po) { int kind = 0; int stickCount = 0; int stick[2]; for (int i=0; i<4; i++) { if (po.value[i] != po.value[i+1]) { stick[stickCount++] = i; kind++; } } if (kind == 2) { po.rank[0] = TwoPairs; if (stick[0] == 1 && stick[1] == 2) { po.rank[1] = po.value[4]; po.rank[2] = po.value[0]; po.rank[3] = po.value[2]; } else if (stick[0] == 0 && stick[1] == 2) { po.rank[1] = po.value[4]; po.rank[2] = po.value[1]; po.rank[3] = po.value[0]; } else { po.rank[1] = po.value[2]; po.rank[2] = po.value[0]; po.rank[3] = po.value[4]; } po.rank[4] = po.rank[5] = 0; return true; } return false; } bool straight(Poker & po) { int count = 0; for (int i=0; i<4; i++) { if (po.value[i] + 1 == po.value[i+1]) count++; } if (count == 4 || (count == 3 && po.value[4] == 12 && po.value[0] == 0)) { po.rank[0] = Straight; po.rank[1] = po.value[4]; po.rank[2] = po.value[3]; po.rank[3] = po.rank[4] = po.rank[5] = 0; return true; } return false; } bool flush(Poker & po) { if (po.rank[0] == Flush) { for (int i=0; i<5; i++) po.rank[i+1] = po.value[4-i]; return true; } return false; } bool onePair(Poker & po) { int kind = 0; int i; for (i=0; i<4; i++) { if (po.value[i] == po.value[i+1]) { kind++; break; } } if (kind == 1) { po.rank[0] = OnePair; switch (i) { case 0: po.rank[1] = po.value[0]; po.rank[2] = po.value[4]; po.rank[3] = po.value[3]; po.rank[4] = po.value[2]; break; case 1: po.rank[1] = po.value[1]; po.rank[2] = po.value[4]; po.rank[3] = po.value[3]; po.rank[4] = po.value[0]; break; case 2: po.rank[1] = po.value[2]; po.rank[2] = po.value[4]; po.rank[3] = po.value[1]; po.rank[4] = po.value[0]; break; case 3: po.rank[1] = po.value[4]; po.rank[2] = po.value[2]; po.rank[3] = po.value[1]; po.rank[4] = po.value[0]; break; } po.rank[5] = 0; return true; } return false; } bool highCard(Poker & po) { po.rank[0] = HighCard; for (int i=0; i<5; i++) { po.rank[i+1] = po.value[4-i]; } return true; } void showResult(int & result) { switch (result) { case BLACK: cout << "Black wins.\n"; break; case WHITE: cout << "White wins.\n"; break; case TIED: cout << "Tie.\n"; break; } } }}} ---- [PokerHands] [문보창]