1 #include "market/poker.h"
2 #include "io/input-key-acceptor.h"
3 #include "system/angband.h"
4 #include "term/screen-processor.h"
5 #include "term/term-color-types.h"
6 #include "util/int-char-converter.h"
13 #define ODDS_5A 3000 /*!< ファイブエースの役倍率 */
14 #define ODDS_5C 400 /*!< ファイブカードの役倍率 */
15 #define ODDS_RF 200 /*!< ロイヤルストレートフラッシュの役倍率 */
16 #define ODDS_SF 80 /*!< ストレートフラッシュの役倍率 */
17 #define ODDS_4C 16 /*!< フォアカードの役倍率 */
18 #define ODDS_FH 12 /*!< フルハウスの役倍率 */
19 #define ODDS_FL 8 /*!< フラッシュの役倍率 */
20 #define ODDS_ST 4 /*!< ストレートの役倍率 */
21 #define ODDS_3C 1 /*!< スリーカードの役倍率 */
22 #define ODDS_2P 1 /*!< ツーペアの役倍率 */
25 * kpoker no (tyuto-hannpa na)pakuri desu...
26 * joker ha shineru node haitte masen.
28 * TODO: donataka! tsukutte!
29 * - agatta yaku no kiroku (like DQ).
30 * - kakkoii card no e.
31 * - sousa-sei no koujyo.
32 * - code wo wakariyasuku.
37 * 9/15/2000 joker wo jissou. soreto, code wo sukosi kakikae. --Habu
40 #define SUIT_OF(card) ((card) / 13) /*!< トランプカードのスートを返す */
41 #define NUM_OF(card) ((card) % 13) /*!< トランプカードの番号を返す */
42 #define IS_JOKER(card) ((card) == 52) /*!< トランプカードがジョーカーかどうかを返す */
49 static void reset_deck(int deck[])
51 for (int i = 0; i < 53; i++)
56 for (int i = 0; i < 53; i++) {
57 int tmp1 = randint0(53 - i) + i;
66 * @brief ポーカープレイ中にジョーカーを持っているかの判定を返す
68 * @return ジョーカーを持っているか
70 static bool have_joker(void)
72 for (int i = 0; i < 5; i++)
74 if (IS_JOKER(cards[i])) return TRUE;
82 * @brief ポーカーの手札に該当の番号の札があるかを返す
83 * @param num 探したいカードの番号
84 * @return 該当の番号が手札にあるか。
86 static bool find_card_num(int num)
88 for (int i = 0; i < 5; i++)
90 if (NUM_OF(cards[i]) == num && !IS_JOKER(cards[i])) return TRUE;
98 * @brief ポーカーの手札がフラッシュ役を得ているかを帰す
102 static bool poker_hand_check_flush(void)
104 bool joker_is_used = FALSE;
106 int suit = IS_JOKER(cards[0]) ? SUIT_OF(cards[1]) : SUIT_OF(cards[0]);
107 for (int i = 0; i < 5; i++) {
108 if (SUIT_OF(cards[i]) == suit) continue;
110 if (have_joker() && !joker_is_used)
111 joker_is_used = TRUE;
121 * @brief ポーカーの手札がストレートを含んだ高位の役を得ているかを帰す
123 * @return 役の判定結果 0…ストレート、フラッシュいずれもなし/1…ストレートのみ/2…ストレートフラッシュ/3…ロイヤルストレートフラッシュ
125 static int poker_hand_check_straight(void)
128 bool joker_is_used = FALSE;
129 bool straight = FALSE;
131 for (int i = 0; i < 5; i++)
133 if (NUM_OF(cards[i]) < lowest && !IS_JOKER(cards[i]))
134 lowest = NUM_OF(cards[i]);
137 if (poker_hand_check_flush())
142 for (i = 0; i < 4; i++)
144 if (!find_card_num(9 + i)) {
145 if (have_joker() && !joker_is_used)
146 joker_is_used = TRUE;
152 if (i == 4) return 3;
157 for (i = 0; i < 3; i++)
159 if (!find_card_num(10 + i))
163 if (i == 3 && have_joker()) return 3;
167 joker_is_used = FALSE;
172 for (i = 0; i < 4; i++)
174 if (!find_card_num(9 + i)) {
175 if (have_joker() && !joker_is_used)
176 joker_is_used = TRUE;
182 if (i == 4) straight = TRUE;
185 joker_is_used = FALSE;
188 for (i = 0; i < 5; i++)
190 if (!find_card_num(lowest + i))
192 if (have_joker() && !joker_is_used)
193 joker_is_used = TRUE;
199 if (i == 5) straight = TRUE;
201 if (straight && poker_hand_check_flush()) return 2; /* Straight Flush */
202 else if (straight) return 1; /* Only Straight */
208 * @brief ポーカーのペア役の状態を返す。
210 * @return 0:nopair 1:1 pair 2:2 pair 3:3 cards 4:full house 6:4cards
212 static int poker_hand_check_pair(void)
215 for (int i = 0; i < 5; i++)
217 for (int j = i + 1; j < 5; j++)
219 if (IS_JOKER(cards[i]) || IS_JOKER(cards[j])) continue;
220 if (NUM_OF(cards[i]) == NUM_OF(cards[j]))
254 * @brief ポーカーの役をチェックし、その結果を画面に表示しつつ結果を返す。
257 static int poker_hand_check(void)
261 switch (poker_hand_check_straight())
264 c_put_str(TERM_YELLOW, _("ロイヤルストレートフラッシュ", "Royal Flush"), 4, 3);
267 c_put_str(TERM_YELLOW, _("ストレートフラッシュ", "Straight Flush"), 4, 3);
270 c_put_str(TERM_YELLOW, _("ストレート", "Straight"), 4, 3);
273 /* Not straight -- fall through */
277 if (poker_hand_check_flush())
279 c_put_str(TERM_YELLOW, _("フラッシュ", "Flush"), 4, 3);
283 switch (poker_hand_check_pair())
286 c_put_str(TERM_YELLOW, _("ワンペア", "One pair"), 4, 3);
289 c_put_str(TERM_YELLOW, _("ツーペア", "Two pair"), 4, 3);
292 c_put_str(TERM_YELLOW, _("スリーカード", "Three of a kind"), 4, 3);
295 c_put_str(TERM_YELLOW, _("フルハウス", "Full house"), 4, 3);
298 c_put_str(TERM_YELLOW, _("フォーカード", "Four of a kind"), 4, 3);
301 if (!NUM_OF(cards[0]) && !NUM_OF(cards[1]))
303 c_put_str(TERM_YELLOW, _("ファイブエース", "Five ace"), 4, 3);
308 c_put_str(TERM_YELLOW, _("ファイブカード", "Five of a kind"), 4, 3);
320 * @brief ポーカーの捨てる/残すインターフェイスの表示を更新する。
321 * @param hoge カーソルの現在位置
322 * @param kaeruka カードの捨てる/残すフラグ配列
325 static void display_kaeruka(int hoge, int kaeruka[])
327 char col = TERM_WHITE;
328 for (int i = 0; i < 5; i++)
330 if (i == hoge) col = TERM_YELLOW;
331 else if (kaeruka[i]) col = TERM_WHITE;
332 else col = TERM_L_BLUE;
335 c_put_str(col, _("かえる", "Change"), 14, 5 + i * 16);
337 c_put_str(col, _("のこす", " Stay "), 14, 5 + i * 16);
340 if (hoge > 4) col = TERM_YELLOW;
341 else col = TERM_WHITE;
342 c_put_str(col, _("決定", "Sure"), 16, 38);
344 if (hoge < 5) move_cursor(14, 5 + hoge * 16);
345 else move_cursor(16, 38);
351 * @brief ポーカーの手札を表示する
355 static void display_cards(void)
357 char suitcolor[4] = { TERM_YELLOW, TERM_L_RED, TERM_L_BLUE, TERM_L_GREEN };
359 concptr suit[4] = { "★", "●", "¶", "†" };
360 concptr card_grph[13][7] = { {"A %s ",
451 concptr joker_grph[7] = { " ",
461 concptr suit[4] = { "[]", "qp", "<>", "db" };
462 concptr card_grph[13][7] = { {"A %s ",
553 concptr joker_grph[7] = { " ",
562 for (int i = 0; i < 5; i++)
564 prt(_("┏━━━━━━┓", " +------------+ "), 5, i * 16);
567 for (int i = 0; i < 5; i++)
569 for (int j = 0; j < 7; j++)
571 prt(_("┃", " |"), j + 6, i * 16);
572 if (IS_JOKER(cards[i]))
573 c_put_str(TERM_VIOLET, joker_grph[j], j + 6, 2 + i * 16);
575 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);
576 prt(_("┃", "| "), j + 6, i * 16 + 14);
580 for (int i = 0; i < 5; i++)
582 prt(_("┗━━━━━━┛", " +------------+ "), 13, i * 16);
588 * @brief ポーカーの1プレイルーチン。
596 bool decision = TRUE;
603 for (int i = 0; i < 5; i++)
605 cards[i] = deck[deck_ptr++];
609 prt(_("残すカードを決めて下さい(方向で移動, スペースで選択)。", "Stay witch? "), 0, 0);
620 display_kaeruka(k + decision * 5, is_put);
627 case '6': case 'l': case 'L': case KTRL('F'):
640 case '4': case 'h': case 'H': case KTRL('B'):
653 case '2': case 'j': case 'J': case KTRL('N'):
656 decision = TRUE; draw = TRUE;
660 case '8': case 'k': case 'K': case KTRL('P'):
663 decision = FALSE; draw = TRUE;
674 is_put[k] = !is_put[k]; draw = TRUE;
685 for (int i = 0; i < 5; i++)
687 if (is_put[i] == 1) cards[i] = deck[deck_ptr++];
692 return poker_hand_check();