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

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

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

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

Q&A

解決済

3回答

784閲覧

Bus error 10は、処理時間の長さに起因しますか?

houki

総合スコア22

C

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

0グッド

0クリップ

投稿2018/11/17 07:00

編集2018/11/17 07:52

前提・実現したいこと

オセロのAIの関数を作っていて「Bus error 10」が表示されます。
再帰関数で手番を交代していきながら、必要な情報を手に入れるという内容です。以下に具体的に書いています。

Bus error は配列のインデックスが超えたりすると起こったりするとの認識なのですが、
疑問に思っていることは、あまりにも探索時間(処理時間)が長い場合に、Bus error 10は出たりしますか?

<内容>
注意!ここでの 自分 はコンピュータ側のことを指します。
<前提>
相手は常に最善の手を打ってくる。

ohelloAI関数が呼ばれると、その手番から勝敗が決定する最終局面まで再帰関数で処理して、その結果を返り値で返す(自分の、勝利は1を、引き分け・敗北はZERO(=0)。

相手の手番にZERO(=0)が返り値として返ってくると、その(自分は敗北する・相手は負けない)マスに打たれて、自分は敗北する。ので、相手手番に複数置ける場所があったとして、複数箇所を探索する前にZEROが返ってくるとif文でreturn ZEROを返します。
自分の手番の時には、上記とは逆で、ZERO(=0)でない返り値が返ってくるとそこに打つというようにします。同様に複数置ける場所があったとして、複数箇所探索する前にZERO以外が帰ってくるとif文で関数の都合上return (そのマスの座標)を返します。

該当のソースコード

c

1int othelloAI(void) 2{ 3 static int mass[60][SIZE][SIZE]; 4 static int t = 0; 5 6 memcpy(mass[t], c_mas2, sizeof(mass[t])); 7 8 return othello_AI_check(t, mass); 9} 10 11int othello_AI_check(int ar_turn, int mass[60][SIZE][SIZE]) 12{ 13 static int counta[70] = {0}; 14 static int countb[70] = {0}; 15 static int eva_count[70]; 16 static int skip_count = 0; 17 18 if (E_cnt_AI(mass[ar_turn]) == 0) //最後までいった(マスが全て埋まった)とき 19 { 20 skip_count = 0; //連続してパスはなかったので初期化する 21 if (result_AI(mass[ar_turn]) == 1) 22 return 10 * countb[ar_turn] + counta[ar_turn]; 23 } 24 25 eva_count[ar_turn] = 0; //初期化する。他のcount変数はfor文で初期化されている 26 27 turn_change(ar_turn); 28 29 if (ar_turn % 2 == 0)//自分の手番 30 { 31 for (counta[ar_turn] = 1; counta[ar_turn] <= 8; counta[ar_turn]++) 32 { 33 for (countb[ar_turn] = 1; countb[ar_turn] <= 8; countb[ar_turn]++) 34 { 35 if (check_AI(ar_turn, mass[ar_turn], counta[ar_turn], countb[ar_turn]) == 1)//置ける箇所か判定し、置ける時は1を返します 36 { 37 mass[ar_turn][counta[ar_turn]][countb[ar_turn]] = my_color; 38 gl_y = counta[ar_turn];//calcularionaiで使う 39 gl_x = counta[ar_turn]; 40 calculationai(mass[ar_turn]);//駒をひっくり返す 41 memcpy(mass[ar_turn + 1], mass[ar_turn], sizeof(mass[ar_turn]));//ar_turn+1のますに現在のマスをコピー 42 43 if (othello_AI_check(ar_turn + 1, mass) != 0) //自分の手番で、返り値が1の時、それ以降は調べる必要がなくなる。また相手の時も同様に返り値が0の時それ以降は調べる必要がなくなる。 44 return 10 * countb[ar_turn] + counta[ar_turn]; 45 eva_count[ar_turn]++; 46 } 47 } 48 } 49 50 if (eva_count[ar_turn] == 0) //置く所がなかった(パスの時) 51 { 52 if (skip_count == 1)//両方打てなくなった時(スキップが二回続いた時) 53 { 54 if (result_AI(mass[ar_turn]) == 1) 55 return 10 * countb[ar_turn] + counta[ar_turn]; 56 else 57 ZERO; 58 } 59 skip_count = 0; //連続してパスはなかったのでリセットする 60 skip_count++; 61 memcpy(mass[ar_turn + 1], mass[ar_turn], sizeof(mass[ar_turn])); 62 return othello_AI_check(ar_turn + 1, mass); 63 } 64 else //置くところはあるが返り値が全てZERO(=0)であった場合 65 skip_count = 0; //連続してパスはなかったのでリセットする 66 return ZERO; 67 } 68//_______________________________________________________________相手の手番 以下似た処理 69 70 else//相手の手番 71 { 72 for (counta[ar_turn] = 1; counta[ar_turn] <= 8; counta[ar_turn]++) 73 { 74 for (countb[ar_turn] = 1; countb[ar_turn] <= 8; countb[ar_turn]++) 75 { 76 if (check_AI(ar_turn, mass[ar_turn], counta[ar_turn], countb[ar_turn]) == 1) 77 { 78 mass[ar_turn][counta[ar_turn]][countb[ar_turn]] = my_color; 79 gl_y = counta[ar_turn]; 80 gl_x = counta[ar_turn]; 81 calculationai(mass[ar_turn]); 82 memcpy(mass[ar_turn + 1], mass[ar_turn], sizeof(mass[ar_turn])); 83 if (othello_AI_check(ar_turn + 1, mass) == ZERO) 84 return ZERO; 85 eva_count[ar_turn]++; 86 } 87 } 88 } 89 90 if (eva_count[ar_turn] == 0) //置く所がなかった(パスの時) 91 { 92 if (skip_count == 1)//両方打てなくなった時(スキップが二回続いた時) 93 { 94 if (result_AI(mass[ar_turn]) == 1) 95 return 10 * countb[ar_turn] + counta[ar_turn]; 96 else 97 ZERO; 98 } 99 skip_count = 0; //連続してパスはなかったのでリセットする 100 skip_count++; 101 memcpy(mass[ar_turn + 1], mass[ar_turn], sizeof(mass[ar_turn])); 102 return othello_AI_check(ar_turn + 1, mass); 103 } 104 else //置くところはあったが返り値が全て1であった場合 105 skip_count = 0; //連続してパスはなかったのでリセットする 106 return 10 * countb[ar_turn] + counta[ar_turn]; 107 } 108}

試したこと

再帰関数で一度は再帰関数で呼び出せることは確認.
配列のインデックスが超えることもないと思います。(確認する限り)

補足情報(FW/ツールのバージョンなど)

c言語

mac pro

vscode

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

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

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

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

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

guest

回答3

0

マスの数が8x8だと手番の総数は単純に88パスの回数分必要だったりしませんか?
ちゃんと読むともっと少ないかもしれませんが・・・。

c

1static int mass[60][SIZE][SIZE];

だと手番60回目で範囲外アクセスになるような気がします。

投稿2018/11/18 14:24

TaroToyotomi

総合スコア1430

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

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

0

「Bus error 10」

検索してみると、範囲外アクセス(例えば、int a[10] なのに、a[11] を実行とか) みたいですね。条件は色々とあるようですが。
とすると、

探索時間が長いから

のが直接の原因というよりは、検索時間が長いと、ネストが深くなったりする事で範囲外アクセスになるのではないでしょうか?
検索時間が長い場合のみ、発生し、通常は起きない事を視点として、デバッグを行うしかないと思います。

投稿2018/11/17 07:35

pepperleaf

総合スコア6383

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

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

0

ベストアンサー

エラーが出るのに探索時間は関係ありません。
コードにミスがあるから、あるいは処理に異常があるからエラーが出ます

投稿2018/11/17 07:13

y_waiwai

総合スコア87747

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

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

houki

2018/11/17 07:57

原因が気づいたかもしれません!ar_turnは常に+1されて引数として渡され、常に増加してエラーを起こしたのだと思います。関数から戻ってくる際に-1するのを記述する対策をとります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問