ViVi Home > 技術文書 > さくさく理解できる C/C++ コンソールアプリ入門 > ポーカー役判定
ポーカーの役判定アルゴリズムを示す。
enum { HIGH_CARD = 0, ONE_PAIR, TWO_PAIR, THREE_OF_A_KIND, STRAIGHT, FLUSH, FULL_HOUSE, FOUR_OF_A_KIND, STRAIGHT_FLUSH, N_KIND_HAND, }; // v のサイズは 7以下とする // 要素はソートされていないものとする int checkHand(const std::vector<Card> &v) { std::vector<int> rcnt(13, 0); std::vector<int> scnt(4, 0); //int rcnt[13] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //int scnt[4] = {0, 0, 0, 0}; for (uint i = 0; i < v.size(); ++i) { const Card c = v[i]; rcnt[c.m_rank] += 1; scnt[c.m_suit] += 1; } int s = -1; if( scnt[s = 0] >= 5 || scnt[s = 1] >= 5 || scnt[s = 2] >= 5 || scnt[s = 3] >= 5 ) { // フラッシュ確定 uint bitmap = 0; for (uint i = 0; i < v.size(); ++i) { const Card c = v[i]; if( c.m_suit == s ) bitmap |= 1 << (c.m_rank); } uint mask = 0x1f00; // AKQJT for (int i = 0; i < 9; ++i, mask>>=1) { if( (bitmap & mask) == mask ) { return STRAIGHT_FLUSH; } } if( bitmap == 0x100f )// 1 0000 00000 1111 = A5432 return STRAIGHT_FLUSH; } else s = -1; int threeOfAKindIX = -1; int pairIX1 = -1; int pairIX2 = -1; for (int i = 0; i < 13; ++i) { switch( rcnt[i] ) { case 4: return FOUR_OF_A_KIND; case 3: threeOfAKindIX = i; break; case 2: pairIX2 = pairIX1; pairIX1 = i; break; } } if( threeOfAKindIX >= 0 && pairIX1 >= 0 ) return FULL_HOUSE; if( s >= 0 ) return FLUSH; uint bitmap = 0; uint mask = 1; for (int i = 0; i < 13; ++i, mask<<=1) { if( rcnt[i] != 0 ) bitmap |= mask; } mask = 0x1f00; // AKQJT for (int i = 0; i < 9; ++i, mask>>=1) { if( (bitmap & mask) == mask ) return STRAIGHT; } if( bitmap == 0x100f )// 1 0000 00000 1111 = A5432 return STRAIGHT; if( threeOfAKindIX >= 0 ) return THREE_OF_A_KIND; if( pairIX2 >= 0 ) return TWO_PAIR; if( pairIX1 >= 0 ) return ONE_PAIR; return HIGH_CARD; }