競技プログラミング風 C++問題集【第15回】


目次

ポーカー:役判定(難易度:★★★☆☆)

問題

引数で与えられたカード配列の役を判定する関数 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++問題集【第16回】

目次 0/1ナップサック問題(難易度:★★★★☆) 0/1ナップサック問題(難易度:★★★★☆) 関連記事 筆者:津田伸秀 プロフィール:テニス・オセロ・ボードゲーム・パズル類が趣味の年齢不詳のおじさん。 自宅研究員(主 […]
コメントなし

競技プログラミング風 C++問題集【第15回】

目次 ポーカー:役判定(難易度:★★★☆☆) ポーカー:役判定(難易度:★★★☆☆) 関連記事 筆者:津田伸秀 プロフィール:テニス・オセロ・ボードゲーム・パズル類が趣味の年齢不詳のおじさん。 自宅研究員(主席)。vi […]
コメントなし

競技プログラミング風 C++問題集【第14回】

目次 無向グラフ(難易度:★★★☆☆) 無向グラフ(難易度:★★★☆☆) 関連記事 筆者:津田伸秀 プロフィール:テニス・オセロ・ボードゲーム・パズル類が趣味の年齢不詳のおじさん。 自宅研究員(主席)。vi と C++が […]
コメントなし

競技プログラミング風 C++問題集【第13回】

はじめに 今回から4回にわたって「競技プログラミング風 C++問題集 第13回~第16回(シーズン4)」をお届けする。 各問題は、「問題文」「テストコード」「ヒント」「解答例」「解説」から構成される。 まず、問題を読んで […]
コメントなし

競技プログラミング風 C++問題集【第12回】

目次 文字列比較(難易度:★★★★☆) 文字列比較(難易度:★★★★☆) 関連記事 筆者:津田伸秀 プロフィール:テニス・オセロ・ボードゲーム・パズル類が趣味の年齢不詳のおじさん。 自宅研究員(主席)。vi と C++が […]
コメントなし

競技プログラミング風 C++問題集【第11回】

目次 クローズド・ナイト・ツアー(難易度:★★★★☆) クローズド・ナイト・ツアー(難易度:★★★★☆) 関連記事 筆者:津田伸秀 プロフィール:テニス・オセロ・ボードゲーム・パズル類が趣味の年齢不詳のおじさん。 自宅研 […]
コメントなし

競技プログラミング風 C++問題集【第10回】

目次 オセロ:石反転(難易度:★★★☆☆) 両端キュー(難易度:★★★☆☆) オセロ:石反転(難易度:★★★☆☆) 両端キュー(難易度:★★★☆☆) 関連記事 筆者:津田伸秀 プロフィール:テニス・オセロ・ボードゲーム・ […]
コメントなし

競技プログラミング風 C++問題集【第9回】

はじめに 今回から4回にわたって「競技プログラミング風 C++問題集 第9回~第12回(シーズン3)」をお届けする。 各問題は、「問題文」「テストコード」「ヒント」「解答例」「解説」から構成される。 まず、問題を読んで正 […]
コメントなし

競技プログラミング風 C++問題集【第8回】

目次 文字列クラス(難易度:★★★★☆) 文字列クラス(難易度:★★★★☆) 関連記事 筆者:津田伸秀 プロフィール:テニス・オセロ・ボードゲーム・パズル類が趣味の年齢不詳のおじさん。 自宅研究員(主席)。vi と C+ […]
コメントなし

競技プログラミング風 C++問題集【第7回】

目次 数独(難易度:★★★☆☆) 数独(難易度:★★★☆☆) 関連記事 筆者:津田伸秀 プロフィール:テニス・オセロ・ボードゲーム・パズル類が趣味の年齢不詳のおじさん。 自宅研究員(主席)。vi と C++が好き。迷走中 […]
コメントなし
筆者:津田伸秀
プロフィール:テニス・オセロ・ボードゲーム・パズル類が趣味の年齢不詳のおじさん。 自宅研究員(主席)。vi と C++が好き。迷走中・・・ ボードゲーム・パズル系アプリ開発・リリースしてます。
  • このエントリーをはてなブックマークに追加

PAGE TOP