OSDN Git Service

[Refactor] have_flag() を has_flag() に改名. / Rename have_flag() to has_flag().
[hengband/hengband.git] / src / market / poker.c
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"
7
8 /*!
9  * ポーカーの現在の手札ID
10  */
11 static int cards[5];
12
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 /*!< ツーペアの役倍率 */
23
24 /*! @note
25  * kpoker no (tyuto-hannpa na)pakuri desu...
26  * joker ha shineru node haitte masen.
27  *
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.
33  *  - double up.
34  *  - Joker... -- done.
35  *
36  * 9/13/2000 --Koka
37  * 9/15/2000 joker wo jissou. soreto, code wo sukosi kakikae. --Habu
38  */
39
40 #define SUIT_OF(card)  ((card) / 13) /*!< トランプカードのスートを返す */
41 #define NUM_OF(card)   ((card) % 13) /*!< トランプカードの番号を返す */
42 #define IS_JOKER(card) ((card) == 52) /*!< トランプカードがジョーカーかどうかを返す */
43
44  /*!
45  * @brief ポーカーの山札を切る
46  * @param deck デッキの配列
47  * @return なし
48  */
49 static void reset_deck(int deck[])
50 {
51         for (int i = 0; i < 53; i++)
52         {
53                 deck[i] = i;
54         }
55
56         for (int i = 0; i < 53; i++) {
57                 int tmp1 = randint0(53 - i) + i;
58                 int tmp2 = deck[i];
59                 deck[i] = deck[tmp1];
60                 deck[tmp1] = tmp2;
61         }
62 }
63
64
65 /*!
66  * @brief ポーカープレイ中にジョーカーを持っているかの判定を返す
67  * @param なし
68  * @return ジョーカーを持っているか
69  */
70 static bool have_joker(void)
71 {
72         for (int i = 0; i < 5; i++)
73         {
74                 if (IS_JOKER(cards[i])) return TRUE;
75         }
76
77         return FALSE;
78 }
79
80
81 /*!
82  * @brief ポーカーの手札に該当の番号の札があるかを返す
83  * @param num 探したいカードの番号
84  * @return 該当の番号が手札にあるか。
85  */
86 static bool find_card_num(int num)
87 {
88         for (int i = 0; i < 5; i++)
89         {
90                 if (NUM_OF(cards[i]) == num && !IS_JOKER(cards[i])) return TRUE;
91         }
92
93         return FALSE;
94 }
95
96
97 /*!
98  * @brief ポーカーの手札がフラッシュ役を得ているかを帰す
99  * @param なし
100  * @return 役の判定結果
101  */
102 static bool poker_hand_check_flush(void)
103 {
104         bool joker_is_used = FALSE;
105
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;
109
110                 if (have_joker() && !joker_is_used)
111                         joker_is_used = TRUE;
112                 else
113                         return FALSE;
114         }
115
116         return TRUE;
117 }
118
119
120 /*!
121  * @brief ポーカーの手札がストレートを含んだ高位の役を得ているかを帰す
122  * @param なし
123  * @return 役の判定結果 0…ストレート、フラッシュいずれもなし/1…ストレートのみ/2…ストレートフラッシュ/3…ロイヤルストレートフラッシュ
124  */
125 static int poker_hand_check_straight(void)
126 {
127         int lowest = 99;
128         bool joker_is_used = FALSE;
129         bool straight = FALSE;
130
131         for (int i = 0; i < 5; i++)
132         {
133                 if (NUM_OF(cards[i]) < lowest && !IS_JOKER(cards[i]))
134                         lowest = NUM_OF(cards[i]);
135         }
136
137         if (poker_hand_check_flush())
138         {
139                 int i;
140                 if (lowest == 0)
141                 {
142                         for (i = 0; i < 4; i++)
143                         {
144                                 if (!find_card_num(9 + i)) {
145                                         if (have_joker() && !joker_is_used)
146                                                 joker_is_used = TRUE;
147                                         else
148                                                 break;
149                                 }
150                         }
151
152                         if (i == 4) return 3;
153                 }
154
155                 if (lowest == 9)
156                 {
157                         for (i = 0; i < 3; i++)
158                         {
159                                 if (!find_card_num(10 + i))
160                                         break;
161                         }
162
163                         if (i == 3 && have_joker()) return 3;
164                 }
165         }
166
167         joker_is_used = FALSE;
168
169         if (lowest == 0)
170         {
171                 int i;
172                 for (i = 0; i < 4; i++)
173                 {
174                         if (!find_card_num(9 + i)) {
175                                 if (have_joker() && !joker_is_used)
176                                         joker_is_used = TRUE;
177                                 else
178                                         break;
179                         }
180                 }
181
182                 if (i == 4) straight = TRUE;
183         }
184
185         joker_is_used = FALSE;
186
187         int i;
188         for (i = 0; i < 5; i++)
189         {
190                 if (!find_card_num(lowest + i))
191                 {
192                         if (have_joker() && !joker_is_used)
193                                 joker_is_used = TRUE;
194                         else
195                                 break; /* None */
196                 }
197         }
198
199         if (i == 5) straight = TRUE;
200
201         if (straight && poker_hand_check_flush()) return 2; /* Straight Flush */
202         else if (straight) return 1; /* Only Straight */
203         else return 0;
204 }
205
206
207 /*!
208  * @brief ポーカーのペア役の状態を返す。
209  * @param なし
210  * @return 0:nopair 1:1 pair 2:2 pair 3:3 cards 4:full house 6:4cards
211  */
212 static int poker_hand_check_pair(void)
213 {
214         int matching = 0;
215         for (int i = 0; i < 5; i++)
216         {
217                 for (int j = i + 1; j < 5; j++)
218                 {
219                         if (IS_JOKER(cards[i]) || IS_JOKER(cards[j])) continue;
220                         if (NUM_OF(cards[i]) == NUM_OF(cards[j]))
221                                 matching++;
222                 }
223         }
224
225         if (have_joker())
226         {
227                 switch (matching) {
228                 case 0:
229                         matching = 1;
230                         break;
231                 case 1:
232                         matching = 3;
233                         break;
234                 case 2:
235                         matching = 4;
236                         break;
237                 case 3:
238                         matching = 6;
239                         break;
240                 case 6:
241                         matching = 7;
242                         break;
243                 default:
244                         /* don't reach */
245                         break;
246                 }
247         }
248
249         return matching;
250 }
251
252
253 /*!
254  * @brief ポーカーの役をチェックし、その結果を画面に表示しつつ結果を返す。
255  * @return 役のID
256  */
257 static int poker_hand_check(void)
258 {
259         prt("                            ", 4, 3);
260
261         switch (poker_hand_check_straight())
262         {
263         case 3: /* RF! */
264                 c_put_str(TERM_YELLOW, _("ロイヤルストレートフラッシュ", "Royal Flush"), 4, 3);
265                 return ODDS_RF;
266         case 2: /* SF! */
267                 c_put_str(TERM_YELLOW, _("ストレートフラッシュ", "Straight Flush"), 4, 3);
268                 return ODDS_SF;
269         case 1:
270                 c_put_str(TERM_YELLOW, _("ストレート", "Straight"), 4, 3);
271                 return ODDS_ST;
272         default:
273                 /* Not straight -- fall through */
274                 break;
275         }
276
277         if (poker_hand_check_flush())
278         {
279                 c_put_str(TERM_YELLOW, _("フラッシュ", "Flush"), 4, 3);
280                 return ODDS_FL;
281         }
282
283         switch (poker_hand_check_pair())
284         {
285         case 1:
286                 c_put_str(TERM_YELLOW, _("ワンペア", "One pair"), 4, 3);
287                 return 0;
288         case 2:
289                 c_put_str(TERM_YELLOW, _("ツーペア", "Two pair"), 4, 3);
290                 return ODDS_2P;
291         case 3:
292                 c_put_str(TERM_YELLOW, _("スリーカード", "Three of a kind"), 4, 3);
293                 return ODDS_3C;
294         case 4:
295                 c_put_str(TERM_YELLOW, _("フルハウス", "Full house"), 4, 3);
296                 return ODDS_FH;
297         case 6:
298                 c_put_str(TERM_YELLOW, _("フォーカード", "Four of a kind"), 4, 3);
299                 return ODDS_4C;
300         case 7:
301                 if (!NUM_OF(cards[0]) && !NUM_OF(cards[1]))
302                 {
303                         c_put_str(TERM_YELLOW, _("ファイブエース", "Five ace"), 4, 3);
304                         return ODDS_5A;
305                 }
306                 else
307                 {
308                         c_put_str(TERM_YELLOW, _("ファイブカード", "Five of a kind"), 4, 3);
309                         return ODDS_5C;
310                 }
311         default:
312                 break;
313         }
314
315         return 0;
316 }
317
318
319 /*!
320  * @brief ポーカーの捨てる/残すインターフェイスの表示を更新する。
321  * @param hoge カーソルの現在位置
322  * @param kaeruka カードの捨てる/残すフラグ配列
323  * @return なし
324  */
325 static void display_kaeruka(int hoge, int kaeruka[])
326 {
327         char col = TERM_WHITE;
328         for (int i = 0; i < 5; i++)
329         {
330                 if (i == hoge) col = TERM_YELLOW;
331                 else if (kaeruka[i]) col = TERM_WHITE;
332                 else col = TERM_L_BLUE;
333
334                 if (kaeruka[i])
335                         c_put_str(col, _("かえる", "Change"), 14, 5 + i * 16);
336                 else
337                         c_put_str(col, _("のこす", " Stay "), 14, 5 + i * 16);
338         }
339
340         if (hoge > 4) col = TERM_YELLOW;
341         else col = TERM_WHITE;
342         c_put_str(col, _("決定", "Sure"), 16, 38);
343
344         if (hoge < 5) move_cursor(14, 5 + hoge * 16);
345         else move_cursor(16, 38);
346 }
347
348
349 /*!
350  * todo _() でまとめる
351  * @brief ポーカーの手札を表示する
352  * @param なし
353  * @return なし
354  */
355 static void display_cards(void)
356 {
357         char suitcolor[4] = { TERM_YELLOW, TERM_L_RED, TERM_L_BLUE, TERM_L_GREEN };
358 #ifdef JP
359         concptr suit[4] = { "★", "●", "¶", "†" };
360         concptr card_grph[13][7] = { {"A   %s     ",
361                                   "     変     ",
362                                   "     愚     ",
363                                   "     蛮     ",
364                                   "     怒     ",
365                                   "     %s     ",
366                                   "          A"},
367                                  {"2          ",
368                                   "     %s     ",
369                                   "            ",
370                                   "            ",
371                                   "            ",
372                                   "     %s     ",
373                                   "          2"},
374                                  {"3          ",
375                                   "     %s     ",
376                                   "            ",
377                                   "     %s     ",
378                                   "            ",
379                                   "     %s     ",
380                                   "          3"},
381                                  {"4          ",
382                                   "   %s  %s   ",
383                                   "            ",
384                                   "            ",
385                                   "            ",
386                                   "   %s  %s   ",
387                                   "          4"},
388                                  {"5          ",
389                                   "   %s  %s   ",
390                                   "            ",
391                                   "     %s     ",
392                                   "            ",
393                                   "   %s  %s   ",
394                                   "          5"},
395                                  {"6          ",
396                                   "   %s  %s   ",
397                                   "            ",
398                                   "   %s  %s   ",
399                                   "            ",
400                                   "   %s  %s   ",
401                                   "          6"},
402                                  {"7          ",
403                                   "   %s  %s   ",
404                                   "     %s     ",
405                                   "   %s  %s   ",
406                                   "            ",
407                                   "   %s  %s   ",
408                                   "          7"},
409                                  {"8          ",
410                                   "   %s  %s   ",
411                                   "     %s     ",
412                                   "   %s  %s   ",
413                                   "     %s     ",
414                                   "   %s  %s   ",
415                                   "          8"},
416                                  {"9 %s  %s   ",
417                                   "            ",
418                                   "   %s  %s   ",
419                                   "     %s     ",
420                                   "   %s  %s   ",
421                                   "            ",
422                                   "   %s  %s 9"},
423                                  {"10 %s  %s   ",
424                                   "     %s     ",
425                                   "   %s  %s   ",
426                                   "            ",
427                                   "   %s  %s   ",
428                                   "     %s     ",
429                                   "   %s  %s 10"},
430                                  {"J   Λ     ",
431                                   "%s   ||     ",
432                                   "     ||     ",
433                                   "     ||     ",
434                                   "     ||     ",
435                                   "   |=亜=| %s",
436                                   "     目   J"},
437                                  {"Q ######   ",
438                                   "%s#      #  ",
439                                   "  # ++++ #  ",
440                                   "  # +==+ #  ",
441                                   "   # ++ #   ",
442                                   "    #  #  %s",
443                                   "     ##   Q"},
444                                  {"K          ",
445                                   "%s `⌒´   ",
446                                   "  γγγλ  ",
447                                   "  ο ο ι  ",
448                                   "   υ    ∂ ",
449                                   "    σ ノ %s",
450                                   "          K"} };
451         concptr joker_grph[7] = { "            ",
452                                   "     J     ",
453                                   "     O     ",
454                                   "     K     ",
455                                   "     E     ",
456                                   "     R     ",
457                                   "            " };
458
459 #else
460
461         concptr suit[4] = { "[]", "qp", "<>", "db" };
462         concptr card_grph[13][7] = { {"A    %s     ",
463                                   "     He     ",
464                                   "     ng     ",
465                                   "     ba     ",
466                                   "     nd     ",
467                                   "     %s     ",
468                                   "           A"},
469                                  {"2           ",
470                                   "     %s     ",
471                                   "            ",
472                                   "            ",
473                                   "            ",
474                                   "     %s     ",
475                                   "           2"},
476                                  {"3           ",
477                                   "     %s     ",
478                                   "            ",
479                                   "     %s     ",
480                                   "            ",
481                                   "     %s     ",
482                                   "           3"},
483                                  {"4           ",
484                                   "   %s  %s   ",
485                                   "            ",
486                                   "            ",
487                                   "            ",
488                                   "   %s  %s   ",
489                                   "           4"},
490                                  {"5           ",
491                                   "   %s  %s   ",
492                                   "            ",
493                                   "     %s     ",
494                                   "            ",
495                                   "   %s  %s   ",
496                                   "           5"},
497                                  {"6           ",
498                                   "   %s  %s   ",
499                                   "            ",
500                                   "   %s  %s   ",
501                                   "            ",
502                                   "   %s  %s   ",
503                                   "           6"},
504                                  {"7           ",
505                                   "   %s  %s   ",
506                                   "     %s     ",
507                                   "   %s  %s   ",
508                                   "            ",
509                                   "   %s  %s   ",
510                                   "           7"},
511                                  {"8           ",
512                                   "   %s  %s   ",
513                                   "     %s     ",
514                                   "   %s  %s   ",
515                                   "     %s     ",
516                                   "   %s  %s   ",
517                                   "           8"},
518                                  {"9  %s  %s   ",
519                                   "            ",
520                                   "   %s  %s   ",
521                                   "     %s     ",
522                                   "   %s  %s   ",
523                                   "            ",
524                                   "   %s  %s  9"},
525                                  {"10 %s  %s   ",
526                                   "     %s     ",
527                                   "   %s  %s   ",
528                                   "            ",
529                                   "   %s  %s   ",
530                                   "     %s     ",
531                                   "   %s  %s 10"},
532                                  {"J    /\\     ",
533                                   "%s   ||     ",
534                                   "     ||     ",
535                                   "     ||     ",
536                                   "     ||     ",
537                                   "   |=HH=| %s",
538                                   "     ][    J"},
539                                  {"Q  ######   ",
540                                   "%s#      #  ",
541                                   "  # ++++ #  ",
542                                   "  # +==+ #  ",
543                                   "   # ++ #   ",
544                                   "    #  #  %s",
545                                   "     ##    Q"},
546                                  {"K           ",
547                                   "%s _'~~`_   ",
548                                   "   jjjjj$&  ",
549                                   "   q q uu   ",
550                                   "   c    &   ",
551                                   "    v__/  %s",
552                                   "           K"} };
553         concptr joker_grph[7] = { "            ",
554                                   "     J      ",
555                                   "     O      ",
556                                   "     K      ",
557                                   "     E      ",
558                                   "     R      ",
559                                   "            " };
560 #endif
561
562         for (int i = 0; i < 5; i++)
563         {
564                 prt(_("┏━━━━━━┓", " +------------+ "), 5, i * 16);
565         }
566
567         for (int i = 0; i < 5; i++)
568         {
569                 for (int j = 0; j < 7; j++)
570                 {
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);
574                         else
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);
577                 }
578         }
579
580         for (int i = 0; i < 5; i++)
581         {
582                 prt(_("┗━━━━━━┛", " +------------+ "), 13, i * 16);
583         }
584 }
585
586
587 /*!
588  * @brief ポーカーの1プレイルーチン。
589  * @return 1プレイの役の結果
590  */
591 int do_poker(void)
592 {
593         int is_put[5];
594
595         bool done = FALSE;
596         bool decision = TRUE;
597         bool draw = TRUE;
598
599         int deck[53];
600         reset_deck(deck);
601
602         int deck_ptr = 0;
603         for (int i = 0; i < 5; i++)
604         {
605                 cards[i] = deck[deck_ptr++];
606                 is_put[i] = 0;
607         }
608
609         prt(_("残すカードを決めて下さい(方向で移動, スペースで選択)。", "Stay witch? "), 0, 0);
610
611         display_cards();
612         poker_hand_check();
613
614         int k = 2;
615         char cmd;
616         while (!done)
617         {
618                 if (draw)
619                 {
620                         display_kaeruka(k + decision * 5, is_put);
621                 }
622
623                 draw = FALSE;
624                 cmd = inkey();
625                 switch (cmd)
626                 {
627                 case '6': case 'l': case 'L': case KTRL('F'):
628                         if (!decision)
629                         {
630                                 k = (k + 1) % 5;
631                         }
632                         else
633                         {
634                                 k = 0;
635                                 decision = FALSE;
636                         }
637
638                         draw = TRUE;
639                         break;
640                 case '4': case 'h': case 'H': case KTRL('B'):
641                         if (!decision)
642                         {
643                                 k = (k + 4) % 5;
644                         }
645                         else
646                         {
647                                 k = 4;
648                                 decision = FALSE;
649                         }
650
651                         draw = TRUE;
652                         break;
653                 case '2': case 'j': case 'J': case KTRL('N'):
654                         if (!decision)
655                         {
656                                 decision = TRUE; draw = TRUE;
657                         }
658
659                         break;
660                 case '8': case 'k': case 'K': case KTRL('P'):
661                         if (decision)
662                         {
663                                 decision = FALSE; draw = TRUE;
664                         }
665
666                         break;
667                 case ' ': case '\r':
668                         if (decision)
669                         {
670                                 done = TRUE;
671                         }
672                         else
673                         {
674                                 is_put[k] = !is_put[k]; draw = TRUE;
675                         }
676
677                         break;
678                 default:
679                         break;
680                 }
681         }
682
683         prt("", 0, 0);
684
685         for (int i = 0; i < 5; i++)
686         {
687                 if (is_put[i] == 1) cards[i] = deck[deck_ptr++];
688         }
689
690         display_cards();
691
692         return poker_hand_check();
693 }