回答編集履歴

1

コード追加

2021/09/17 16:10

投稿

jimbe
jimbe

スコア13215

test CHANGED
@@ -13,3 +13,409 @@
13
13
  }
14
14
 
15
15
  ```
16
+
17
+
18
+
19
+ ----
20
+
21
+ 弄ってみました。
22
+
23
+ 置ける場所等を何度も探すのを避けるため、points 配列を用意しました。
24
+
25
+ Delta 構造体と Point 構造体が同じですが、まぁ雰囲気ということで。
26
+
27
+ ```c
28
+
29
+ #include <stdio.h>
30
+
31
+ #include <stdlib.h>
32
+
33
+ #include <memory.h>
34
+
35
+ #include <time.h>
36
+
37
+ #include <stdarg.h>
38
+
39
+
40
+
41
+ #define WHITE 'w'
42
+
43
+ #define BLACK 'b'
44
+
45
+ #define SPACE '.'
46
+
47
+
48
+
49
+ #define TRUE 1
50
+
51
+ #define FALSE 0
52
+
53
+
54
+
55
+ #define SIZE 8
56
+
57
+
58
+
59
+ #ifndef NULL
60
+
61
+ #define NULL ((void)0)
62
+
63
+ #endif
64
+
65
+
66
+
67
+ char board[SIZE][SIZE];
68
+
69
+
70
+
71
+ //初期化
72
+
73
+ void init(){
74
+
75
+ srand((unsigned int)time(NULL));
76
+
77
+
78
+
79
+ memset(board, SPACE, sizeof(board));
80
+
81
+ board[SIZE/2-1][SIZE/2-1]=board[SIZE/2][SIZE/2]=WHITE;//一旦wは自分,bが敵だとする
82
+
83
+ board[SIZE/2-1][SIZE/2]=board[SIZE/2][SIZE/2-1]=BLACK;
84
+
85
+ }
86
+
87
+
88
+
89
+ //盤面表示
90
+
91
+ void print(){
92
+
93
+ printf(" ");
94
+
95
+ for(int x=0; x<SIZE; x++){
96
+
97
+ printf("%d", x+1);
98
+
99
+ }
100
+
101
+ printf("\n");
102
+
103
+ for(int y=0; y<SIZE; y++){
104
+
105
+ printf("%d", y+1);
106
+
107
+ for(int x=0; x<SIZE; x++){
108
+
109
+ printf("%c", board[y][x]);
110
+
111
+ }
112
+
113
+ printf("\n");
114
+
115
+ }
116
+
117
+ }
118
+
119
+
120
+
121
+ //結果
122
+
123
+ void judgement(){
124
+
125
+ int w_count = 0;
126
+
127
+ int b_count = 0;
128
+
129
+ for(int y=0; y<SIZE; y++){
130
+
131
+ for(int x=0; x<SIZE; x++){
132
+
133
+ if(board[y][x] == WHITE){
134
+
135
+ ++w_count;
136
+
137
+ } else if(board[y][x] == BLACK){
138
+
139
+ ++b_count;
140
+
141
+ }
142
+
143
+ }
144
+
145
+ }
146
+
147
+
148
+
149
+ printf("白%d枚、黒%d枚\n",w_count, b_count);
150
+
151
+ if(w_count == b_count){
152
+
153
+ printf("引き分けです\n");
154
+
155
+ }else if(w_count > b_count){
156
+
157
+ printf("あなたの勝利です\n");
158
+
159
+ }else{
160
+
161
+ printf("あなたの敗北です\n");
162
+
163
+ }
164
+
165
+ }
166
+
167
+
168
+
169
+ //8方向
170
+
171
+ typedef struct Delta { int x, y; } Delta;
172
+
173
+ Delta deltas[] = {
174
+
175
+ {-1,-1}, {0,-1}, {1,-1},
176
+
177
+ {-1, 0}, {1, 0},
178
+
179
+ {-1, 1}, {0, 1}, {1, 1}
180
+
181
+ };
182
+
183
+
184
+
185
+ //座標保持用バッファ
186
+
187
+ typedef struct Point { int x, y; } Point;
188
+
189
+ Point points[SIZE*SIZE];
190
+
191
+
192
+
193
+ //x,y に打った場合にひっくり返せる数を返す.
194
+
195
+ //keepPoints に TRUE を指定すると, ひっくり返せる各座標を points に格納する.
196
+
197
+ int acquiredPoints(int x, int y, int color, int keepPoints){
198
+
199
+ int total = 0;
200
+
201
+ if(board[y][x] != SPACE) return total;
202
+
203
+
204
+
205
+ for(int i=0; i<sizeof(deltas)/sizeof(Delta); i++) {
206
+
207
+ Delta *d = &deltas[i];
208
+
209
+
210
+
211
+ for(int sx=x+d->x, sy=y+d->y, count=0;
212
+
213
+ sx>=0 && sy>=0 && sx<SIZE && sy<SIZE && board[sy][sx]!=SPACE;
214
+
215
+ sx+=d->x, sy+=d->y, count++){
216
+
217
+ if(board[sy][sx] == color) { //挟める
218
+
219
+ total += count;
220
+
221
+ break;
222
+
223
+ }
224
+
225
+ if(keepPoints) {
226
+
227
+ points[total + count].x = sx;
228
+
229
+ points[total + count].y = sy;
230
+
231
+ }
232
+
233
+ }
234
+
235
+ }
236
+
237
+ return total;
238
+
239
+ }
240
+
241
+
242
+
243
+ //x,y と points の各座標に color を設定する.
244
+
245
+ void acquired(int x, int y, int total, int color) {
246
+
247
+ board[y][x] = color;
248
+
249
+ for(int i=0; i<total; i++) {
250
+
251
+ board[points[i].y][points[i].x] = color;
252
+
253
+ }
254
+
255
+ }
256
+
257
+
258
+
259
+ //打てる各座標を points に格納しその件数を返す.
260
+
261
+ int availablePoints(int color) {
262
+
263
+ int count = 0;
264
+
265
+ for(int y=0; y<SIZE; y++){
266
+
267
+ for(int x=0; x<SIZE; x++){
268
+
269
+ if(acquiredPoints(x, y, color, FALSE) > 0) {
270
+
271
+ points[count].x = x;
272
+
273
+ points[count].y = y;
274
+
275
+ count ++;
276
+
277
+ }
278
+
279
+ }
280
+
281
+ }
282
+
283
+ return count;
284
+
285
+ }
286
+
287
+
288
+
289
+ int input(int min, int max, char *fmt, ...) {
290
+
291
+ int v;
292
+
293
+ va_list arg_ptr;
294
+
295
+ do {
296
+
297
+ va_start(arg_ptr, fmt);
298
+
299
+ vprintf(fmt, arg_ptr);
300
+
301
+ va_end(arg_ptr);
302
+
303
+
304
+
305
+ scanf("%d",&v);
306
+
307
+ } while(v < min || max < v);
308
+
309
+ return v;
310
+
311
+ }
312
+
313
+
314
+
315
+ void turnPlayer(int color){
316
+
317
+ int count = availablePoints(color);
318
+
319
+ if(count == 0) {
320
+
321
+ printf("あなたは打てないのでパスです\n");
322
+
323
+ return;
324
+
325
+ }
326
+
327
+
328
+
329
+ int x, y, total;
330
+
331
+ printf("あなた('%c')のターンです。\n", color);
332
+
333
+ while(1) {
334
+
335
+ x = input(1, SIZE, "横方向(x:1-%d)", SIZE);
336
+
337
+ y = input(1, SIZE, "縦方向(y:1-%d)", SIZE);
338
+
339
+ if(x>=1 && y>=1 && x<=SIZE && y<=SIZE && (total = acquiredPoints(x-1, y-1, color, TRUE)) > 0){
340
+
341
+ acquired(x-1, y-1, total, color);
342
+
343
+ print();
344
+
345
+ return;
346
+
347
+ }
348
+
349
+ printf("そこには打てません。\n");
350
+
351
+ }
352
+
353
+ }
354
+
355
+
356
+
357
+ void turnComputer(int color) {
358
+
359
+ int count = availablePoints(color);
360
+
361
+ if(count == 0) {
362
+
363
+ printf("コンピュータが打てるコマがないのでパス。\n");
364
+
365
+ return;
366
+
367
+ }
368
+
369
+
370
+
371
+ Point point = points[rand() % count]; //コピー
372
+
373
+ int total = acquiredPoints(point.x, point.y, color, TRUE);
374
+
375
+ acquired(point.x, point.y, total, color);
376
+
377
+ printf("コンピュータ('%c')は x%d,y%d に打ちました。\n", color, point.x+1, point.y+1);
378
+
379
+ print();
380
+
381
+ }
382
+
383
+
384
+
385
+ int main(){
386
+
387
+ printf("/////////////////オセロ/////////////////\n");
388
+
389
+ init();
390
+
391
+ print();
392
+
393
+
394
+
395
+ while(1) {
396
+
397
+ turnPlayer(WHITE);
398
+
399
+ turnComputer(BLACK);
400
+
401
+
402
+
403
+ if(!availablePoints(WHITE) && !availablePoints(BLACK)){
404
+
405
+ break;
406
+
407
+ }
408
+
409
+ }
410
+
411
+
412
+
413
+ printf("試合終了です\n");
414
+
415
+ judgement();
416
+
417
+ return 0;
418
+
419
+ }
420
+
421
+ ```