質問編集履歴

3

ソースコードの追記と関数の内容の補足

2018/11/17 07:52

投稿

houki
houki

スコア22

test CHANGED
File without changes
test CHANGED
File without changes

2

ソースコードの追記

2018/11/17 07:52

投稿

houki
houki

スコア22

test CHANGED
File without changes
test CHANGED
@@ -118,25 +118,105 @@
118
118
 
119
119
  {
120
120
 
121
+ if (check_AI(ar_turn, mass[ar_turn], counta[ar_turn], countb[ar_turn]) == 1)//置ける箇所か判定し、置ける時は1を返します
122
+
123
+ {
124
+
125
+ mass[ar_turn][counta[ar_turn]][countb[ar_turn]] = my_color;
126
+
127
+ gl_y = counta[ar_turn];//calcularionaiで使う
128
+
129
+ gl_x = counta[ar_turn];
130
+
131
+ calculationai(mass[ar_turn]);//駒をひっくり返す
132
+
133
+ memcpy(mass[ar_turn + 1], mass[ar_turn], sizeof(mass[ar_turn]));//ar_turn+1のますに現在のマスをコピー
134
+
135
+
136
+
137
+ if (othello_AI_check(ar_turn + 1, mass) != 0) //自分の手番で、返り値が1の時、それ以降は調べる必要がなくなる。また相手の時も同様に返り値が0の時それ以降は調べる必要がなくなる。
138
+
139
+ return 10 * countb[ar_turn] + counta[ar_turn];
140
+
141
+ eva_count[ar_turn]++;
142
+
143
+ }
144
+
145
+ }
146
+
147
+ }
148
+
149
+
150
+
151
+ if (eva_count[ar_turn] == 0) //置く所がなかった(パスの時)
152
+
153
+ {
154
+
155
+ if (skip_count == 1)//両方打てなくなった時(スキップが二回続いた時)
156
+
157
+ {
158
+
159
+ if (result_AI(mass[ar_turn]) == 1)
160
+
161
+ return 10 * countb[ar_turn] + counta[ar_turn];
162
+
163
+ else
164
+
165
+ ZERO;
166
+
167
+ }
168
+
169
+ skip_count = 0; //連続してパスはなかったのでリセットする
170
+
171
+ skip_count++;
172
+
173
+ memcpy(mass[ar_turn + 1], mass[ar_turn], sizeof(mass[ar_turn]));
174
+
175
+ return othello_AI_check(ar_turn + 1, mass);
176
+
177
+ }
178
+
179
+ else //置くところはあるが返り値が全てZERO(=0)であった場合
180
+
181
+ skip_count = 0; //連続してパスはなかったのでリセットする
182
+
183
+ return ZERO;
184
+
185
+ }
186
+
187
+ //_______________________________________________________________相手の手番 以下似た処理
188
+
189
+
190
+
191
+ else//相手の手番
192
+
193
+ {
194
+
195
+ for (counta[ar_turn] = 1; counta[ar_turn] <= 8; counta[ar_turn]++)
196
+
197
+ {
198
+
199
+ for (countb[ar_turn] = 1; countb[ar_turn] <= 8; countb[ar_turn]++)
200
+
201
+ {
202
+
121
203
  if (check_AI(ar_turn, mass[ar_turn], counta[ar_turn], countb[ar_turn]) == 1)
122
204
 
123
205
  {
124
206
 
125
207
  mass[ar_turn][counta[ar_turn]][countb[ar_turn]] = my_color;
126
208
 
127
- gl_y = counta[ar_turn];//calcularionaiで使う
209
+ gl_y = counta[ar_turn];
128
210
 
129
211
  gl_x = counta[ar_turn];
130
212
 
131
- calculationai(mass[ar_turn]);//駒をひっくり返す
213
+ calculationai(mass[ar_turn]);
132
-
214
+
133
- memcpy(mass[ar_turn + 1], mass[ar_turn], sizeof(mass[ar_turn]));//ar_turn+1のますに現在のマスをコピー
215
+ memcpy(mass[ar_turn + 1], mass[ar_turn], sizeof(mass[ar_turn]));
134
-
135
-
136
-
137
- if (othello_AI_check(ar_turn + 1, mass) != 0) //自分の手番で、返り値が1の時、それ以降は調べる必要がなくなる。また相手の時も同様に返り値が0の時それ以降は調べる必要がなくなる。
216
+
138
-
139
- return 10 * countb[ar_turn] + counta[ar_turn];
217
+ if (othello_AI_check(ar_turn + 1, mass) == ZERO)
218
+
219
+ return ZERO;
140
220
 
141
221
  eva_count[ar_turn]++;
142
222
 
@@ -176,94 +256,14 @@
176
256
 
177
257
  }
178
258
 
179
- else //置くところはあが返り値が全てZERO(=0)であった場合
259
+ else //置くところはあったが返り値が全て1であった場合
180
-
260
+
181
- skip_count = 0; //連続してパスはなかったのでリセットする
261
+ skip_count = 0; //連続してパスはなかったのでリセットする
182
-
262
+
183
- return ZERO;
263
+ return 10 * countb[ar_turn] + counta[ar_turn];
184
264
 
185
265
  }
186
266
 
187
- //_______________________________________________________________相手の手番
188
-
189
-
190
-
191
- else//相手の手番
192
-
193
- {
194
-
195
- for (counta[ar_turn] = 1; counta[ar_turn] <= 8; counta[ar_turn]++)
196
-
197
- {
198
-
199
- for (countb[ar_turn] = 1; countb[ar_turn] <= 8; countb[ar_turn]++)
200
-
201
- {
202
-
203
- if (check_AI(ar_turn, mass[ar_turn], counta[ar_turn], countb[ar_turn]) == 1)
204
-
205
- {
206
-
207
- mass[ar_turn][counta[ar_turn]][countb[ar_turn]] = my_color;
208
-
209
- gl_y = counta[ar_turn];
210
-
211
- gl_x = counta[ar_turn];
212
-
213
- calculationai(mass[ar_turn]);
214
-
215
- memcpy(mass[ar_turn + 1], mass[ar_turn], sizeof(mass[ar_turn]));
216
-
217
- if (othello_AI_check(ar_turn + 1, mass) == ZERO)
218
-
219
- return ZERO;
220
-
221
- eva_count[ar_turn]++;
222
-
223
- }
224
-
225
- }
226
-
227
- }
228
-
229
-
230
-
231
- if (eva_count[ar_turn] == 0) //置く所がなかった(パスの時)
232
-
233
- {
234
-
235
- if (skip_count == 1)//両方打てなくなった時(スキップが二回続いた時)
236
-
237
- {
238
-
239
- if (result_AI(mass[ar_turn]) == 1)
240
-
241
- return 10 * countb[ar_turn] + counta[ar_turn];
242
-
243
- else
244
-
245
- ZERO;
246
-
247
- }
248
-
249
- skip_count = 0; //連続してパスはなかったのでリセットする
250
-
251
- skip_count++;
252
-
253
- memcpy(mass[ar_turn + 1], mass[ar_turn], sizeof(mass[ar_turn]));
254
-
255
- return othello_AI_check(ar_turn + 1, mass);
256
-
257
- }
258
-
259
- else //置くところはあったが返り値が全て1であった場合
260
-
261
- skip_count = 0; //連続してパスはなかったのでリセットする
262
-
263
- return 10 * countb[ar_turn] + counta[ar_turn];
264
-
265
- }
266
-
267
267
  }
268
268
 
269
269
  ```

1

ソースコードの追記と関数の内容の補足

2018/11/17 07:48

投稿

houki
houki

スコア22

test CHANGED
File without changes
test CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  オセロのAIの関数を作っていて「Bus error 10」が表示されます。
6
6
 
7
- 再帰関数で手番を交代していきながら、必要な情報を手に入れるという内容です。
7
+ 再帰関数で手番を交代していきながら、必要な情報を手に入れるという内容です。以下に具体的に書いています。
8
8
 
9
9
 
10
10
 
@@ -14,6 +14,266 @@
14
14
 
15
15
 
16
16
 
17
+
18
+
19
+ <内容>
20
+
21
+ 注意!ここでの 自分 はコンピュータ側のことを指します。
22
+
23
+ <前提>
24
+
25
+ 相手は常に最善の手を打ってくる。
26
+
27
+
28
+
29
+ ohelloAI関数が呼ばれると、その手番から勝敗が決定する最終局面まで再帰関数で処理して、その結果を返り値で返す(自分の、勝利は1を、引き分け・敗北はZERO(=0)。
30
+
31
+
32
+
33
+ 相手の手番にZERO(=0)が返り値として返ってくると、その(自分は敗北する・相手は負けない)マスに打たれて、自分は敗北する。ので、相手手番に複数置ける場所があったとして、複数箇所を探索する前にZEROが返ってくるとif文でreturn ZEROを返します。
34
+
35
+ 自分の手番の時には、上記とは逆で、ZERO(=0)でない返り値が返ってくるとそこに打つというようにします。同様に複数置ける場所があったとして、複数箇所探索する前にZERO以外が帰ってくるとif文で関数の都合上return (そのマスの座標)を返します。
36
+
37
+
38
+
39
+
40
+
41
+
42
+
43
+
44
+
45
+
46
+
47
+ ### 該当のソースコード
48
+
49
+
50
+
51
+ ```c
52
+
53
+ int othelloAI(void)
54
+
55
+ {
56
+
57
+ static int mass[60][SIZE][SIZE];
58
+
59
+ static int t = 0;
60
+
61
+
62
+
63
+ memcpy(mass[t], c_mas2, sizeof(mass[t]));
64
+
65
+
66
+
67
+ return othello_AI_check(t, mass);
68
+
69
+ }
70
+
71
+
72
+
73
+ int othello_AI_check(int ar_turn, int mass[60][SIZE][SIZE])
74
+
75
+ {
76
+
77
+ static int counta[70] = {0};
78
+
79
+ static int countb[70] = {0};
80
+
81
+ static int eva_count[70];
82
+
83
+ static int skip_count = 0;
84
+
85
+
86
+
87
+ if (E_cnt_AI(mass[ar_turn]) == 0) //最後までいった(マスが全て埋まった)とき
88
+
89
+ {
90
+
91
+ skip_count = 0; //連続してパスはなかったので初期化する
92
+
93
+ if (result_AI(mass[ar_turn]) == 1)
94
+
95
+ return 10 * countb[ar_turn] + counta[ar_turn];
96
+
97
+ }
98
+
99
+
100
+
101
+ eva_count[ar_turn] = 0; //初期化する。他のcount変数はfor文で初期化されている
102
+
103
+
104
+
105
+ turn_change(ar_turn);
106
+
107
+
108
+
109
+ if (ar_turn % 2 == 0)//自分の手番
110
+
111
+ {
112
+
113
+ for (counta[ar_turn] = 1; counta[ar_turn] <= 8; counta[ar_turn]++)
114
+
115
+ {
116
+
117
+ for (countb[ar_turn] = 1; countb[ar_turn] <= 8; countb[ar_turn]++)
118
+
119
+ {
120
+
121
+ if (check_AI(ar_turn, mass[ar_turn], counta[ar_turn], countb[ar_turn]) == 1)
122
+
123
+ {
124
+
125
+ mass[ar_turn][counta[ar_turn]][countb[ar_turn]] = my_color;
126
+
127
+ gl_y = counta[ar_turn];//calcularionaiで使う
128
+
129
+ gl_x = counta[ar_turn];
130
+
131
+ calculationai(mass[ar_turn]);//駒をひっくり返す
132
+
133
+ memcpy(mass[ar_turn + 1], mass[ar_turn], sizeof(mass[ar_turn]));//ar_turn+1のますに現在のマスをコピー
134
+
135
+
136
+
137
+ if (othello_AI_check(ar_turn + 1, mass) != 0) //自分の手番で、返り値が1の時、それ以降は調べる必要がなくなる。また相手の時も同様に返り値が0の時それ以降は調べる必要がなくなる。
138
+
139
+ return 10 * countb[ar_turn] + counta[ar_turn];
140
+
141
+ eva_count[ar_turn]++;
142
+
143
+ }
144
+
145
+ }
146
+
147
+ }
148
+
149
+
150
+
151
+ if (eva_count[ar_turn] == 0) //置く所がなかった(パスの時)
152
+
153
+ {
154
+
155
+ if (skip_count == 1)//両方打てなくなった時(スキップが二回続いた時)
156
+
157
+ {
158
+
159
+ if (result_AI(mass[ar_turn]) == 1)
160
+
161
+ return 10 * countb[ar_turn] + counta[ar_turn];
162
+
163
+ else
164
+
165
+ ZERO;
166
+
167
+ }
168
+
169
+ skip_count = 0; //連続してパスはなかったのでリセットする
170
+
171
+ skip_count++;
172
+
173
+ memcpy(mass[ar_turn + 1], mass[ar_turn], sizeof(mass[ar_turn]));
174
+
175
+ return othello_AI_check(ar_turn + 1, mass);
176
+
177
+ }
178
+
179
+ else //置くところはあるが返り値が全てZERO(=0)であった場合
180
+
181
+ skip_count = 0; //連続してパスはなかったのでリセットする
182
+
183
+ return ZERO;
184
+
185
+ }
186
+
187
+ //_______________________________________________________________相手の手番
188
+
189
+
190
+
191
+ else//相手の手番
192
+
193
+ {
194
+
195
+ for (counta[ar_turn] = 1; counta[ar_turn] <= 8; counta[ar_turn]++)
196
+
197
+ {
198
+
199
+ for (countb[ar_turn] = 1; countb[ar_turn] <= 8; countb[ar_turn]++)
200
+
201
+ {
202
+
203
+ if (check_AI(ar_turn, mass[ar_turn], counta[ar_turn], countb[ar_turn]) == 1)
204
+
205
+ {
206
+
207
+ mass[ar_turn][counta[ar_turn]][countb[ar_turn]] = my_color;
208
+
209
+ gl_y = counta[ar_turn];
210
+
211
+ gl_x = counta[ar_turn];
212
+
213
+ calculationai(mass[ar_turn]);
214
+
215
+ memcpy(mass[ar_turn + 1], mass[ar_turn], sizeof(mass[ar_turn]));
216
+
217
+ if (othello_AI_check(ar_turn + 1, mass) == ZERO)
218
+
219
+ return ZERO;
220
+
221
+ eva_count[ar_turn]++;
222
+
223
+ }
224
+
225
+ }
226
+
227
+ }
228
+
229
+
230
+
231
+ if (eva_count[ar_turn] == 0) //置く所がなかった(パスの時)
232
+
233
+ {
234
+
235
+ if (skip_count == 1)//両方打てなくなった時(スキップが二回続いた時)
236
+
237
+ {
238
+
239
+ if (result_AI(mass[ar_turn]) == 1)
240
+
241
+ return 10 * countb[ar_turn] + counta[ar_turn];
242
+
243
+ else
244
+
245
+ ZERO;
246
+
247
+ }
248
+
249
+ skip_count = 0; //連続してパスはなかったのでリセットする
250
+
251
+ skip_count++;
252
+
253
+ memcpy(mass[ar_turn + 1], mass[ar_turn], sizeof(mass[ar_turn]));
254
+
255
+ return othello_AI_check(ar_turn + 1, mass);
256
+
257
+ }
258
+
259
+ else //置くところはあったが返り値が全て1であった場合
260
+
261
+ skip_count = 0; //連続してパスはなかったのでリセットする
262
+
263
+ return 10 * countb[ar_turn] + counta[ar_turn];
264
+
265
+ }
266
+
267
+ }
268
+
269
+ ```
270
+
271
+
272
+
273
+
274
+
275
+
276
+
17
277
  ### 試したこと
18
278
 
19
279
 
@@ -24,6 +284,10 @@
24
284
 
25
285
 
26
286
 
287
+
288
+
289
+
290
+
27
291
  ### 補足情報(FW/ツールのバージョンなど)
28
292
 
29
293
 
@@ -37,7 +301,3 @@
37
301
 
38
302
 
39
303
  vscode
40
-
41
-
42
-
43
- 探索時間が長いからBus errorが出る訳ではない時は、ソースコードを貼ろうと思います。