From 52e20bac3fd60fb3cedd91670b8f130f967e76e5 Mon Sep 17 00:00:00 2001 From: Hourier Date: Sun, 22 Mar 2020 19:24:10 +0900 Subject: [PATCH] [Refactor] #40275 Separated poker.c/h from bldg.c --- Hengband_vcs2017/Hengband/Hengband.vcxproj | 2 + Hengband_vcs2017/Hengband/Hengband.vcxproj.filters | 6 + src/Makefile.am | 3 +- src/bldg.c | 691 +-------------------- src/market/poker.c | 689 ++++++++++++++++++++ src/market/poker.h | 3 + 6 files changed, 704 insertions(+), 690 deletions(-) create mode 100644 src/market/poker.c create mode 100644 src/market/poker.h diff --git a/Hengband_vcs2017/Hengband/Hengband.vcxproj b/Hengband_vcs2017/Hengband/Hengband.vcxproj index e05df72bc..50c738fef 100644 --- a/Hengband_vcs2017/Hengband/Hengband.vcxproj +++ b/Hengband_vcs2017/Hengband/Hengband.vcxproj @@ -209,6 +209,7 @@ + @@ -379,6 +380,7 @@ + diff --git a/Hengband_vcs2017/Hengband/Hengband.vcxproj.filters b/Hengband_vcs2017/Hengband/Hengband.vcxproj.filters index 468e67041..7a206b2e5 100644 --- a/Hengband_vcs2017/Hengband/Hengband.vcxproj.filters +++ b/Hengband_vcs2017/Hengband/Hengband.vcxproj.filters @@ -538,6 +538,9 @@ cmd + + market + @@ -1058,6 +1061,9 @@ cmd + + market + diff --git a/src/Makefile.am b/src/Makefile.am index d3c8f4447..2b5574c67 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -11,6 +11,7 @@ hengband_SOURCES = \ \ avatar.h avatar.c birth.c birth.h \ \ + market/poker.c market/poker.h \ bldg.c bldg.h chest.c chest.h chuukei.c chuukei.h \ \ view/display-characteristic.c view/display-characteristic.h \ @@ -162,7 +163,7 @@ EXTRA_DIST = \ CFLAGS += $(XFT_CFLAGS) LIBS += $(XFT_LIBS) COMPILE = $(srcdir)/gcc-wrap $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -Icmd -Icombat -Icore -Iio -Imonster -Iplayer -Iview + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -Icmd -Icombat -Icore -Iio -Imarket -Imonster -Iplayer -Iview install-exec-hook: if SET_GID diff --git a/src/bldg.c b/src/bldg.c index bb6ee3346..ee53c7d22 100644 --- a/src/bldg.c +++ b/src/bldg.c @@ -62,6 +62,8 @@ #include "monsterrace.h" #include "autopick.h" +#include "market/poker.h" + /* * todo MAX_BLDGが定義されていない旨のエラーが出る……がコンパイルには成功する * Buildings @@ -129,23 +131,6 @@ const arena_type arena_info[MAX_ARENA_MONS + 2] = }; /*! - * todo グローバルである必要があるか? - * ポーカーの現在の手札ID - */ -static int cards[5]; - -#define ODDS_5A 3000 /*!< ファイブエースの役倍率 */ -#define ODDS_5C 400 /*!< ファイブカードの役倍率 */ -#define ODDS_RF 200 /*!< ロイヤルストレートフラッシュの役倍率 */ -#define ODDS_SF 80 /*!< ストレートフラッシュの役倍率 */ -#define ODDS_4C 16 /*!< フォアカードの役倍率 */ -#define ODDS_FH 12 /*!< フルハウスの役倍率 */ -#define ODDS_FL 8 /*!< フラッシュの役倍率 */ -#define ODDS_ST 4 /*!< ストレートの役倍率 */ -#define ODDS_3C 1 /*!< スリーカードの役倍率 */ -#define ODDS_2P 1 /*!< ツーペアの役倍率 */ - -/*! * @brief 施設毎に設定された種族、職業、魔法領域フラグがプレイヤーと一致するかを判定する。 * @details 各種ギルドや寺院など、特定の職業ならば優遇措置を得られる施設、 * あるいは食堂など特定の種族では利用できない施設の判定処理を行う。 @@ -546,678 +531,6 @@ static void display_fruit(int row, int col, int fruit) } -/*! @note - * kpoker no (tyuto-hannpa na)pakuri desu... - * joker ha shineru node haitte masen. - * - * TODO: donataka! tsukutte! - * - agatta yaku no kiroku (like DQ). - * - kakkoii card no e. - * - sousa-sei no koujyo. - * - code wo wakariyasuku. - * - double up. - * - Joker... -- done. - * - * 9/13/2000 --Koka - * 9/15/2000 joker wo jissou. soreto, code wo sukosi kakikae. --Habu - */ - -#define SUIT_OF(card) ((card) / 13) /*!< トランプカードのスートを返す */ -#define NUM_OF(card) ((card) % 13) /*!< トランプカードの番号を返す */ -#define IS_JOKER(card) ((card) == 52) /*!< トランプカードがジョーカーかどうかを返す */ - - /*! - * @brief ポーカーの山札を切る。 - * @param deck デッキの配列 - * @return なし - */ -static void reset_deck(int deck[]) -{ - for (int i = 0; i < 53; i++) - { - deck[i] = i; - } - - for (int i = 0; i < 53; i++) { - int tmp1 = randint0(53 - i) + i; - int tmp2 = deck[i]; - deck[i] = deck[tmp1]; - deck[tmp1] = tmp2; - } -} - - -/*! - * @brief ポーカープレイ中にジョーカーを持っているかの判定を返す。 - * @return ジョーカーを持っているか。 - */ -static bool have_joker(void) -{ - for (int i = 0; i < 5; i++) - { - if (IS_JOKER(cards[i])) return TRUE; - } - - return FALSE; -} - - -/*! - * @brief ポーカーの手札に該当の番号の札があるかを返す。 - * @param num 探したいカードの番号。 - * @return 該当の番号が手札にあるか。 - */ -static bool find_card_num(int num) -{ - for (int i = 0; i < 5; i++) - { - if (NUM_OF(cards[i]) == num && !IS_JOKER(cards[i])) return TRUE; - } - - return FALSE; -} - - -/*! - * @brief ポーカーの手札がフラッシュ役を得ているかを帰す。 - * @return 役の判定結果 - */ -static bool poker_hand_check_flush(void) -{ - bool joker_is_used = FALSE; - - int suit = IS_JOKER(cards[0]) ? SUIT_OF(cards[1]) : SUIT_OF(cards[0]); - for (int i = 0; i < 5; i++) { - if (SUIT_OF(cards[i]) == suit) continue; - - if (have_joker() && !joker_is_used) - joker_is_used = TRUE; - else - return FALSE; - } - - return TRUE; -} - - -/*! - * @brief ポーカーの手札がストレートを含んだ高位の役を得ているかを帰す。 - * @return 役の判定結果 0…ストレート、フラッシュいずれもなし/1…ストレートのみ/2…ストレートフラッシュ/3…ロイヤルストレートフラッシュ - */ -static int poker_hand_check_straight(void) -{ - int lowest = 99; - bool joker_is_used = FALSE; - bool straight = FALSE; - - for (int i = 0; i < 5; i++) - { - if (NUM_OF(cards[i]) < lowest && !IS_JOKER(cards[i])) - lowest = NUM_OF(cards[i]); - } - - if (poker_hand_check_flush()) - { - int i; - if (lowest == 0) - { - for (i = 0; i < 4; i++) - { - if (!find_card_num(9 + i)) { - if (have_joker() && !joker_is_used) - joker_is_used = TRUE; - else - break; - } - } - - if (i == 4) return 3; - } - - if (lowest == 9) - { - for (i = 0; i < 3; i++) - { - if (!find_card_num(10 + i)) - break; - } - - if (i == 3 && have_joker()) return 3; - } - } - - joker_is_used = FALSE; - - if (lowest == 0) - { - int i; - for (i = 0; i < 4; i++) - { - if (!find_card_num(9 + i)) { - if (have_joker() && !joker_is_used) - joker_is_used = TRUE; - else - break; - } - } - - if (i == 4) straight = TRUE; - } - - joker_is_used = FALSE; - - int i; - for (i = 0; i < 5; i++) - { - if (!find_card_num(lowest + i)) - { - if (have_joker() && !joker_is_used) - joker_is_used = TRUE; - else - break; /* None */ - } - } - - if (i == 5) straight = TRUE; - - if (straight && poker_hand_check_flush()) return 2; /* Straight Flush */ - else if (straight) return 1; /* Only Straight */ - else return 0; -} - - -/*! - * @brief ポーカーのペア役の状態を返す。 - * @return 0:nopair 1:1 pair 2:2 pair 3:3 cards 4:full house 6:4cards - */ -static int poker_hand_check_pair(void) -{ - int matching = 0; - for (int i = 0; i < 5; i++) - { - for (int j = i + 1; j < 5; j++) - { - if (IS_JOKER(cards[i]) || IS_JOKER(cards[j])) continue; - if (NUM_OF(cards[i]) == NUM_OF(cards[j])) - matching++; - } - } - - if (have_joker()) - { - switch (matching) { - case 0: - matching = 1; - break; - case 1: - matching = 3; - break; - case 2: - matching = 4; - break; - case 3: - matching = 6; - break; - case 6: - matching = 7; - break; - default: - /* don't reach */ - break; - } - } - - return matching; -} - - -/*! - * @brief ポーカーの役をチェックし、その結果を画面に表示しつつ結果を返す。 - * @return 役のID - */ -static int poker_hand_check(void) -{ - prt(" ", 4, 3); - - switch (poker_hand_check_straight()) - { - case 3: /* RF! */ - c_put_str(TERM_YELLOW, _("ロイヤルストレートフラッシュ", "Royal Flush"), 4, 3); - return ODDS_RF; - case 2: /* SF! */ - c_put_str(TERM_YELLOW, _("ストレートフラッシュ", "Straight Flush"), 4, 3); - return ODDS_SF; - case 1: - c_put_str(TERM_YELLOW, _("ストレート", "Straight"), 4, 3); - return ODDS_ST; - default: - /* Not straight -- fall through */ - break; - } - - if (poker_hand_check_flush()) - { - c_put_str(TERM_YELLOW, _("フラッシュ", "Flush"), 4, 3); - return ODDS_FL; - } - - switch (poker_hand_check_pair()) - { - case 1: - c_put_str(TERM_YELLOW, _("ワンペア", "One pair"), 4, 3); - return 0; - case 2: - c_put_str(TERM_YELLOW, _("ツーペア", "Two pair"), 4, 3); - return ODDS_2P; - case 3: - c_put_str(TERM_YELLOW, _("スリーカード", "Three of a kind"), 4, 3); - return ODDS_3C; - case 4: - c_put_str(TERM_YELLOW, _("フルハウス", "Full house"), 4, 3); - return ODDS_FH; - case 6: - c_put_str(TERM_YELLOW, _("フォーカード", "Four of a kind"), 4, 3); - return ODDS_4C; - case 7: - if (!NUM_OF(cards[0]) && !NUM_OF(cards[1])) - { - c_put_str(TERM_YELLOW, _("ファイブエース", "Five ace"), 4, 3); - return ODDS_5A; - } - else - { - c_put_str(TERM_YELLOW, _("ファイブカード", "Five of a kind"), 4, 3); - return ODDS_5C; - } - default: - break; - } - - return 0; -} - - -/*! - * @brief ポーカーの捨てる/残すインターフェイスの表示を更新する。 - * @param hoge カーソルの現在位置 - * @param kaeruka カードの捨てる/残すフラグ配列 - * @return なし - */ -static void display_kaeruka(int hoge, int kaeruka[]) -{ - char col = TERM_WHITE; - for (int i = 0; i < 5; i++) - { - if (i == hoge) col = TERM_YELLOW; - else if (kaeruka[i]) col = TERM_WHITE; - else col = TERM_L_BLUE; - - if (kaeruka[i]) - c_put_str(col, _("かえる", "Change"), 14, 5 + i * 16); - else - c_put_str(col, _("のこす", " Stay "), 14, 5 + i * 16); - } - - if (hoge > 4) col = TERM_YELLOW; - else col = TERM_WHITE; - c_put_str(col, _("決定", "Sure"), 16, 38); - - if (hoge < 5) move_cursor(14, 5 + hoge * 16); - else move_cursor(16, 38); -} - - -/*! - * @brief ポーカーの手札を表示する。 - * @return なし - */ -static void display_cards(void) -{ - char suitcolor[4] = { TERM_YELLOW, TERM_L_RED, TERM_L_BLUE, TERM_L_GREEN }; -#ifdef JP - concptr suit[4] = { "★", "●", "¶", "†" }; - concptr card_grph[13][7] = { {"A %s ", - " 変 ", - " 愚 ", - " 蛮 ", - " 怒 ", - " %s ", - " A"}, - {"2 ", - " %s ", - " ", - " ", - " ", - " %s ", - " 2"}, - {"3 ", - " %s ", - " ", - " %s ", - " ", - " %s ", - " 3"}, - {"4 ", - " %s %s ", - " ", - " ", - " ", - " %s %s ", - " 4"}, - {"5 ", - " %s %s ", - " ", - " %s ", - " ", - " %s %s ", - " 5"}, - {"6 ", - " %s %s ", - " ", - " %s %s ", - " ", - " %s %s ", - " 6"}, - {"7 ", - " %s %s ", - " %s ", - " %s %s ", - " ", - " %s %s ", - " 7"}, - {"8 ", - " %s %s ", - " %s ", - " %s %s ", - " %s ", - " %s %s ", - " 8"}, - {"9 %s %s ", - " ", - " %s %s ", - " %s ", - " %s %s ", - " ", - " %s %s 9"}, - {"10 %s %s ", - " %s ", - " %s %s ", - " ", - " %s %s ", - " %s ", - " %s %s 10"}, - {"J Λ ", - "%s || ", - " || ", - " || ", - " || ", - " |=亜=| %s", - " 目 J"}, - {"Q ###### ", - "%s# # ", - " # ++++ # ", - " # +==+ # ", - " # ++ # ", - " # # %s", - " ## Q"}, - {"K ", - "%s `⌒´ ", - " γγγλ ", - " ο ο ι ", - " υ ∂ ", - " σ ノ %s", - " K"} }; - concptr joker_grph[7] = { " ", - " J ", - " O ", - " K ", - " E ", - " R ", - " " }; - -#else - - concptr suit[4] = { "[]", "qp", "<>", "db" }; - concptr card_grph[13][7] = { {"A %s ", - " He ", - " ng ", - " ba ", - " nd ", - " %s ", - " A"}, - {"2 ", - " %s ", - " ", - " ", - " ", - " %s ", - " 2"}, - {"3 ", - " %s ", - " ", - " %s ", - " ", - " %s ", - " 3"}, - {"4 ", - " %s %s ", - " ", - " ", - " ", - " %s %s ", - " 4"}, - {"5 ", - " %s %s ", - " ", - " %s ", - " ", - " %s %s ", - " 5"}, - {"6 ", - " %s %s ", - " ", - " %s %s ", - " ", - " %s %s ", - " 6"}, - {"7 ", - " %s %s ", - " %s ", - " %s %s ", - " ", - " %s %s ", - " 7"}, - {"8 ", - " %s %s ", - " %s ", - " %s %s ", - " %s ", - " %s %s ", - " 8"}, - {"9 %s %s ", - " ", - " %s %s ", - " %s ", - " %s %s ", - " ", - " %s %s 9"}, - {"10 %s %s ", - " %s ", - " %s %s ", - " ", - " %s %s ", - " %s ", - " %s %s 10"}, - {"J /\\ ", - "%s || ", - " || ", - " || ", - " || ", - " |=HH=| %s", - " ][ J"}, - {"Q ###### ", - "%s# # ", - " # ++++ # ", - " # +==+ # ", - " # ++ # ", - " # # %s", - " ## Q"}, - {"K ", - "%s _'~~`_ ", - " jjjjj$& ", - " q q uu ", - " c & ", - " v__/ %s", - " K"} }; - concptr joker_grph[7] = { " ", - " J ", - " O ", - " K ", - " E ", - " R ", - " " }; -#endif - - for (int i = 0; i < 5; i++) - { - prt(_("┏━━━━━━┓", " +------------+ "), 5, i * 16); - } - - for (int i = 0; i < 5; i++) - { - for (int j = 0; j < 7; j++) - { - prt(_("┃", " |"), j + 6, i * 16); - if (IS_JOKER(cards[i])) - c_put_str(TERM_VIOLET, joker_grph[j], j + 6, 2 + i * 16); - else - c_put_str(suitcolor[SUIT_OF(cards[i])], format(card_grph[NUM_OF(cards[i])][j], suit[SUIT_OF(cards[i])], suit[SUIT_OF(cards[i])]), j + 6, 2 + i * 16); - prt(_("┃", "| "), j + 6, i * 16 + 14); - } - } - - for (int i = 0; i < 5; i++) - { - prt(_("┗━━━━━━┛", " +------------+ "), 13, i * 16); - } -} - - -/*! - * @brief ポーカーの1プレイルーチン。 - * @return 1プレイの役の結果 - */ -static int do_poker(void) -{ - int is_put[5]; - - bool done = FALSE; - bool decision = TRUE; - bool draw = TRUE; - - int deck[53]; - reset_deck(deck); - - int deck_ptr = 0; - for (int i = 0; i < 5; i++) - { - cards[i] = deck[deck_ptr++]; - is_put[i] = 0; - } - - prt(_("残すカードを決めて下さい(方向で移動, スペースで選択)。", "Stay witch? "), 0, 0); - - display_cards(); - poker_hand_check(); - - int k = 2; - char cmd; - while (!done) - { - if (draw) - { - display_kaeruka(k + decision * 5, is_put); - } - - draw = FALSE; - cmd = inkey(); - switch (cmd) - { - case '6': case 'l': case 'L': case KTRL('F'): - if (!decision) - { - k = (k + 1) % 5; - } - else - { - k = 0; - decision = FALSE; - } - - draw = TRUE; - break; - case '4': case 'h': case 'H': case KTRL('B'): - if (!decision) - { - k = (k + 4) % 5; - } - else - { - k = 4; - decision = FALSE; - } - - draw = TRUE; - break; - case '2': case 'j': case 'J': case KTRL('N'): - if (!decision) - { - decision = TRUE; draw = TRUE; - } - - break; - case '8': case 'k': case 'K': case KTRL('P'): - if (decision) - { - decision = FALSE; draw = TRUE; - } - - break; - case ' ': case '\r': - if (decision) - { - done = TRUE; - } - else - { - is_put[k] = !is_put[k]; draw = TRUE; - } - - break; - default: - break; - } - } - - prt("", 0, 0); - - for (int i = 0; i < 5; i++) - { - if (is_put[i] == 1) cards[i] = deck[deck_ptr++]; - } - - display_cards(); - - return poker_hand_check(); -} - -// todo このundefは必要か? -#undef SUIT_OF -#undef NUM_OF -#undef IS_JOKER -/* end of poker codes --Koka */ - - /*! * @brief カジノ1プレイごとのメインルーチン / gamble_comm * @param player_ptr プレーヤーへの参照ポインタ diff --git a/src/market/poker.c b/src/market/poker.c new file mode 100644 index 000000000..5f682a511 --- /dev/null +++ b/src/market/poker.c @@ -0,0 +1,689 @@ +#include "angband.h" +#include "poker.h" +#include "term.h" + +/*! + * ポーカーの現在の手札ID + */ +static int cards[5]; + +#define ODDS_5A 3000 /*!< ファイブエースの役倍率 */ +#define ODDS_5C 400 /*!< ファイブカードの役倍率 */ +#define ODDS_RF 200 /*!< ロイヤルストレートフラッシュの役倍率 */ +#define ODDS_SF 80 /*!< ストレートフラッシュの役倍率 */ +#define ODDS_4C 16 /*!< フォアカードの役倍率 */ +#define ODDS_FH 12 /*!< フルハウスの役倍率 */ +#define ODDS_FL 8 /*!< フラッシュの役倍率 */ +#define ODDS_ST 4 /*!< ストレートの役倍率 */ +#define ODDS_3C 1 /*!< スリーカードの役倍率 */ +#define ODDS_2P 1 /*!< ツーペアの役倍率 */ + +/*! @note + * kpoker no (tyuto-hannpa na)pakuri desu... + * joker ha shineru node haitte masen. + * + * TODO: donataka! tsukutte! + * - agatta yaku no kiroku (like DQ). + * - kakkoii card no e. + * - sousa-sei no koujyo. + * - code wo wakariyasuku. + * - double up. + * - Joker... -- done. + * + * 9/13/2000 --Koka + * 9/15/2000 joker wo jissou. soreto, code wo sukosi kakikae. --Habu + */ + +#define SUIT_OF(card) ((card) / 13) /*!< トランプカードのスートを返す */ +#define NUM_OF(card) ((card) % 13) /*!< トランプカードの番号を返す */ +#define IS_JOKER(card) ((card) == 52) /*!< トランプカードがジョーカーかどうかを返す */ + + /*! + * @brief ポーカーの山札を切る + * @param deck デッキの配列 + * @return なし + */ +static void reset_deck(int deck[]) +{ + for (int i = 0; i < 53; i++) + { + deck[i] = i; + } + + for (int i = 0; i < 53; i++) { + int tmp1 = randint0(53 - i) + i; + int tmp2 = deck[i]; + deck[i] = deck[tmp1]; + deck[tmp1] = tmp2; + } +} + + +/*! + * @brief ポーカープレイ中にジョーカーを持っているかの判定を返す + * @param なし + * @return ジョーカーを持っているか + */ +static bool have_joker(void) +{ + for (int i = 0; i < 5; i++) + { + if (IS_JOKER(cards[i])) return TRUE; + } + + return FALSE; +} + + +/*! + * @brief ポーカーの手札に該当の番号の札があるかを返す + * @param num 探したいカードの番号 + * @return 該当の番号が手札にあるか。 + */ +static bool find_card_num(int num) +{ + for (int i = 0; i < 5; i++) + { + if (NUM_OF(cards[i]) == num && !IS_JOKER(cards[i])) return TRUE; + } + + return FALSE; +} + + +/*! + * @brief ポーカーの手札がフラッシュ役を得ているかを帰す + * @param なし + * @return 役の判定結果 + */ +static bool poker_hand_check_flush(void) +{ + bool joker_is_used = FALSE; + + int suit = IS_JOKER(cards[0]) ? SUIT_OF(cards[1]) : SUIT_OF(cards[0]); + for (int i = 0; i < 5; i++) { + if (SUIT_OF(cards[i]) == suit) continue; + + if (have_joker() && !joker_is_used) + joker_is_used = TRUE; + else + return FALSE; + } + + return TRUE; +} + + +/*! + * @brief ポーカーの手札がストレートを含んだ高位の役を得ているかを帰す + * @param なし + * @return 役の判定結果 0…ストレート、フラッシュいずれもなし/1…ストレートのみ/2…ストレートフラッシュ/3…ロイヤルストレートフラッシュ + */ +static int poker_hand_check_straight(void) +{ + int lowest = 99; + bool joker_is_used = FALSE; + bool straight = FALSE; + + for (int i = 0; i < 5; i++) + { + if (NUM_OF(cards[i]) < lowest && !IS_JOKER(cards[i])) + lowest = NUM_OF(cards[i]); + } + + if (poker_hand_check_flush()) + { + int i; + if (lowest == 0) + { + for (i = 0; i < 4; i++) + { + if (!find_card_num(9 + i)) { + if (have_joker() && !joker_is_used) + joker_is_used = TRUE; + else + break; + } + } + + if (i == 4) return 3; + } + + if (lowest == 9) + { + for (i = 0; i < 3; i++) + { + if (!find_card_num(10 + i)) + break; + } + + if (i == 3 && have_joker()) return 3; + } + } + + joker_is_used = FALSE; + + if (lowest == 0) + { + int i; + for (i = 0; i < 4; i++) + { + if (!find_card_num(9 + i)) { + if (have_joker() && !joker_is_used) + joker_is_used = TRUE; + else + break; + } + } + + if (i == 4) straight = TRUE; + } + + joker_is_used = FALSE; + + int i; + for (i = 0; i < 5; i++) + { + if (!find_card_num(lowest + i)) + { + if (have_joker() && !joker_is_used) + joker_is_used = TRUE; + else + break; /* None */ + } + } + + if (i == 5) straight = TRUE; + + if (straight && poker_hand_check_flush()) return 2; /* Straight Flush */ + else if (straight) return 1; /* Only Straight */ + else return 0; +} + + +/*! + * @brief ポーカーのペア役の状態を返す。 + * @param なし + * @return 0:nopair 1:1 pair 2:2 pair 3:3 cards 4:full house 6:4cards + */ +static int poker_hand_check_pair(void) +{ + int matching = 0; + for (int i = 0; i < 5; i++) + { + for (int j = i + 1; j < 5; j++) + { + if (IS_JOKER(cards[i]) || IS_JOKER(cards[j])) continue; + if (NUM_OF(cards[i]) == NUM_OF(cards[j])) + matching++; + } + } + + if (have_joker()) + { + switch (matching) { + case 0: + matching = 1; + break; + case 1: + matching = 3; + break; + case 2: + matching = 4; + break; + case 3: + matching = 6; + break; + case 6: + matching = 7; + break; + default: + /* don't reach */ + break; + } + } + + return matching; +} + + +/*! + * @brief ポーカーの役をチェックし、その結果を画面に表示しつつ結果を返す。 + * @return 役のID + */ +static int poker_hand_check(void) +{ + prt(" ", 4, 3); + + switch (poker_hand_check_straight()) + { + case 3: /* RF! */ + c_put_str(TERM_YELLOW, _("ロイヤルストレートフラッシュ", "Royal Flush"), 4, 3); + return ODDS_RF; + case 2: /* SF! */ + c_put_str(TERM_YELLOW, _("ストレートフラッシュ", "Straight Flush"), 4, 3); + return ODDS_SF; + case 1: + c_put_str(TERM_YELLOW, _("ストレート", "Straight"), 4, 3); + return ODDS_ST; + default: + /* Not straight -- fall through */ + break; + } + + if (poker_hand_check_flush()) + { + c_put_str(TERM_YELLOW, _("フラッシュ", "Flush"), 4, 3); + return ODDS_FL; + } + + switch (poker_hand_check_pair()) + { + case 1: + c_put_str(TERM_YELLOW, _("ワンペア", "One pair"), 4, 3); + return 0; + case 2: + c_put_str(TERM_YELLOW, _("ツーペア", "Two pair"), 4, 3); + return ODDS_2P; + case 3: + c_put_str(TERM_YELLOW, _("スリーカード", "Three of a kind"), 4, 3); + return ODDS_3C; + case 4: + c_put_str(TERM_YELLOW, _("フルハウス", "Full house"), 4, 3); + return ODDS_FH; + case 6: + c_put_str(TERM_YELLOW, _("フォーカード", "Four of a kind"), 4, 3); + return ODDS_4C; + case 7: + if (!NUM_OF(cards[0]) && !NUM_OF(cards[1])) + { + c_put_str(TERM_YELLOW, _("ファイブエース", "Five ace"), 4, 3); + return ODDS_5A; + } + else + { + c_put_str(TERM_YELLOW, _("ファイブカード", "Five of a kind"), 4, 3); + return ODDS_5C; + } + default: + break; + } + + return 0; +} + + +/*! + * @brief ポーカーの捨てる/残すインターフェイスの表示を更新する。 + * @param hoge カーソルの現在位置 + * @param kaeruka カードの捨てる/残すフラグ配列 + * @return なし + */ +static void display_kaeruka(int hoge, int kaeruka[]) +{ + char col = TERM_WHITE; + for (int i = 0; i < 5; i++) + { + if (i == hoge) col = TERM_YELLOW; + else if (kaeruka[i]) col = TERM_WHITE; + else col = TERM_L_BLUE; + + if (kaeruka[i]) + c_put_str(col, _("かえる", "Change"), 14, 5 + i * 16); + else + c_put_str(col, _("のこす", " Stay "), 14, 5 + i * 16); + } + + if (hoge > 4) col = TERM_YELLOW; + else col = TERM_WHITE; + c_put_str(col, _("決定", "Sure"), 16, 38); + + if (hoge < 5) move_cursor(14, 5 + hoge * 16); + else move_cursor(16, 38); +} + + +/*! + * @brief ポーカーの手札を表示する + * @param なし + * @return なし + */ +static void display_cards(void) +{ + char suitcolor[4] = { TERM_YELLOW, TERM_L_RED, TERM_L_BLUE, TERM_L_GREEN }; +#ifdef JP + concptr suit[4] = { "★", "●", "¶", "†" }; + concptr card_grph[13][7] = { {"A %s ", + " 変 ", + " 愚 ", + " 蛮 ", + " 怒 ", + " %s ", + " A"}, + {"2 ", + " %s ", + " ", + " ", + " ", + " %s ", + " 2"}, + {"3 ", + " %s ", + " ", + " %s ", + " ", + " %s ", + " 3"}, + {"4 ", + " %s %s ", + " ", + " ", + " ", + " %s %s ", + " 4"}, + {"5 ", + " %s %s ", + " ", + " %s ", + " ", + " %s %s ", + " 5"}, + {"6 ", + " %s %s ", + " ", + " %s %s ", + " ", + " %s %s ", + " 6"}, + {"7 ", + " %s %s ", + " %s ", + " %s %s ", + " ", + " %s %s ", + " 7"}, + {"8 ", + " %s %s ", + " %s ", + " %s %s ", + " %s ", + " %s %s ", + " 8"}, + {"9 %s %s ", + " ", + " %s %s ", + " %s ", + " %s %s ", + " ", + " %s %s 9"}, + {"10 %s %s ", + " %s ", + " %s %s ", + " ", + " %s %s ", + " %s ", + " %s %s 10"}, + {"J Λ ", + "%s || ", + " || ", + " || ", + " || ", + " |=亜=| %s", + " 目 J"}, + {"Q ###### ", + "%s# # ", + " # ++++ # ", + " # +==+ # ", + " # ++ # ", + " # # %s", + " ## Q"}, + {"K ", + "%s `⌒´ ", + " γγγλ ", + " ο ο ι ", + " υ ∂ ", + " σ ノ %s", + " K"} }; + concptr joker_grph[7] = { " ", + " J ", + " O ", + " K ", + " E ", + " R ", + " " }; + +#else + + concptr suit[4] = { "[]", "qp", "<>", "db" }; + concptr card_grph[13][7] = { {"A %s ", + " He ", + " ng ", + " ba ", + " nd ", + " %s ", + " A"}, + {"2 ", + " %s ", + " ", + " ", + " ", + " %s ", + " 2"}, + {"3 ", + " %s ", + " ", + " %s ", + " ", + " %s ", + " 3"}, + {"4 ", + " %s %s ", + " ", + " ", + " ", + " %s %s ", + " 4"}, + {"5 ", + " %s %s ", + " ", + " %s ", + " ", + " %s %s ", + " 5"}, + {"6 ", + " %s %s ", + " ", + " %s %s ", + " ", + " %s %s ", + " 6"}, + {"7 ", + " %s %s ", + " %s ", + " %s %s ", + " ", + " %s %s ", + " 7"}, + {"8 ", + " %s %s ", + " %s ", + " %s %s ", + " %s ", + " %s %s ", + " 8"}, + {"9 %s %s ", + " ", + " %s %s ", + " %s ", + " %s %s ", + " ", + " %s %s 9"}, + {"10 %s %s ", + " %s ", + " %s %s ", + " ", + " %s %s ", + " %s ", + " %s %s 10"}, + {"J /\\ ", + "%s || ", + " || ", + " || ", + " || ", + " |=HH=| %s", + " ][ J"}, + {"Q ###### ", + "%s# # ", + " # ++++ # ", + " # +==+ # ", + " # ++ # ", + " # # %s", + " ## Q"}, + {"K ", + "%s _'~~`_ ", + " jjjjj$& ", + " q q uu ", + " c & ", + " v__/ %s", + " K"} }; + concptr joker_grph[7] = { " ", + " J ", + " O ", + " K ", + " E ", + " R ", + " " }; +#endif + + for (int i = 0; i < 5; i++) + { + prt(_("┏━━━━━━┓", " +------------+ "), 5, i * 16); + } + + for (int i = 0; i < 5; i++) + { + for (int j = 0; j < 7; j++) + { + prt(_("┃", " |"), j + 6, i * 16); + if (IS_JOKER(cards[i])) + c_put_str(TERM_VIOLET, joker_grph[j], j + 6, 2 + i * 16); + else + c_put_str(suitcolor[SUIT_OF(cards[i])], format(card_grph[NUM_OF(cards[i])][j], suit[SUIT_OF(cards[i])], suit[SUIT_OF(cards[i])]), j + 6, 2 + i * 16); + prt(_("┃", "| "), j + 6, i * 16 + 14); + } + } + + for (int i = 0; i < 5; i++) + { + prt(_("┗━━━━━━┛", " +------------+ "), 13, i * 16); + } +} + + +/*! + * @brief ポーカーの1プレイルーチン。 + * @return 1プレイの役の結果 + */ +int do_poker(void) +{ + int is_put[5]; + + bool done = FALSE; + bool decision = TRUE; + bool draw = TRUE; + + int deck[53]; + reset_deck(deck); + + int deck_ptr = 0; + for (int i = 0; i < 5; i++) + { + cards[i] = deck[deck_ptr++]; + is_put[i] = 0; + } + + prt(_("残すカードを決めて下さい(方向で移動, スペースで選択)。", "Stay witch? "), 0, 0); + + display_cards(); + poker_hand_check(); + + int k = 2; + char cmd; + while (!done) + { + if (draw) + { + display_kaeruka(k + decision * 5, is_put); + } + + draw = FALSE; + cmd = inkey(); + switch (cmd) + { + case '6': case 'l': case 'L': case KTRL('F'): + if (!decision) + { + k = (k + 1) % 5; + } + else + { + k = 0; + decision = FALSE; + } + + draw = TRUE; + break; + case '4': case 'h': case 'H': case KTRL('B'): + if (!decision) + { + k = (k + 4) % 5; + } + else + { + k = 4; + decision = FALSE; + } + + draw = TRUE; + break; + case '2': case 'j': case 'J': case KTRL('N'): + if (!decision) + { + decision = TRUE; draw = TRUE; + } + + break; + case '8': case 'k': case 'K': case KTRL('P'): + if (decision) + { + decision = FALSE; draw = TRUE; + } + + break; + case ' ': case '\r': + if (decision) + { + done = TRUE; + } + else + { + is_put[k] = !is_put[k]; draw = TRUE; + } + + break; + default: + break; + } + } + + prt("", 0, 0); + + for (int i = 0; i < 5; i++) + { + if (is_put[i] == 1) cards[i] = deck[deck_ptr++]; + } + + display_cards(); + + return poker_hand_check(); +} diff --git a/src/market/poker.h b/src/market/poker.h new file mode 100644 index 000000000..1c6eb46b3 --- /dev/null +++ b/src/market/poker.h @@ -0,0 +1,3 @@ +#pragma once + +int do_poker(void); -- 2.11.0