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) /*!< トランプカードがジョーカーかどうかを返す */
48 static void reset_deck(int deck[])
50 for (int i = 0; i < 53; i++) {
54 for (int i = 0; i < 53; i++) {
55 int tmp1 = randint0(53 - i) + i;
63 * @brief ポーカープレイ中にジョーカーを持っているかの判定を返す
65 * @return ジョーカーを持っているか
67 static bool has_joker(void)
69 for (int i = 0; i < 5; i++) {
70 if (IS_JOKER(cards[i])) {
78 * @brief ポーカーの手札に該当の番号の札があるかを返す
79 * @param num 探したいカードの番号
80 * @return 該当の番号が手札にあるか。
82 static bool find_card_num(int num)
84 for (int i = 0; i < 5; i++) {
85 if (NUM_OF(cards[i]) == num && !IS_JOKER(cards[i])) {
94 * @brief ポーカーの手札がフラッシュ役を得ているかを帰す
98 static bool poker_hand_check_flush(void)
100 bool joker_is_used = false;
102 int suit = IS_JOKER(cards[0]) ? SUIT_OF(cards[1]) : SUIT_OF(cards[0]);
103 for (int i = 0; i < 5; i++) {
104 if (SUIT_OF(cards[i]) == suit) {
108 if (has_joker() && !joker_is_used) {
109 joker_is_used = true;
119 * @brief ポーカーの手札がストレートを含んだ高位の役を得ているかを帰す
121 * @return 役の判定結果 0…ストレート、フラッシュいずれもなし/1…ストレートのみ/2…ストレートフラッシュ/3…ロイヤルストレートフラッシュ
123 static int poker_hand_check_straight(void)
126 bool joker_is_used = false;
127 bool straight = false;
129 for (int i = 0; i < 5; i++) {
130 if (NUM_OF(cards[i]) < lowest && !IS_JOKER(cards[i])) {
131 lowest = NUM_OF(cards[i]);
135 if (poker_hand_check_flush()) {
138 for (i = 0; i < 4; i++) {
139 if (!find_card_num(9 + i)) {
140 if (has_joker() && !joker_is_used) {
141 joker_is_used = true;
154 for (i = 0; i < 3; i++) {
155 if (!find_card_num(10 + i)) {
160 if (i == 3 && has_joker()) {
166 joker_is_used = false;
170 for (i = 0; i < 4; i++) {
171 if (!find_card_num(9 + i)) {
172 if (has_joker() && !joker_is_used) {
173 joker_is_used = true;
185 joker_is_used = false;
188 for (i = 0; i < 5; i++) {
189 if (!find_card_num(lowest + i)) {
190 if (has_joker() && !joker_is_used) {
191 joker_is_used = true;
202 if (straight && poker_hand_check_flush()) {
204 } /* Straight Flush */
207 } /* Only Straight */
214 * @brief ポーカーのペア役の状態を返す。
216 * @return 0:nopair 1:1 pair 2:2 pair 3:3 cards 4:full house 6:4cards
218 static int poker_hand_check_pair(void)
221 for (int i = 0; i < 5; i++) {
222 for (int j = i + 1; j < 5; j++) {
223 if (IS_JOKER(cards[i]) || IS_JOKER(cards[j])) {
226 if (NUM_OF(cards[i]) == NUM_OF(cards[j])) {
259 * @brief ポーカーの役をチェックし、その結果を画面に表示しつつ結果を返す。
262 static int poker_hand_check(void)
266 switch (poker_hand_check_straight()) {
268 c_put_str(TERM_YELLOW, _("ロイヤルストレートフラッシュ", "Royal Flush"), 4, 3);
271 c_put_str(TERM_YELLOW, _("ストレートフラッシュ", "Straight Flush"), 4, 3);
274 c_put_str(TERM_YELLOW, _("ストレート", "Straight"), 4, 3);
277 /* Not straight -- fall through */
281 if (poker_hand_check_flush()) {
282 c_put_str(TERM_YELLOW, _("フラッシュ", "Flush"), 4, 3);
286 switch (poker_hand_check_pair()) {
288 c_put_str(TERM_YELLOW, _("ワンペア", "One pair"), 4, 3);
291 c_put_str(TERM_YELLOW, _("ツーペア", "Two pair"), 4, 3);
294 c_put_str(TERM_YELLOW, _("スリーカード", "Three of a kind"), 4, 3);
297 c_put_str(TERM_YELLOW, _("フルハウス", "Full house"), 4, 3);
300 c_put_str(TERM_YELLOW, _("フォーカード", "Four of a kind"), 4, 3);
303 if (!NUM_OF(cards[0]) && !NUM_OF(cards[1])) {
304 c_put_str(TERM_YELLOW, _("ファイブエース", "Five ace"), 4, 3);
307 c_put_str(TERM_YELLOW, _("ファイブカード", "Five of a kind"), 4, 3);
318 * @brief ポーカーの捨てる/残すインターフェイスの表示を更新する。
319 * @param hoge カーソルの現在位置
320 * @param kaeruka カードの捨てる/残すフラグ配列
322 static void display_kaeruka(int hoge, int kaeruka[])
324 char col = TERM_WHITE;
325 for (int i = 0; i < 5; i++) {
328 } else if (kaeruka[i]) {
335 c_put_str(col, _("かえる", "Change"), 14, 5 + i * 16);
337 c_put_str(col, _("のこす", " Stay "), 14, 5 + i * 16);
346 c_put_str(col, _("決定", "Sure"), 16, 38);
349 move_cursor(14, 5 + hoge * 16);
356 * @brief ポーカーの手札を表示する
360 static void display_cards(void)
362 char suitcolor[4] = { TERM_YELLOW, TERM_L_RED, TERM_L_BLUE, TERM_L_GREEN };
364 concptr suit[4] = { "★", "●", "¶", "†" };
365 concptr card_grph[13][7] = { { "A %s ",
456 concptr joker_grph[7] = { " ",
466 concptr suit[4] = { "[]", "qp", "<>", "db" };
467 concptr card_grph[13][7] = { { "A %s ",
558 concptr joker_grph[7] = { " ",
567 for (int i = 0; i < 5; i++) {
568 prt(_("┏━━━━━━┓", " +------------+ "), 5, i * 16);
571 for (int i = 0; i < 5; i++) {
572 for (int j = 0; j < 7; j++) {
573 prt(_("┃", " |"), j + 6, i * 16);
574 if (IS_JOKER(cards[i])) {
575 c_put_str(TERM_VIOLET, joker_grph[j], j + 6, 2 + i * 16);
577 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);
579 prt(_("┃", "| "), j + 6, i * 16 + 14);
583 for (int i = 0; i < 5; i++) {
584 prt(_("┗━━━━━━┛", " +------------+ "), 13, i * 16);
589 * @brief ポーカーの1プレイルーチン。
597 bool decision = true;
604 for (int i = 0; i < 5; i++) {
605 cards[i] = deck[deck_ptr++];
609 prt(_("残すカードを決めて下さい(方向で移動, スペースで選択)。", "Keep which cards (direction keys move; space selects)? "), 0, 0);
618 display_kaeruka(k + decision * 5, is_put);
675 is_put[k] = !is_put[k];
687 for (int i = 0; i < 5; i++) {
688 if (is_put[i] == 1) {
689 cards[i] = deck[deck_ptr++];
695 return poker_hand_check();