11-26 poker - 1

{c101345 クラス 11 \atop 公益太郎}

平成 15 年 11 月 24 日

1 問題

課題中の問題番号 1 番

• ツーペアの判定関数を作る

を選択した。

2 作成したプログラム

今回作成したプログラムは以下の通り。

1  #include <stdio.h>
2  #include <stdlib.h>
3  #include <string.h>
4
5  #define CARDS   52       /* 難しいのでジョーカー抜き */
6
7  typedef struct { /* 1 枚のカードの構造体 */
8    char *suit;           /* スート */
9    int  number; /* 数字 */
10    char *name; /* 読み名 */
11  } aCard;
12
13  typedef struct { /* 山、手札などカードの集合体 */
14    aCard card[CARDS]; /* 単一カードが 52 枚 */
15    int   n; /* 今何枚あるか */
16  } Cards;
17
18  char *hand[] = { /* 役の名前の配列 */

19    "ハイカード",
20    "ワンペア",
21    "ツーペア",

22 "スリーカード",

23    "ストレート",
24    "フラッシュ",
25    "フルハウス",

26 "フォーカード", 27 "ストレートフラッシュ", 28 "ロイヤルストレートフラッシュ",

29  };
30
31  void initialize(Cards *d) /* Cards 構造体のポインタ */
32  {
33    static char *suits[] = {

34 "ハート", "スペード", "ダイヤ", "クラブ", "ジョーカー"

35    };
36    static char *numbers[] = {
37      "JOKER", "A", "2", "3", "4", "5", "6", "7", "8", "9", "10",
38      "J", "Q", "K"
39    }; /* ここまでは initcard2 と同じ*/
40
41    int s, n, i;
42    for (i=0; i<CARDS; i++) {
43      s = i/13;                   /* 13 で割ると切捨て */
44      n = i%13 + 1;               /* 13 で割った余り+1 */
45      /* d->card が aCard 構造体の配列メンバになる。
46         d->card は配列なので d->card[x] でアクセスする。 */
47      d->card[i].suit=suits[s];
48      d->card[i].number = n;
49      d->card[i].name = numbers[n];
50    }

51 d->n = 52; /* この山が持っている枚数をセット */

52  }
53
54  void shuffle(Cards *d)
55  {
56    int i, pair;
57    int length=d->n;

58    srandom(time(NULL));
59    aCard work;
60    for (i=0; i<length; i++) {
61      pair = random()%length;  /* 交換相手の決定 */
62      memcpy(&work, &d->card[i], sizeof work);
63      memcpy(&d->card[i], &d->card[pair], sizeof work);
64      memcpy(&d->card[pair], &work, sizeof work);
65    }
66  }
67
68  void dispcard(aCard c)
69  {
70    printf("%s の%s\n", c.suit, c.name);
71  }
72
73  int is_onepair(Cards *c)
74  {
75    int box[14];          /* 該当番号が何個あるかの配列 */
76    int i, j;
77    int sum=0; /* 1 枚以上のカードが何種類? */
78    for (i=0; i<=13; i++) {/* All clear */
79      box[i] = 0;
80    }
81    for (j=0; j<c->n; j++) {      /* Count each number */
82      /* c->card[j] が手持の 5 枚目のカードの構造体 */
83      /* c->card[j].number は、その数字 */
84      box[c->card[j].number]++;
85    }
86    for (i=0; i<=13; i++) {
87      if (box[i]>0)
88        sum++;
89    }
90    printf("sum=%d\n", sum);
91    if (sum == 4)
92      return 1;
93    return 0;
94  }
95
96  int is_twopair(Cards *c)

 97  {
 98    int box[14];          /* 該当番号が何個あるかの配列 */
 99    int i, j;
100    int sum=0; /* 1 枚以上のカードが何種類? */
101    for (i=0; i<=13; i++) {/* All clear */
102      box[i] = 0;
103    }
104    for (j=0; j<c->n; j++) {      /* Count each number */
105      /* c->card[j] が手持の 5 枚目のカードの構造体 */
106      /* c->card[j].number は、その数字 */
107      box[c->card[j].number]++;
108    }
109    for (i=0; i<=13; i++) {
110      if (box[i]>0)
111        sum++;
112    }
113    printf("sum=%d\n", sum);
114    if (sum == 3) { /* 「数」の種類が 3 しかないなら */

115 ごにょごにょ; /* ツーペアの可能性があるので */ 116 もにょもにょ; /* 色々調べてみる */

117      if (ほにゃら)
118        return 1;
119    }
120    return 0;
121  }
122  int judge(Cards *c)
123  {
124    if (is_onepair(c)) {
125      return 1;
126    } else if (is_twopair(c)) {
127      return 2;
128    } else {
129      return 0;
130    }
131  }
132
133  int main(int argc, char *argv[])
134  {
135    Cards deck, human, com;

136    int i, result;
137    initialize(&deck);
138    shuffle(&deck);
139    /* 人間に 5 枚配る */
140    for (human.n=0; human.n<5; human.n++) {
141      memcpy(&human.card[human.n], &deck.card[--deck.n], sizeof
(aCard));
142    }
143
144    puts("あなたの手は");
145    for (i=0; i<human.n; i++) {
146      dispcard(human.card[i]);
147    }
148    result = judge(&human);
149    printf("result=%d, 役は%s\n", result, hand[result]);
150  }

3 実行結果

[figure]

% ./poker

あなたの手はダイヤの A ハートの Q ダイヤの 4 クラブの K クラブの 7

sum=5
result=0, 役はハイカード
% ./poker

あなたの手はハートの Q ダイヤの K ハートの K ダイヤの J ハートの J

sum=4
result=1, 役はツーペア

[figure]

〜〜〜以下省略〜〜〜 6