今、オセロ形式のゲームを作っています。
一応石をオセロのルールで置く&ひっくり返すところまで作ったのですが、
石を黒白合わせて半分くらい置いたところですべての処理が停止するバグが起きてしまいます。
(Osero.exeは応答していませんしません、というエラー文が出てきます)
どうやらスペースキー(石を置くキー)を押した瞬間にフリーズするようなのですが、
カンストするようなものはおいてありません。
何かカンスト以外にフリーズする原因とかはありますでしょうか?
コードを貼るとすごく長くなってしまうのですが、
コードを見ないと分からない等であれば要点だけまとめて貼ります。
多少説明不足のところもあるかと思いますが、
ご回答よろしくお願いいたします。
ゲーム中のフリーズについて
Re: ゲーム中のフリーズについて
コードが無いとまず答えようがありません。
オーバーフローのことですか?
フリーズする原因としてはメモリのアクセス違反や、無限ループなどがあります。
「カンスト」とはどのような意味で使っているのでしょうか?えん さんが書きました:何かカンスト以外にフリーズする原因とかはありますでしょうか?
オーバーフローのことですか?
フリーズする原因としてはメモリのアクセス違反や、無限ループなどがあります。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: ゲーム中のフリーズについて
VC++などをお使いでしたら、デバッガの機能で中断すると何処でループしているか調べられます。
石が置けるか調べているところで無限ループしている可能性が高いと思いますが、コードが見れていないので断言できません。
石が置けるか調べているところで無限ループしている可能性が高いと思いますが、コードが見れていないので断言できません。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: ゲーム中のフリーズについて
カンストではなくオーバーフローでした。あいまいで申し訳ありません・・・
以下スペースを押した際の処理
以下check_storn_black()(check_storn_white()も似たような感じです)
長くて申し訳ないです!
board.board[8][8]にそれぞれのマス目の情報(黒か白か何もないか)を入れ、
board.cursor_pointには今カーソルがどこのマスにいるかを入れています。
何度かテストプレイをしたのですが、ボードの端に近いところに石を置くとフリーズしやすかったので、
もしかしたらアクセス違反が原因かもしれないです。
が、どこが原因だかはっきりとはわかりませんでした。
以下スペースを押した際の処理
void board_storn(){
if(Key[KEY_INPUT_SPACE]==1){
switch(board.turn){
case BLACK://黒の番の時
if(board.board[board.cursor_point_x][board.cursor_point_y]==0)
check_storn_black();
if(board.check_flag_black==1)
board.turn=WHITE;
break;
case WHITE://白の番の時
if(board.board[board.cursor_point_x][board.cursor_point_y]==0)
check_storn_white();
if(board.check_flag_white==1)
board.turn=BLACK;
break;
default:
printfDx("エラー\n");
break;
}
}
以下check_storn_black()(check_storn_white()も似たような感じです)
void check_storn_black(){
int i=0, j;
if(board.cursor_point_x<7){//右にマスがあるとき
while(board.board[board.cursor_point_x+1+i][board.cursor_point_y]==WHITE){//右側が白の時
if(board.cursor_point_x+1+i!=7)//右側が8列目の時を除く
i++;
}
if(i!=0 && board.board[board.cursor_point_x+1+i][board.cursor_point_y]==BLACK){
board.check_flag_black=1;
for(j=0;j<i+1;j++)
board.board[board.cursor_point_x+j][board.cursor_point_y]=BLACK;
}
}
i=0;
if(board.cursor_point_x>0){//左にマスがあるとき
while(board.board[board.cursor_point_x-1-i][board.cursor_point_y]==WHITE){//左側が白の時
if(board.cursor_point_x-1-i!=0)//左側が1列目の時を除く
i++;
}
if(i!=0 && board.board[board.cursor_point_x-1-i][board.cursor_point_y]==BLACK){
board.check_flag_black=1;
for(j=0;j<i+1;j++)
board.board[board.cursor_point_x-j][board.cursor_point_y]=BLACK;
}
}
i=0;
if(board.cursor_point_y>0){//上にマスがあるとき
while(board.board[board.cursor_point_x][board.cursor_point_y-1-i]==WHITE){//上側が白の時
if(board.cursor_point_y-1-i!=0)//上側が1列目の時を除く
i++;
}
if(i!=0 && board.board[board.cursor_point_x][board.cursor_point_y-1-i]==BLACK){
board.check_flag_black=1;
for(j=0;j<i+1;j++)
board.board[board.cursor_point_x][board.cursor_point_y-j]=BLACK;
}
}
i=0;
if(board.cursor_point_y<7){//下にマスがあるとき
while(board.board[board.cursor_point_x][board.cursor_point_y+1+i]==WHITE){//下側が白の時
if(board.cursor_point_y+1+i!=7)//下側が8列目の時を除く
i++;
}
if(i!=0 && board.board[board.cursor_point_x][board.cursor_point_y+1+i]==BLACK){
board.check_flag_black=1;
for(j=0;j<i+1;j++)
board.board[board.cursor_point_x][board.cursor_point_y+j]=BLACK;
}
}
i=0;
if(board.cursor_point_x<7 && board.cursor_point_y<7){//右下にマスがあるとき
while(board.board[board.cursor_point_x+1+i][board.cursor_point_y+1+i]==WHITE){//右下側が白の時
if(board.cursor_point_x+1+i!=7 || board.cursor_point_y+1+i!=7)//右側が8列目、下側が8列目の時を除く
i++;
}
if(i!=0 && board.board[board.cursor_point_x+1+i][board.cursor_point_y+1+i]==BLACK){
board.check_flag_black=1;
for(j=0;j<i+1;j++)
board.board[board.cursor_point_x+j][board.cursor_point_y+j]=BLACK;
}
}
i=0;
if(board.cursor_point_x>0 && board.cursor_point_y<7){//左下にマスがあるとき
while(board.board[board.cursor_point_x-1-i][board.cursor_point_y+1+i]==WHITE){//左下側が白の時
if(board.cursor_point_x-1-i!=0 || board.cursor_point_y+1+i!=7)//左側が1列目、下側が8列目の時を除く
i++;
}
if(i!=0 && board.board[board.cursor_point_x-1-i][board.cursor_point_y+1+i]==BLACK){
board.check_flag_black=1;
for(j=0;j<i+1;j++)
board.board[board.cursor_point_x-j][board.cursor_point_y+j]=BLACK;
}
}
i=0;
if(board.cursor_point_x<7 && board.cursor_point_y>0){//右上にマスがあるとき
while(board.board[board.cursor_point_x+1+i][board.cursor_point_y-1-i]==WHITE){//右上側が白の時
if(board.cursor_point_x+1+i!=7 || board.cursor_point_y-1-i!=0)//右側が8列目、上側が1列目の時を除く
i++;
}
if(i!=0 && board.board[board.cursor_point_x+1+i][board.cursor_point_y-1-i]==BLACK){
board.check_flag_black=1;
for(j=0;j<i+1;j++)
board.board[board.cursor_point_x+j][board.cursor_point_y-j]=BLACK;
}
}
i=0;
if(board.cursor_point_x>0 && board.cursor_point_y>0){//左上にマスがあるとき
while(board.board[board.cursor_point_x-1-i][board.cursor_point_y-1-i]==WHITE){//左上側が白の時
if(board.cursor_point_x-1-i!=0 || board.cursor_point_y-1-i!=0)//左側が1列目、上側が1列目の時を除く
i++;
}
if(i!=0 && board.board[board.cursor_point_x-1-i][board.cursor_point_y-1-i]==BLACK){
board.check_flag_black=1;
for(j=0;j<i+1;j++)
board.board[board.cursor_point_x-j][board.cursor_point_y-j]=BLACK;
}
}
}
長くて申し訳ないです!
board.board[8][8]にそれぞれのマス目の情報(黒か白か何もないか)を入れ、
board.cursor_pointには今カーソルがどこのマスにいるかを入れています。
何度かテストプレイをしたのですが、ボードの端に近いところに石を置くとフリーズしやすかったので、
もしかしたらアクセス違反が原因かもしれないです。
が、どこが原因だかはっきりとはわかりませんでした。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: ゲーム中のフリーズについて
>もしかしたらアクセス違反が原因かもしれないです。
アクセス違反ならプログラムが停止しますので、それも間違いですね。
私が提案したデバッガで調べてもらえたのでしょうか?
それともデバッガが何か分からないんでしょうか?
何も答えてもらっていないのでスルーした理由をお聞かせください。
それとソースコードで気になったのが、
このコードだとboard.cursor_point_x=6のときboard.board[board.cursor_point_x+1+i][board.cursor_point_y]==WHITEだと無限ループになりませんか?
これが原因な気がしますが、なんのためにある if(board.cursor_point_x+1+i!=7)なんでしょうか?
アクセス違反ならプログラムが停止しますので、それも間違いですね。
私が提案したデバッガで調べてもらえたのでしょうか?
それともデバッガが何か分からないんでしょうか?
何も答えてもらっていないのでスルーした理由をお聞かせください。
それとソースコードで気になったのが、
while(board.board[board.cursor_point_x+1+i][board.cursor_point_y]==WHITE){//右側が白の時
if(board.cursor_point_x+1+i!=7)//右側が8列目の時を除く
i++;
}
これが原因な気がしますが、なんのためにある if(board.cursor_point_x+1+i!=7)なんでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: ゲーム中のフリーズについて
若干言い訳臭くなってしまうのですが、softya(ソフト屋) さんが書きました: 私が提案したデバッガで調べてもらえたのでしょうか?
それともデバッガが何か分からないんでしょうか?
何も答えてもらっていないのでスルーした理由をお聞かせください。
デバッガの方法を知らなかったので、他サイトで調べていた傍ら
答えてくださったお二方が「ソースがないと何とも言えない」とのことでしたのであわててソースを書き込んだので、
デバッガを試さずに返信してしまいました。
申し訳ありませんでした。
if(board.cursor_point_x+1+i!=7)は、端まで全部WHITEだった場合はsoftya(ソフト屋) さんが書きました: それとソースコードで気になったのが、このコードだとboard.cursor_point_x=6のときboard.board[board.cursor_point_x+1+i][board.cursor_point_y]==WHITEだと無限ループになりませんか?while(board.board[board.cursor_point_x+1+i][board.cursor_point_y]==WHITE){//右側が白の時 if(board.cursor_point_x+1+i!=7)//右側が8列目の時を除く i++; }
これが原因な気がしますが、なんのためにある if(board.cursor_point_x+1+i!=7)なんでしょうか?
次のboard.board[board.cursor_point_x+1+i][board.cursor_point_y]で存在しない領域にアクセスしないようにつけたものです。
softyaさんのおっしゃるとおり、そこで無限ループが起こっていたようです。
while(board.board[board.cursor_point_x+1+i][board.cursor_point_y]==WHITE){//右側が白の時
if(board.cursor_point_x+1+i!=7)//右側が8列目の時を除く
i++;
else
break;
}
答えてくださったお二方、本当にありがとうございました!
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: ゲーム中のフリーズについて
最後にアドバイスをひとつ。
check_storn_blackとcheck_storn_whiteに分かれているみたいですが、check_storn(int checkStone,int revarseStone)とか引数にすれば関数をまとめられますね。
上下左右チェックも再帰呼び出しや上下左右の情報が入った配列でループなどを工夫すれば、もっとシンプルになりますよ。
気になったら質問してくださいね。
check_storn_blackとcheck_storn_whiteに分かれているみたいですが、check_storn(int checkStone,int revarseStone)とか引数にすれば関数をまとめられますね。
上下左右チェックも再帰呼び出しや上下左右の情報が入った配列でループなどを工夫すれば、もっとシンプルになりますよ。
気になったら質問してくださいね。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: ゲーム中のフリーズについて
なるほど!ありがとうございますm(__)msoftya(ソフト屋) さんが書きました:最後にアドバイスをひとつ。
check_storn_blackとcheck_storn_whiteに分かれているみたいですが、check_storn(int checkStone,int revarseStone)とか引数にすれば関数をまとめられますね。
上下左右チェックも再帰呼び出しや上下左右の情報が入った配列でループなどを工夫すれば、もっとシンプルになりますよ。
気になったら質問してくださいね。
一度全体の形を完成させてから、もしかしたら質問させていただくかもしれないです。
そのときはまたお手間をかけさせますが、よろしくお願いします。
Re: ゲーム中のフリーズについて
解決してるようだけど、53行目は&&の間違いじゃないかな。その他3箇所も。
私の勘違いならば申し訳ないです。
ついでに、あやしい英単語はマメに辞書で確認する習慣を付けた方が良いと思う。
stornとかrevarseとか。PCならば殆ど手間はかからないし。
私の勘違いならば申し訳ないです。
ついでに、あやしい英単語はマメに辞書で確認する習慣を付けた方が良いと思う。
stornとかrevarseとか。PCならば殆ど手間はかからないし。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: ゲーム中のフリーズについて
revarseを間違ったのは私ですね。
失礼しました。正解はreverse(逆の)です。
失礼しました。正解はreverse(逆の)です。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。