目次
ポーカー:役判定(難易度:★★★☆☆)
問題
引数で与えられたカード配列の役を判定する関数 int checkHand(const vector<Card>& v) を実装しなさい。
ただし、無役は0を、ワンペアは1を、…、ストレートフラッシュは8を返すものとする(テストコードのポーカー役 enum 参照)。
また、Card は一枚のカードを表す構造体で、スート(マーク)とランク(数字)から構成される(テストコードの Card 構造体参照)。
#include <iostream> // 標準入出力ライブラリ #include <string> #include <vector> using namespace std; // std 名前空間使用 #define DO_TEST(exp) do_test(exp, __LINE__) void do_test(bool b, int line) { if( b ) return; // OK cout << "\nNG at line " << line << "\n"; exit(1); } typedef unsigned int uint; 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, // 役種類数 SPADES = 0, // スペード CLUBS, HEARTS, DIAMONDS, N_SUIT, // スート(マーク)種類数 RANK_BLANK = -1, RANK_2 = 0, RANK_3, RANK_4, RANK_5, RANK_6, RANK_7, RANK_8, RANK_9, RANK_10, RANK_J, RANK_Q, RANK_K, RANK_A, N_RANK, // 数字種類数 N_CARD = N_SUIT * N_RANK, // 全カード枚数 }; // 1枚のカードを表す構造体(ジョーカーは除く) struct Card { public: Card(char suit = 0, char rank = -1) : m_suit(suit), m_rank(rank) {} void print() const { std::cout << toString(); } void printW() const; std::string toString() const { if( m_suit < 0 || m_suit >= N_SUIT || m_rank < 0 || m_rank >= N_RANK ) return std::string("??"); std::string str(1, "SCHD"[m_suit]); str += "23456789TJQKA"[m_rank]; return str; } int numRank() const { return m_rank + (2-RANK_2); } // A は 14 を返す bool operator==(const Card &x) const { return m_suit == x.m_suit && m_rank == x.m_rank; } public: char m_suit; // スート(マーク) char m_rank; // 0: 2,… 7: 9, 8:10, 9:J, 10:Q, 11:K, 12:A }; typedef std::vector<Card> Cards; int checkHand(const Cards& v) { // ToDo: return HIGH_CARD; } int main() { DO_TEST(checkHand(Cards{ {SPADES, RANK_A}, {SPADES, RANK_2}, {CLUBS, RANK_4}, {CLUBS, RANK_6}, {HEARTS, RANK_Q} }) == HIGH_CARD); DO_TEST(checkHand(Cards{ {SPADES, RANK_7}, {CLUBS, RANK_10}, {DIAMONDS, RANK_6}, {SPADES, RANK_5}, {HEARTS, RANK_8} }) == HIGH_CARD); DO_TEST(checkHand(Cards{ {SPADES, RANK_Q}, {SPADES, RANK_2}, {CLUBS, RANK_4}, {CLUBS, RANK_6}, {HEARTS, RANK_Q} }) == ONE_PAIR); DO_TEST(checkHand(Cards{ {SPADES, RANK_Q}, {SPADES, RANK_6}, {CLUBS, RANK_4}, {CLUBS, RANK_6}, {HEARTS, RANK_Q} }) == TWO_PAIR); DO_TEST(checkHand(Cards{ {SPADES, RANK_J}, {SPADES, RANK_6}, {CLUBS, RANK_J}, {CLUBS, RANK_A}, {HEARTS, RANK_J} }) == THREE_OF_A_KIND); DO_TEST(checkHand(Cards{ {SPADES, RANK_7}, {CLUBS, RANK_9}, {DIAMONDS, RANK_6}, {SPADES, RANK_5}, {HEARTS, RANK_8} }) == STRAIGHT); DO_TEST(checkHand(Cards{ {SPADES, RANK_A}, {CLUBS, RANK_2}, {DIAMONDS, RANK_3}, {SPADES, RANK_5}, {HEARTS, RANK_4} }) == STRAIGHT); DO_TEST(checkHand(Cards{ {SPADES, RANK_Q}, {SPADES, RANK_2}, {SPADES, RANK_4}, {SPADES, RANK_6}, {SPADES, RANK_Q} }) == FLUSH); DO_TEST(checkHand(Cards{ {SPADES, RANK_Q}, {SPADES, RANK_6}, {CLUBS, RANK_Q}, {CLUBS, RANK_6}, {HEARTS, RANK_Q} }) == FULL_HOUSE); DO_TEST(checkHand(Cards{ {SPADES, RANK_J}, {SPADES, RANK_6}, {CLUBS, RANK_J}, {DIAMONDS, RANK_J}, {HEARTS, RANK_J} }) == FOUR_OF_A_KIND); DO_TEST(checkHand(Cards{ {SPADES, RANK_10}, {SPADES, RANK_J}, {SPADES, RANK_Q}, {SPADES, RANK_K}, {SPADES, RANK_A} }) == STRAIGHT_FLUSH); cout << "\nGood Job!\n"; return 0; }
競技プログラミング風 標準C++ライブラリ入門 連載目次リンク
![]() |
筆者:津田伸秀 プロフィール:テニス・オセロ・ボードゲーム・パズル類が趣味の年齢不詳のおじさん。 自宅研究員(主席)。vi と C++が好き。迷走中・・・ ボードゲーム・パズル系アプリ開発・リリースしてます。 |