質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

1回答

411閲覧

C言語のオセロAI育成プログラムを作っている際に…

Removed_Past

総合スコア14

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2018/04/12 12:40

前提・実現したいこと

タイトルにもある通り、C言語を使って遺伝的アルゴリズムを使用したオセロのAI育成プログラムをしていて、現在その中の自動で対戦させる機構を作っています。

発生している問題

本来打つ事が出来るはずのマス目に対する「打てるかを判定する処理」を実行した際、「打つ事が出来ない」という判断をされてしまう。

![問題が起きている画面
上写真において、例えば盤面の「E2」にあたるマス(Check:○○のところで1マスずつ判定しています)の処理結果である下文は、
E2にあたるマス「41」(書式はx-1、y-1の順番です)はResult:2と表示されています。
Resultの数字は-1なら打つ事ができない、自然数ならそこに置いた場合に獲得できる枚数を表しています。
ここで、本来打てる「D1」「E1」「A2」といったマス「40」「50」「01」は-1、つまり打てない、と判断されてしまうのです。

該当のソースコード

C

1//付属の自作ヘッダです 2#define INCLUDE(a, b) do{x2 = a; y2 = b; enemy = 0;}while(0) 3 4int putboard(int x, int y, int player, int board[8][8]){ 5 int code = 0; 6 int a; 7 int enemy = 0; 8 int x2, y2; 9 10 // そのマスが空白か判定する 11 if(board[y][x] != 0){ 12 code = -1; 13 goto end; 14 } 15 16 // 八方向に挟めるかの判定 17 // 上 18 INCLUDE(x, y); 19 while(1){ 20 y2--; 21 if((y2 < 0) || !(enemy < 100)) break; 22 if(board[y2][x2] == 0) enemy += 900; 23 if(board[y2][x2] == player) enemy += 100; 24 if(board[y2][x2] == player * -1) enemy += 1; 25 } 26 if(!(enemy >= 900 || enemy - 100 == 0)){ 27 code += enemy - 100; 28 board[y][x] = player; 29 for(a = enemy - 100; a > 0; a--){ 30 board[y - a][x] = player; 31 } 32 } 33 // 下 34 INCLUDE(x, y); 35 while(1){ 36 y2++; 37 if((y2 > 8) || !(enemy < 100)) break; 38 if(board[y2][x2] == 0) enemy += 900; 39 if(board[y2][x2] == player) enemy += 100; 40 if(board[y2][x2] == player * -1) enemy += 1; 41 } 42 if(!(enemy >= 900 || enemy - 100 == 0)){ 43 code += enemy - 100; 44 board[y][x] = player; 45 for(a = enemy - 100; a > 0; a--){ 46 board[y + a][x] = player; 47 } 48 } 49 // 左 50 INCLUDE(x, y); 51 while(1){ 52 x2--; 53 if((x2 < 0) || !(enemy < 100)) break; 54 if(board[y2][x2] == 0) enemy += 900; 55 if(board[y2][x2] == player) enemy += 100; 56 if(board[y2][x2] == player * -1) enemy += 1; 57 } 58 if(!(enemy >= 900 || enemy - 100 == 0)){ 59 code += enemy - 100; 60 board[y][x] = player; 61 for(a = enemy - 100; a > 0; a--){ 62 board[y][x - a] = player; 63 } 64 } 65 // 右 66 INCLUDE(x, y); 67 while(1){ 68 x2++; 69 if((x2 > 8) || !(enemy < 100)) break; 70 if(board[y2][x2] == 0) enemy += 900; 71 if(board[y2][x2] == player) enemy += 100; 72 if(board[y2][x2] == player * -1) enemy += 1; 73 } 74 if(!(enemy >= 900 || enemy - 100 == 0)){ 75 code += enemy - 100; 76 board[y][x] = player; 77 for(a = enemy - 100; a > 0; a--){ 78 board[y][x + a] = player; 79 } 80 } 81 // 左上 82 INCLUDE(x, y); 83 while(1){ 84 x2--; 85 y2--; 86 if((y2 < 0) || (x2 < 0) || !(enemy < 100)) break; 87 if(board[y2][x2] == 0) enemy += 900; 88 if(board[y2][x2] == player) enemy += 100; 89 if(board[y2][x2] == player * -1) enemy += 1; 90 } 91 if(!(enemy >= 900 || enemy - 100 == 0)){ 92 code += enemy - 100; 93 board[y][x] = player; 94 for(a = enemy - 100; a > 0; a--){ 95 board[y - a][x - a] = player; 96 } 97 } 98 // 右上 99 INCLUDE(x, y); 100 while(1){ 101 x2++; 102 y2--; 103 if((y2 < 0) || (x2 > 8) || !(enemy < 100)) break; 104 if(board[y2][x2] == 0) enemy += 900; 105 if(board[y2][x2] == player) enemy += 100; 106 if(board[y2][x2] == player * -1) enemy += 1; 107 } 108 if(!(enemy >= 900 || enemy - 100 == 0)){ 109 code += enemy - 100; 110 board[y][x] = player; 111 for(a = enemy - 100; a > 0; a--){ 112 board[y - a][x + a] = player; 113 } 114 } 115 // 左下 116 INCLUDE(x, y); 117 while(1){ 118 x2--; 119 y2++; 120 if((y2 > 8) || (x2 < 0) || !(enemy < 100)) break; 121 if(board[y2][x2] == 0) enemy += 900; 122 if(board[y2][x2] == player) enemy += 100; 123 if(board[y2][x2] == player * -1) enemy += 1; 124 } 125 if(!(enemy >= 900 || enemy - 100 == 0)){ 126 code += enemy - 100; 127 board[y][x] = player; 128 for(a = enemy - 100; a > 0; a--){ 129 board[y + a][x - a] = player; 130 } 131 } 132 // 右下 133 INCLUDE(x, y); 134 while(1){ 135 x2++; 136 y2++; 137 if((y2 > 8) || (x2 > 8) || !(enemy < 100)) break; 138 if(board[y2][x2] == 0) enemy += 900; 139 if(board[y2][x2] == player) enemy += 100; 140 if(board[y2][x2] == player * -1) enemy += 1; 141 } 142 if(!(enemy >= 900 || enemy - 100 == 0)){ 143 code += enemy - 100; 144 board[y][x] = player; 145 for(a = enemy - 100; a > 0; a--){ 146 board[y + a][x + a] = player; 147 } 148 } 149 150 end: 151 // codeがここまでで0なら-1に、それ以外は+1する(置いた分) 152 if(code <= 0) code = -1; 153 else code++; 154 155 return code; 156} 157 158//メインのCファイルです(関連する関数のみを書いてます) 159void thinking(int player, const int bn, const int wn, int put[2]){ 160 srand(time(NULL)); 161 // とりま1手読み 162 int code = 0, x, y, a = 0; 163 int n, score, t; 164 int max = -10000; 165 int putx[64], puty[64]; 166 167 printf("Turn %s\n", player == 1 ? "Black" : "White"); 168 169 for(y = 0; y < 8; y++){ 170 for(x = 0; x < 8; x++){ 171 setvr(); 172 code = putboard(x, y, player, vboard); 173 printf("Check:%d%d Result:%d\n", x, y, code); 174 if(code < 0) continue; 175 score = pointcheck(player, player == 1 ? bn : wn); 176 if(score > max){ 177 max = score; 178 printf("New Max:%d\n", max); 179 putx[0] = x; 180 puty[0] = y; 181 t = 0; 182 } 183 if(score == max){ 184 t++; 185 putx[t] = x; 186 puty[t] = y; 187 } 188 } 189 } 190 191 if(t > 0){ 192 n = rand() % (t + 1); 193 put[0] = putx[n]; 194 put[1] = puty[n]; 195 } 196 else{ 197 put[0] = putx[0]; 198 put[1] = puty[1]; 199 } 200 201 printf("Max:%d\nPut:%d%d\n", max, put[0] + 1, put[1] + 1); 202}

試したこと

関数間の受け渡しの値を調節したりプログラムを読み直したりしたのですが、原因が分かりませんでした。

色々分かりにくい箇所があるかと思いますが、よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

ボードの範囲外に出たときの処理が足りてない。

座標00から上方向に行ったらbreakするけど、そのままifブロック内に入ってcodeが-100になってる。
盤面は8x8で64しかないから、何をどうやってもプラスに戻ることはない。

C

1 // 八方向に挟めるかの判定 2 // 上 3 INCLUDE(x, y); 4 while(1){ 5 y2--; 6 if((y2 < 0) || !(enemy < 100)) break; 7(略) 8 } 9 if(!(enemy >= 900 || enemy - 100 == 0)){ 10 code += enemy - 100; 11(略) 12 }

投稿2018/04/12 13:07

kopio

総合スコア487

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Removed_Past

2018/04/12 13:31

なるほど、確かに上方向の場合上端ならenemy=0のままwhile文を抜けるけど、それだとその直後のif文の条件に合ってしまうんですね… こんなに素早く的確な回答をして下さってありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問