teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

2

結果例を追加

2021/01/15 06:46

投稿

fana
fana

スコア12229

answer CHANGED
@@ -148,4 +148,23 @@
148
148
  }
149
149
  return 0;
150
150
  }
151
+ ```
152
+
153
+ 結果例:
154
+ ```text
155
+ Dealer : C8( 8) HQ(18)
156
+ Player : H5( 5) CK(15) DQ(25)
157
+ -----------
158
+ Dealer : C2( 2) S5( 7) D2( 9) SQ(19)
159
+ Player : C3( 3) S8(11) H4(15) HT(25)
160
+ -----------
161
+ Dealer : HQ(10) H8(18)
162
+ Player : H4( 4) DT(14) ST(24)
163
+ -----------
164
+ Dealer : DJ(10) C9(19)
165
+ Player : DT(10) S8(18) H6(24)
166
+ -----------
167
+ Dealer : H5( 5) D2( 7) H3(10) SK(20)
168
+ Player : C4( 4) H9(13) DJ(23)
169
+ -----------
151
170
  ```

1

コード追記

2021/01/15 06:46

投稿

fana
fana

スコア12229

answer CHANGED
@@ -4,4 +4,148 @@
4
4
  まず,ゲームを実際に(何も表示とかせずに処理だけを)試行して,プレイヤが絶対に勝てない(途中でカードを配るのをやめたら負けるし,配りすぎるとバーストする)パターンを見つける(見つかるまで繰り返し試行する).
5
5
 
6
6
  あとは,今まさにプログラムが始まったかのようにプレイヤとのゲームを開始してみせるが,実際には単に先に発見した勝ちパターンを再現してみせるだけである.
7
- (プレイヤーがプレイする段階では,既に,ディーラー側のカード内容も,プレイヤーには何枚目に何のカードが配られるのかも確定している.)
7
+ (プレイヤーがプレイする段階では,既に,ディーラー側のカード内容も,プレイヤーには何枚目に何のカードが配られるのかも確定している.)
8
+
9
+ ---
10
+
11
+ 実装してみた.
12
+
13
+ ```C
14
+ //カードのスコア.
15
+ //※面倒なので,Aのスコアは常に11点としている
16
+ unsigned char ScoreOfCard( unsigned char CardID )
17
+ {
18
+ static const unsigned char SCORE[] = { 11,2,3,4,5,6,7,8,9,10,10,10,10 };
19
+ return SCORE[ CardID % 13 ];
20
+ }
21
+
22
+ //カードの表示用
23
+ void PrintCard( unsigned char CardID )
24
+ {
25
+ printf( "%c%c", "SHDC"[ CardID/13 ], "A23456789TJQK"[ CardID%13 ] );
26
+ }
27
+
28
+ //デック
29
+ typedef struct Deck{ unsigned char Card[52]; } Deck;
30
+
31
+ //デックを初期化
32
+ void InitDeck( Deck *pDeck )
33
+ {
34
+ int i;
35
+ for( i=0; i<52; ++i ){ pDeck->Card[i]=i; }
36
+ }
37
+
38
+ //デックをシャッフルする
39
+ void ShuffleDeck( Deck *pDeck )
40
+ {
41
+ int i,j;
42
+ for( i=52; i>=1; --i )
43
+ {
44
+ j = rand() % i;
45
+ unsigned char tmp = pDeck->Card[i-1];
46
+ pDeck->Card[i-1] = pDeck->Card[j];
47
+ pDeck->Card[j] = tmp;
48
+ }
49
+ }
50
+
51
+ //ディーラーが勝利するようにデックをセットアップする.
52
+ //イカサマ方法として,ディーラーに対してカードを配る際には常にボトムディールすることとする
53
+ //(すなわち,ディーラーに配る用のカード群はデックのボトム側に仕込まれる).
54
+ //
55
+ //引数:
56
+ // pDeck : デック.処理が成功すると仕込まれた状態になる.
57
+ // pND : ディーラーに配る用にボトム側から仕込んだカードの枚数を返す用.
58
+ // pNP : プレイヤーに配る用にトップ側から仕込んだカードの枚数を返す用.
59
+ //
60
+ //戻り値:
61
+ // 成功時(うまく仕込めた時)には非0,失敗時は0を返す.
62
+ int SetupGame( Deck *pDeck, int *pND, int *pNP )
63
+ {
64
+ unsigned char DealerScore = 0;
65
+ unsigned char PlayerScore = 0;
66
+ const unsigned char *pCard;
67
+
68
+ //デックをシャッフル
69
+ ShuffleDeck( pDeck );
70
+
71
+ //ディーラーの手をチェック
72
+ pCard = pDeck->Card + 51; //ボトム
73
+ *pND = 0;
74
+ while( DealerScore<17 )
75
+ {
76
+ DealerScore += ScoreOfCard( *pCard );
77
+ ++*pND;
78
+ //※面倒なのでディーラーがバーストするパターンは棄却する
79
+ if( DealerScore > 21 )return 0;
80
+ --pCard;
81
+ }
82
+
83
+ //プレイヤーの手をチェック
84
+ pCard = pDeck->Card; //トップ
85
+ *pNP = 0;
86
+ while( 1 )
87
+ {
88
+ PlayerScore += ScoreOfCard( *pCard );
89
+ ++*pNP;
90
+
91
+ if( PlayerScore > 21 )break;
92
+ if( PlayerScore >= DealerScore )return 0;
93
+ ++pCard;
94
+ }
95
+ return 1;
96
+ }
97
+
98
+ //やってみる
99
+ void Test()
100
+ {
101
+ int i;
102
+ Deck TheDeck;
103
+ int ND, NP;
104
+ unsigned char Score;
105
+ const unsigned char *pCard;
106
+
107
+ //デックを初期化
108
+ InitDeck( &TheDeck );
109
+ //ディーラーの勝ちパターンを仕込む
110
+ while( !SetupGame( &TheDeck, &ND, &NP ) ){}
111
+
112
+ //以下,仕込んだ結果を表示してみる
113
+
114
+ //ディーラー側の手
115
+ Score = 0;
116
+ pCard = TheDeck.Card + 51; //※ボトム
117
+ printf( "Dealer : " );
118
+ for( i=0; i<ND; ++i, --pCard )
119
+ {
120
+ PrintCard( *pCard );
121
+ Score += ScoreOfCard( *pCard );
122
+ printf( "(%2d) ", (int)Score );
123
+ }
124
+ printf( "\n" );
125
+
126
+ //プレイヤー側(カードを配り続けてバーストするところまで)
127
+ Score = 0;
128
+ pCard = TheDeck.Card; //※トップ
129
+ printf( "Player : " );
130
+ for( i=0; i<NP; ++i, ++pCard )
131
+ {
132
+ PrintCard( *pCard );
133
+ Score += ScoreOfCard( *pCard );
134
+ printf( "(%2d) ", (int)Score );
135
+ }
136
+ printf( "\n" );
137
+ }
138
+
139
+ //main
140
+ int main(void)
141
+ {
142
+ int i;
143
+ srand( time(NULL) );
144
+ for( i=0; i<5; ++i )
145
+ {
146
+ Test();
147
+ printf( "-----------\n" );
148
+ }
149
+ return 0;
150
+ }
151
+ ```