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

回答編集履歴

1

コード追加

2021/09/17 16:10

投稿

jimbe
jimbe

スコア13355

answer CHANGED
@@ -5,4 +5,207 @@
5
5
  sy -= sy; //!!!!!
6
6
  board[sy][sx]=my_iro;
7
7
  }
8
+ ```
9
+
10
+ ----
11
+ 弄ってみました。
12
+ 置ける場所等を何度も探すのを避けるため、points 配列を用意しました。
13
+ Delta 構造体と Point 構造体が同じですが、まぁ雰囲気ということで。
14
+ ```c
15
+ #include <stdio.h>
16
+ #include <stdlib.h>
17
+ #include <memory.h>
18
+ #include <time.h>
19
+ #include <stdarg.h>
20
+
21
+ #define WHITE 'w'
22
+ #define BLACK 'b'
23
+ #define SPACE '.'
24
+
25
+ #define TRUE 1
26
+ #define FALSE 0
27
+
28
+ #define SIZE 8
29
+
30
+ #ifndef NULL
31
+ #define NULL ((void)0)
32
+ #endif
33
+
34
+ char board[SIZE][SIZE];
35
+
36
+ //初期化
37
+ void init(){
38
+ srand((unsigned int)time(NULL));
39
+
40
+ memset(board, SPACE, sizeof(board));
41
+ board[SIZE/2-1][SIZE/2-1]=board[SIZE/2][SIZE/2]=WHITE;//一旦wは自分,bが敵だとする
42
+ board[SIZE/2-1][SIZE/2]=board[SIZE/2][SIZE/2-1]=BLACK;
43
+ }
44
+
45
+ //盤面表示
46
+ void print(){
47
+ printf(" ");
48
+ for(int x=0; x<SIZE; x++){
49
+ printf("%d", x+1);
50
+ }
51
+ printf("\n");
52
+ for(int y=0; y<SIZE; y++){
53
+ printf("%d", y+1);
54
+ for(int x=0; x<SIZE; x++){
55
+ printf("%c", board[y][x]);
56
+ }
57
+ printf("\n");
58
+ }
59
+ }
60
+
61
+ //結果
62
+ void judgement(){
63
+ int w_count = 0;
64
+ int b_count = 0;
65
+ for(int y=0; y<SIZE; y++){
66
+ for(int x=0; x<SIZE; x++){
67
+ if(board[y][x] == WHITE){
68
+ ++w_count;
69
+ } else if(board[y][x] == BLACK){
70
+ ++b_count;
71
+ }
72
+ }
73
+ }
74
+
75
+ printf("白%d枚、黒%d枚\n",w_count, b_count);
76
+ if(w_count == b_count){
77
+ printf("引き分けです\n");
78
+ }else if(w_count > b_count){
79
+ printf("あなたの勝利です\n");
80
+ }else{
81
+ printf("あなたの敗北です\n");
82
+ }
83
+ }
84
+
85
+ //8方向
86
+ typedef struct Delta { int x, y; } Delta;
87
+ Delta deltas[] = {
88
+ {-1,-1}, {0,-1}, {1,-1},
89
+ {-1, 0}, {1, 0},
90
+ {-1, 1}, {0, 1}, {1, 1}
91
+ };
92
+
93
+ //座標保持用バッファ
94
+ typedef struct Point { int x, y; } Point;
95
+ Point points[SIZE*SIZE];
96
+
97
+ //x,y に打った場合にひっくり返せる数を返す.
98
+ //keepPoints に TRUE を指定すると, ひっくり返せる各座標を points に格納する.
99
+ int acquiredPoints(int x, int y, int color, int keepPoints){
100
+ int total = 0;
101
+ if(board[y][x] != SPACE) return total;
102
+
103
+ for(int i=0; i<sizeof(deltas)/sizeof(Delta); i++) {
104
+ Delta *d = &deltas[i];
105
+
106
+ for(int sx=x+d->x, sy=y+d->y, count=0;
107
+ sx>=0 && sy>=0 && sx<SIZE && sy<SIZE && board[sy][sx]!=SPACE;
108
+ sx+=d->x, sy+=d->y, count++){
109
+ if(board[sy][sx] == color) { //挟める
110
+ total += count;
111
+ break;
112
+ }
113
+ if(keepPoints) {
114
+ points[total + count].x = sx;
115
+ points[total + count].y = sy;
116
+ }
117
+ }
118
+ }
119
+ return total;
120
+ }
121
+
122
+ //x,y と points の各座標に color を設定する.
123
+ void acquired(int x, int y, int total, int color) {
124
+ board[y][x] = color;
125
+ for(int i=0; i<total; i++) {
126
+ board[points[i].y][points[i].x] = color;
127
+ }
128
+ }
129
+
130
+ //打てる各座標を points に格納しその件数を返す.
131
+ int availablePoints(int color) {
132
+ int count = 0;
133
+ for(int y=0; y<SIZE; y++){
134
+ for(int x=0; x<SIZE; x++){
135
+ if(acquiredPoints(x, y, color, FALSE) > 0) {
136
+ points[count].x = x;
137
+ points[count].y = y;
138
+ count ++;
139
+ }
140
+ }
141
+ }
142
+ return count;
143
+ }
144
+
145
+ int input(int min, int max, char *fmt, ...) {
146
+ int v;
147
+ va_list arg_ptr;
148
+ do {
149
+ va_start(arg_ptr, fmt);
150
+ vprintf(fmt, arg_ptr);
151
+ va_end(arg_ptr);
152
+
153
+ scanf("%d",&v);
154
+ } while(v < min || max < v);
155
+ return v;
156
+ }
157
+
158
+ void turnPlayer(int color){
159
+ int count = availablePoints(color);
160
+ if(count == 0) {
161
+ printf("あなたは打てないのでパスです\n");
162
+ return;
163
+ }
164
+
165
+ int x, y, total;
166
+ printf("あなた('%c')のターンです。\n", color);
167
+ while(1) {
168
+ x = input(1, SIZE, "横方向(x:1-%d)", SIZE);
169
+ y = input(1, SIZE, "縦方向(y:1-%d)", SIZE);
170
+ if(x>=1 && y>=1 && x<=SIZE && y<=SIZE && (total = acquiredPoints(x-1, y-1, color, TRUE)) > 0){
171
+ acquired(x-1, y-1, total, color);
172
+ print();
173
+ return;
174
+ }
175
+ printf("そこには打てません。\n");
176
+ }
177
+ }
178
+
179
+ void turnComputer(int color) {
180
+ int count = availablePoints(color);
181
+ if(count == 0) {
182
+ printf("コンピュータが打てるコマがないのでパス。\n");
183
+ return;
184
+ }
185
+
186
+ Point point = points[rand() % count]; //コピー
187
+ int total = acquiredPoints(point.x, point.y, color, TRUE);
188
+ acquired(point.x, point.y, total, color);
189
+ printf("コンピュータ('%c')は x%d,y%d に打ちました。\n", color, point.x+1, point.y+1);
190
+ print();
191
+ }
192
+
193
+ int main(){
194
+ printf("/////////////////オセロ/////////////////\n");
195
+ init();
196
+ print();
197
+
198
+ while(1) {
199
+ turnPlayer(WHITE);
200
+ turnComputer(BLACK);
201
+
202
+ if(!availablePoints(WHITE) && !availablePoints(BLACK)){
203
+ break;
204
+ }
205
+ }
206
+
207
+ printf("試合終了です\n");
208
+ judgement();
209
+ return 0;
210
+ }
8
211
  ```