バグの原因は・・・
バグの原因は・・・
短いスパンでの投稿となり、自分の未熟さが悔しさを募らせます。
いまだにパズルゲームの製作に手間取っています。
以前、再帰関数について質問させていただき、皆さんの助言のおかげで今、4つブロックをそろえて消し、消えたところは上の段のブロックが下にずれて埋め、上の空いたところに、新たにランダムにブロックを配置するというプログラムを組むところまで来ました。しかし、たまにバグります。4つ揃えても消えなかったり、揃えていないところが、なぜか消えたり、白いブロック(意図していない)が生み出されたり(たぶん、二つ以上の数字が同時にブロックを参照したため?)etc...
今私の考えでは、おそらくScenePly.cppの188行目と222行目のg_DeletePanelW[h2][w2]とg_DeletePanelH[h2][w2]の初期化が行われていないからだと推測して、色々策を講じているのですが、うまくいきません。ブロックが瞬時に切り替わってしまうので視認しずらいのも一役買っています。(この演出方法も何かうまい方法があれば教えていただきたいと思っているのは別のお話)
ソースファイルは、スパゲッティになる前のg_DeletePanelW[h2][w2]とg_DeletePanelH[h2][w2]の初期化をしていない過去のものを載せておきます。
皆さんもお忙しい中、デバッグになんか付き合ってられねーよと思われるかもしれませんが、ご助言だけでもいただけると幸いです。
どうかよろしくお願いいただけないでしょうか。
いまだにパズルゲームの製作に手間取っています。
以前、再帰関数について質問させていただき、皆さんの助言のおかげで今、4つブロックをそろえて消し、消えたところは上の段のブロックが下にずれて埋め、上の空いたところに、新たにランダムにブロックを配置するというプログラムを組むところまで来ました。しかし、たまにバグります。4つ揃えても消えなかったり、揃えていないところが、なぜか消えたり、白いブロック(意図していない)が生み出されたり(たぶん、二つ以上の数字が同時にブロックを参照したため?)etc...
今私の考えでは、おそらくScenePly.cppの188行目と222行目のg_DeletePanelW[h2][w2]とg_DeletePanelH[h2][w2]の初期化が行われていないからだと推測して、色々策を講じているのですが、うまくいきません。ブロックが瞬時に切り替わってしまうので視認しずらいのも一役買っています。(この演出方法も何かうまい方法があれば教えていただきたいと思っているのは別のお話)
ソースファイルは、スパゲッティになる前のg_DeletePanelW[h2][w2]とg_DeletePanelH[h2][w2]の初期化をしていない過去のものを載せておきます。
皆さんもお忙しい中、デバッグになんか付き合ってられねーよと思われるかもしれませんが、ご助言だけでもいただけると幸いです。
どうかよろしくお願いいただけないでしょうか。
- 添付ファイル
-
- CG・BGM.zip
- (5.08 MiB) ダウンロード数: 92 回
-
- ソースファイル.zip
- (5.96 KiB) ダウンロード数: 100 回
Re: バグの原因は・・・
そういえば、
操作方法とか書いていませんでした。
方向キーとスペースキーのみ
スタートにカーソルを合わせてスペースでゲーム開始、Xキーでタイトルに戻る
ゲーム終了に合わせてスペースでゲーム終了。
ほかの、おまけとかには触らないでください(何もないので戻れなくなります)
プレイ画面
方向キーで薄緑色のカーソル移動。任意の場所でスペースを押すと、その真下の画像が左右入れ替わる。
4つ以上縦または横にそろうと消え、・・・・
操作方法とか書いていませんでした。
方向キーとスペースキーのみ
スタートにカーソルを合わせてスペースでゲーム開始、Xキーでタイトルに戻る
ゲーム終了に合わせてスペースでゲーム終了。
ほかの、おまけとかには触らないでください(何もないので戻れなくなります)
プレイ画面
方向キーで薄緑色のカーソル移動。任意の場所でスペースを押すと、その真下の画像が左右入れ替わる。
4つ以上縦または横にそろうと消え、・・・・
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: バグの原因は・・・
チェックと消えた状態管理の配列が多いのがバグりやすい原因かと思いますので、出来るだけ単純なアルゴリズムにするとバグが減るかと思います。
消去ルールって縦横が4つ以上揃ったらで消えた後は鉄のブロックになって鉄のブロックも移動可能で良いんですよね?
だとしたらg_Panel以外の
int g_DeletePanelW[PANEL_SIZE][PANEL_SIZE],g_DeletePanelH[PANEL_SIZE][PANEL_SIZE]; // 1なら消える
int g_CheckPanelW[PANEL_SIZE][PANEL_SIZE],g_CheckPanelH[PANEL_SIZE][PANEL_SIZE]; // 1ならチェック済み
は4つも不要で1つだけの配列で処理できるのと思うのですが。
その1つの配列もチェックをはじめる時に初期化すれば良いと思います。
消去ルールって縦横が4つ以上揃ったらで消えた後は鉄のブロックになって鉄のブロックも移動可能で良いんですよね?
だとしたらg_Panel以外の
int g_DeletePanelW[PANEL_SIZE][PANEL_SIZE],g_DeletePanelH[PANEL_SIZE][PANEL_SIZE]; // 1なら消える
int g_CheckPanelW[PANEL_SIZE][PANEL_SIZE],g_CheckPanelH[PANEL_SIZE][PANEL_SIZE]; // 1ならチェック済み
は4つも不要で1つだけの配列で処理できるのと思うのですが。
その1つの配列もチェックをはじめる時に初期化すれば良いと思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: バグの原因は・・・
[quote="softya(ソフト屋)"]
消去ルールって縦横が4つ以上揃ったらで消えた後は鉄のブロックになって鉄のブロックも移動可能で良いんですよね?
quote]
sofutoyaさん返信ありがとうございます。
すみません、自分がどうしたいかを書いていませんでした。フォーラムルールに抵触していますね。
鉄ブロックに変えたのはあくまで便宜的なので、最終的には完全に消去して、上段のブロックを下にスライドさせ、上の空きを新規ブロックで埋める。←これを目的にしています。(ちなみに縦と横は別々に判定します。)
仮にそうだとしても、変数の数は減らしてもいいみたいですね、少し、試してみます。
消去ルールって縦横が4つ以上揃ったらで消えた後は鉄のブロックになって鉄のブロックも移動可能で良いんですよね?
quote]
sofutoyaさん返信ありがとうございます。
すみません、自分がどうしたいかを書いていませんでした。フォーラムルールに抵触していますね。
鉄ブロックに変えたのはあくまで便宜的なので、最終的には完全に消去して、上段のブロックを下にスライドさせ、上の空きを新規ブロックで埋める。←これを目的にしています。(ちなみに縦と横は別々に判定します。)
仮にそうだとしても、変数の数は減らしてもいいみたいですね、少し、試してみます。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: バグの原因は・・・
ルール的に抜けを感じるのですが揃ったら横のブロックがずれる事はないのでしょうか?
あと縦横同時にそろったら、どちらが優先されるのでしょうか?それとも同時に消去されるのでしょうか?
あと縦横同時にそろったら、どちらが優先されるのでしょうか?それとも同時に消去されるのでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: バグの原因は・・・
消した後はy方向しか見ていないので、横にずれることは(たぶん)ないと思います。
縦と横を同時に消すと、ウォータフォールにのっとり横が優先されるようです。
縦と横を同時に消すと、ウォータフォールにのっとり横が優先されるようです。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: バグの原因は・・・
ルール的には下にしかズレ無いということですね。
それと横が優先と言うことですね。
「優先されるようです。」ってのが曖昧で気になりますが。
次の場合の動作イメージは、これで合ってますか?
(1)4つ縦横で揃う 数値は何らかの図柄
■333
■222
■111
■■■■
(2)横が消滅
■333
■222
■111
□□□□
(3)上からズレる。
4444
■333
■222
■111
そういえば落下するなら連鎖もするんですよね?
後々返ってややこしくなるので、鉄のブロックに置き換えるのではなく最初から消滅するロジックで書くことをおすすめします。
それと横が優先と言うことですね。
「優先されるようです。」ってのが曖昧で気になりますが。
次の場合の動作イメージは、これで合ってますか?
(1)4つ縦横で揃う 数値は何らかの図柄
■333
■222
■111
■■■■
(2)横が消滅
■333
■222
■111
□□□□
(3)上からズレる。
4444
■333
■222
■111
そういえば落下するなら連鎖もするんですよね?
後々返ってややこしくなるので、鉄のブロックに置き換えるのではなく最初から消滅するロジックで書くことをおすすめします。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: バグの原因は・・・
sofutyaさん返信ありがとうございます。
動作のイメージはまさにその通りです。連鎖もします。(といっても一瞬で処理が進むので視認しづらいですが)
ブロックの画像はお持ちかと思いますが、#difine BLOCK_NO 15 として、消えたなら15番目の真っ白なブロックに代わるようにしています。
みたいにしていました。
今気づきましたがこの加算ブレンドの処理はDrowGraph()を挟む以外は無意味なようですね。
動作のイメージはまさにその通りです。連鎖もします。(といっても一瞬で処理が進むので視認しづらいですが)
ブロックの画像はお持ちかと思いますが、#difine BLOCK_NO 15 として、消えたなら15番目の真っ白なブロックに代わるようにしています。
if(g_DeletePanelH[h2][w2] == 1){
SetDrawBlendMode( DX_BLENDMODE_ALPHA, 0 );
g_Panel[h2][w2] = BLOCK_NO;
SetDrawBlendMode( DX_BLENDMODE_NOBLEND,0 );
}
今気づきましたがこの加算ブレンドの処理はDrowGraph()を挟む以外は無意味なようですね。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: バグの原因は・・・
はい。無意味です。icon01 さんが書きました: 今気づきましたがこの加算ブレンドの処理はDrowGraph()を挟む以外は無意味なようですね。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: バグの原因は・・・
あれからしばらく原因を探ってみましたがまだ完全にバグは治りません。
色々調べて分かったことは、
・#difine BLOCK_NO 15 の数字を変えただけでバグが増える(spaceを押していないのにあるところにカーソルを合わせるとブロックが変化する・カーソルが端まで動かせない「spaceを押すと見当違いの場所のブロックが入れ替わる」)等々
・一番上のブロックを横に並べると白いブロック(意図していないもの)で埋まる
(これは修正できたと思います)
・たぶん4つ揃えても消えないバグはなくなった?と思う。
・ネットで調べた情報ですがZeroMemoryで初期化するのはよろしくない(らしい)とのことなので、for文で回してみました
以上を踏まえたうえで、皆さんのお力をもう一度お貸し願えないでしょうか?
頼ってばかりで申し訳ないですが、どうかよろしくお願いいたします。最新のファイルScenePlyファイルのみ添付しておきます。
色々調べて分かったことは、
・#difine BLOCK_NO 15 の数字を変えただけでバグが増える(spaceを押していないのにあるところにカーソルを合わせるとブロックが変化する・カーソルが端まで動かせない「spaceを押すと見当違いの場所のブロックが入れ替わる」)等々
・一番上のブロックを横に並べると白いブロック(意図していないもの)で埋まる
(これは修正できたと思います)
・たぶん4つ揃えても消えないバグはなくなった?と思う。
・ネットで調べた情報ですがZeroMemoryで初期化するのはよろしくない(らしい)とのことなので、for文で回してみました
以上を踏まえたうえで、皆さんのお力をもう一度お貸し願えないでしょうか?
頼ってばかりで申し訳ないですが、どうかよろしくお願いいたします。最新のファイルScenePlyファイルのみ添付しておきます。
- 添付ファイル
-
- ScenePlay.cpp
- (9.33 KiB) ダウンロード数: 87 回
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: バグの原因は・・・
一時的に画面の横幅を広げてg_DeletePanelWやg_DeletePanelHの情報を表示するようにしてみてください。
問題があれば目に見えて分かると思います。追いかけ辛いプログラムなのでお願いします。
私としては、g_DeletePanelWとg_DeletePanelHの2つの分かれている理由がわかりません。
それとg_DeletePanelWとg_DeletePanelHの値をずっと保持している理由もです。
チェックするときだけ必要な配列なんじゃないでしょうか?
問題があれば目に見えて分かると思います。追いかけ辛いプログラムなのでお願いします。
私としては、g_DeletePanelWとg_DeletePanelHの2つの分かれている理由がわかりません。
それとg_DeletePanelWとg_DeletePanelHの値をずっと保持している理由もです。
チェックするときだけ必要な配列なんじゃないでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: バグの原因は・・・
softoyaさん返信ありがとうございます。softya(ソフト屋) さんが書きました:一時的に画面の横幅を広げてg_DeletePanelWやg_DeletePanelHの情報を表示するようにしてみてください。
問題があれば目に見えて分かると思います。追いかけ辛いプログラムなのでお願いします。
私としては、g_DeletePanelWとg_DeletePanelHの2つの分かれている理由がわかりません。
それとg_DeletePanelWとg_DeletePanelHの値をずっと保持している理由もです。
チェックするときだけ必要な配列なんじゃないでしょうか?
g_DeletePanelWとg_DeletePanelHは縦と横を別々に判定して4つ塊があれば勝手に消えるのを防ぐためにしているつもりだったのですが・・・1つで事足りるのでしょうか?
あとグローバル変数ではなくSearchDelBlock()の関数の中でローカルとして使うべきということでしょうか?
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: バグの原因は・・・
同時に使用しないなら1つで足りるでしょう。icon01 さんが書きました: g_DeletePanelWとg_DeletePanelHは縦と横を別々に判定して4つ塊があれば勝手に消えるのを防ぐためにしているつもりだったのですが・・・1つで事足りるのでしょうか?
そういう意味ではなく、常に値を保持する必要はないでしょうと言う意味です。icon01 さんが書きました: あとグローバル変数ではなくSearchDelBlock()の関数の中でローカルとして使うべきということでしょうか?
チェックをはじめる時に現状のg_Panelに合わせて初期化して結果は再び使う必要がないのでは?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: バグの原因は・・・
icon01 さんが書きました: g_DeletePanelWとg_DeletePanelHは縦と横を別々に判定して4つ塊があれば勝手に消えるのを防ぐためにしているつもりだったのですが・・・1つで事足りるのでしょうか?
これは以前のスレで私が確認したことですね。
何か必要があって、縦方向と横方向の両方のフラグを持っているのかということですね。
消える場所かそうでないかの管理だけであれば1つでいいのでは?という意味です。
バグ さんが書きました: 横方向に並んで消える、縦方向に並んで消えるという情報は必要なのでしょうか?
それとも消えるか消えないかの情報だけでも構わないのでしょうか?
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: バグの原因は・・・
バグさんへ。
添付のコードですが起動はするのですがパズル画面に移行できません。
起動状態でウィンドウを動かそうとすると応答なしになり、起動直後にそのままスペースキーを押しても反応がありません(音楽は流れた状態)。
Log.txtには特にエラーは出ていません。icon01さんのは動いていたんですが。
添付のコードですが起動はするのですがパズル画面に移行できません。
起動状態でウィンドウを動かそうとすると応答なしになり、起動直後にそのままスペースキーを押しても反応がありません(音楽は流れた状態)。
Log.txtには特にエラーは出ていません。icon01さんのは動いていたんですが。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: バグの原因は・・・
ソースコードにProcessMessage()が無いんですが動いていますか?
while (!::ClearDrawScreen() && CKeyboard::GetInstance()->Refresh() && scene.Update() && !::ScreenFlip());
↓ こうすればうごく。
while (!::ClearDrawScreen() && !::ProcessMessage() && CKeyboard::GetInstance()->Refresh() && scene.Update() && !::ScreenFlip());
そのほうが不思議なんですが。
while (!::ClearDrawScreen() && CKeyboard::GetInstance()->Refresh() && scene.Update() && !::ScreenFlip());
↓ こうすればうごく。
while (!::ClearDrawScreen() && !::ProcessMessage() && CKeyboard::GetInstance()->Refresh() && scene.Update() && !::ScreenFlip());
そのほうが不思議なんですが。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: バグの原因は・・・
バグさん、softoyaさん返信ありがとうございます。
諸事情によりパソコンからしばらく離れていたので返信が遅れてしまい申し訳ありませんでした。
さて、バグさんのソースコードを読ませていただきました。が、まさかほぼ百パーセントの回答をいただけるとはつゆほども思っていなかったので、しばらくあいた口がふさがりませんでした(笑)。このまま丸コピするつもりはありませんので、C言語に自分の書き方で直した後、そのソースを張って、この質問を「解決」としたいと思います。
ではまた後程。
諸事情によりパソコンからしばらく離れていたので返信が遅れてしまい申し訳ありませんでした。
さて、バグさんのソースコードを読ませていただきました。が、まさかほぼ百パーセントの回答をいただけるとはつゆほども思っていなかったので、しばらくあいた口がふさがりませんでした(笑)。このまま丸コピするつもりはありませんので、C言語に自分の書き方で直した後、そのソースを張って、この質問を「解決」としたいと思います。
ではまた後程。
Re: バグの原因は・・・
大変申し上げにくいのですが・・・。
バグさんのプログラムバグってます。たまに4つ揃えてもいないのに消えたり、別のブロックが巻き添えになったりします。
熟練のプログラマーさんでもこのようなミスか引き起こされるとは・・・自分には敷居が高すぎたかな・・・orz。
バグさんのプログラムバグってます。たまに4つ揃えてもいないのに消えたり、別のブロックが巻き添えになったりします。
熟練のプログラマーさんでもこのようなミスか引き起こされるとは・・・自分には敷居が高すぎたかな・・・orz。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: バグの原因は・・・
プロでもだれでもバグる可能性はあります。icon01 さんが書きました: 大変申し上げにくいのですが・・・。
バグさんのプログラムバグってます。たまに4つ揃えてもいないのに消えたり、別のブロックが巻き添えになったりします。
熟練のプログラマーさんでもこのようなミスか引き起こされるとは・・・自分には敷居が高すぎたかな・・・orz。
全部自分で作ったコードじゃない場合や作りなれたものじゃない場合は特にですね。
パズルコードは、綺麗に組みさえすればバグが出る可能性が減らせられますのでシンプルにすることを目指してください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: バグの原因は・・・
>>icon01さん
あぁ・・・すみません。まだやらかしてましたか(^_^;)
とりあえず動きを見る為のサンプルなので、あんまりデバッグ作業を詰めてないです。(ProcessMessageを書き忘れているほどなのでw)
落ち物パズルゲームは割りと敷居は低い方だと思います。
ちなみに、私がプログラムを勉強しはじめて最初に作ったのはコラムスと呼ばれる落ち物パズルゲームでした。
http://dixq.net/sm/
ここに載せてもらっている「ぷよぷよもどき」や「ColorDrop」なんかは(今見ると赤面もののソースコードなのであまり紹介はしたくないのですがw)勉強を始めた初期のころの作品です。よければ遊んでみてください。
あぁ・・・すみません。まだやらかしてましたか(^_^;)
とりあえず動きを見る為のサンプルなので、あんまりデバッグ作業を詰めてないです。(ProcessMessageを書き忘れているほどなのでw)
落ち物パズルゲームは割りと敷居は低い方だと思います。
ちなみに、私がプログラムを勉強しはじめて最初に作ったのはコラムスと呼ばれる落ち物パズルゲームでした。
http://dixq.net/sm/
ここに載せてもらっている「ぷよぷよもどき」や「ColorDrop」なんかは(今見ると赤面もののソースコードなのであまり紹介はしたくないのですがw)勉強を始めた初期のころの作品です。よければ遊んでみてください。
Re: バグの原因は・・・
統計的には、ミスは誰にでも一定の確率で発生すると言われています。icon01 さんが書きました:熟練のプログラマーさんでもこのようなミスか引き起こされるとは・・・自分には敷居が高すぎたかな・・・orz。
確率で発生するわけですから、試行錯誤を繰り返すとミスの発生する確率はどんどん増えていきます。
コード量を減らせば、ミスも減ります。
経験者はミスをしないのではありません。
シンプルに実装し、試行錯誤が少なく、他人が気付く前に修正するのが経験者です。
あと、ゲームのルールのようなロジックを考えるときは、母国語で考えたほうが遥かに効率が良いと思います。