新しい方式
悔しがっててもしかたないから、つながったぷよの検索の部分に新しい方式を実装した。
今回のは、操作ぷよが落ちた時、消えたぷよの上段が落ちた時、それぞれでグループ分けをしなおすので、増えようが、分割されようが、座標が変ろうが関係ない。
まず、ぷよ全てにバラバラのグループ番号を付けてグループ用の配列に記録する。
↓
フィールド用の配列を参照して各グループの色情報を得る。
↓
グループ配列を上段から検索する。
検索ブロックの上下、右に同じ色のグループがある時は、若い方のグループ番号で結合する。
生き残ったグループ番号のメンバーを+1。
↓
検索終了後、メンバーが4以上になったぷよを消す。
↓
消えたぷよの上段を落とす。
↓
最初に戻る。(消えるぷよが無くなるまで繰り返す。)
処理の流れはこんな感じ。
失敗に終った方式から、グループで管理する部分を継承しつつ、インデックスの仕方と検索の仕方を変えた。
グループメンバーの座標を管理する必要がなくなったのと、グループナンバーが使用中かどうかのフラグも必要なくなったので、シンプルな形になった。
まだ、たまにおかしな動きがあるけど、格段に良くなった。
テストしながら直してゆこう。
どうか・・・致命的な問題がありませんように・・・。
http://u7.getuploader.com/game/download/54/%E3%81%B7%E3%82%88%E5%86%8D%E7%8F%BE%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8%EF%BC%8312.zip
実行ファイルをアップしときます。
いつもどうりzipです。解凍してからexeファイルを実行してください。
デバッグ用のため落下ごとに一時停止します。
そのつど、なにかキーを押してください。
下は現在のソースファイルです。
前の方式で使ってた変数宣言が残ったままの生々しい感じで・・・。
http://u7.getuploader.com/game/download/55/%E3%81%B7%E3%82%88%E3%81%B7%E3%82%88%E5%86%8D%E7%8F%BE%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8%EF%BC%8312%E3%81%AE%E3%82%BD%E3%83%BC%E3%82%B9.txt
悔しがっててもしかたないから、つながったぷよの検索の部分に新しい方式を実装した。
今回のは、操作ぷよが落ちた時、消えたぷよの上段が落ちた時、それぞれでグループ分けをしなおすので、増えようが、分割されようが、座標が変ろうが関係ない。
まず、ぷよ全てにバラバラのグループ番号を付けてグループ用の配列に記録する。
↓
フィールド用の配列を参照して各グループの色情報を得る。
↓
グループ配列を上段から検索する。
検索ブロックの上下、右に同じ色のグループがある時は、若い方のグループ番号で結合する。
生き残ったグループ番号のメンバーを+1。
↓
検索終了後、メンバーが4以上になったぷよを消す。
↓
消えたぷよの上段を落とす。
↓
最初に戻る。(消えるぷよが無くなるまで繰り返す。)
処理の流れはこんな感じ。
失敗に終った方式から、グループで管理する部分を継承しつつ、インデックスの仕方と検索の仕方を変えた。
グループメンバーの座標を管理する必要がなくなったのと、グループナンバーが使用中かどうかのフラグも必要なくなったので、シンプルな形になった。
まだ、たまにおかしな動きがあるけど、格段に良くなった。
テストしながら直してゆこう。
どうか・・・致命的な問題がありませんように・・・。
http://u7.getuploader.com/game/download/54/%E3%81%B7%E3%82%88%E5%86%8D%E7%8F%BE%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8%EF%BC%8312.zip
実行ファイルをアップしときます。
いつもどうりzipです。解凍してからexeファイルを実行してください。
デバッグ用のため落下ごとに一時停止します。
そのつど、なにかキーを押してください。
下は現在のソースファイルです。
前の方式で使ってた変数宣言が残ったままの生々しい感じで・・・。
http://u7.getuploader.com/game/download/55/%E3%81%B7%E3%82%88%E3%81%B7%E3%82%88%E5%86%8D%E7%8F%BE%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8%EF%BC%8312%E3%81%AE%E3%82%BD%E3%83%BC%E3%82%B9.txt
PR
致命的な問題
つながったぷよの管理に致命的な問題を発見。
動作が変だったのはこのせいだ。
消えたぷよの上のブロックが落ちる時にグループ内のメンバーの座標が変る事を想定できてなかった。
それどころかグループが分断される事もあるじゃないか。
ああ、バカだ。俺。
どうやら管理の方法自体を1から考えなおさなきゃいけない。
くっそー!
悔しいなっ!
つながったぷよの管理に致命的な問題を発見。
動作が変だったのはこのせいだ。
消えたぷよの上のブロックが落ちる時にグループ内のメンバーの座標が変る事を想定できてなかった。
それどころかグループが分断される事もあるじゃないか。
ああ、バカだ。俺。
どうやら管理の方法自体を1から考えなおさなきゃいけない。
くっそー!
悔しいなっ!
ぷよのグループ管理
ぷよが同色で並んだかどうかとか、同色でつながった数はいくつになったかとか、そういうのを把握するためにもう1つ配列変数を用意した。
前の、配列変数には座標上のぷよの色が記録されていたんだけど、今回のはグループナンバーが記録される。
処理の流れはこんな感じ。
例えば最初に赤が二つのペアを右隅に置くと、
~前略~
000000
000000
000002
000001
こんな感じになる。
同色であってもいったん、別のグループとして記録される。
その後、フィールド内を順に検索して、同色が隣り合っている場合は、片方のグループに結合してしまう。
その際に、互いのグループのメンバー数を足し、それぞれの座標も生き残る方のグループ番号が引き継ぐ。
結合されてしまった方のグループ番号は未使用のフラグになるので、いずれ新しく落ちてきたぷよに使われる事になる。
~前略~
000000
000000
000002
000002
検索によって赤が隣り合っている事が判明したので、グループ2番で結合。
次に緑、黄色の組み合わせをとなりにおとすと、
~前略~
000000
000000
000012
000032
こんな感じになる。
グループ番号は若い順に使用中じゃないものを見つけ次第、それを使用する。
これをくりかえして、メンバー数が4以上になったグループは消して、消えたマスの上のぷよをスライドさせる処理をする。
グループ管理に使う変数はまとめて構造体にした。
group.Index [gn] ・・・そのグループ番号が使用中かどうかを表すフラグ
group.Color [gn] ・・・そのグループの色
group.Member [gn] ・・・そのグループのメンバー数
group.MemberX [gn] [no] ・・・グループメンバーのX座標
group.MemberY [gn] [no] ・・・グループメンバーのY座標
gnはグループ番号
noはメンバーの番号
で、ながながと書いてきて、なんだけども、現在バグバグである(笑)
グループの結合処理を行うごとに、とりあえず1~10までのグループデータを表示させて、原因を探索中。
うまくグループ分けできてる時と、そうじゃない時があって、その分岐要因がわからないのよ。
いちお、デバッグ中のバージョン置いときます。
操作は前回と一緒。
落下するごとにデータを表示して一時停止しますんで、そのつどなにかキーを押してください。
毎度ですがzipなんで解凍してから実行してください。
http://u7.getuploader.com/game/download/50/%E3%81%B7%E3%82%88%E5%86%8D%E7%8F%BE%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8%EF%BC%8310.zip
引き続きバグ取りしますW
地味に時間のかかる作業なので、ブログの更新が遅れるかも・・・
ぷよが同色で並んだかどうかとか、同色でつながった数はいくつになったかとか、そういうのを把握するためにもう1つ配列変数を用意した。
前の、配列変数には座標上のぷよの色が記録されていたんだけど、今回のはグループナンバーが記録される。
処理の流れはこんな感じ。
例えば最初に赤が二つのペアを右隅に置くと、
~前略~
000000
000000
000002
000001
こんな感じになる。
同色であってもいったん、別のグループとして記録される。
その後、フィールド内を順に検索して、同色が隣り合っている場合は、片方のグループに結合してしまう。
その際に、互いのグループのメンバー数を足し、それぞれの座標も生き残る方のグループ番号が引き継ぐ。
結合されてしまった方のグループ番号は未使用のフラグになるので、いずれ新しく落ちてきたぷよに使われる事になる。
~前略~
000000
000000
000002
000002
検索によって赤が隣り合っている事が判明したので、グループ2番で結合。
次に緑、黄色の組み合わせをとなりにおとすと、
~前略~
000000
000000
000012
000032
こんな感じになる。
グループ番号は若い順に使用中じゃないものを見つけ次第、それを使用する。
これをくりかえして、メンバー数が4以上になったグループは消して、消えたマスの上のぷよをスライドさせる処理をする。
グループ管理に使う変数はまとめて構造体にした。
group.Index [gn] ・・・そのグループ番号が使用中かどうかを表すフラグ
group.Color [gn] ・・・そのグループの色
group.Member [gn] ・・・そのグループのメンバー数
group.MemberX [gn] [no] ・・・グループメンバーのX座標
group.MemberY [gn] [no] ・・・グループメンバーのY座標
gnはグループ番号
noはメンバーの番号
で、ながながと書いてきて、なんだけども、現在バグバグである(笑)
グループの結合処理を行うごとに、とりあえず1~10までのグループデータを表示させて、原因を探索中。
うまくグループ分けできてる時と、そうじゃない時があって、その分岐要因がわからないのよ。
いちお、デバッグ中のバージョン置いときます。
操作は前回と一緒。
落下するごとにデータを表示して一時停止しますんで、そのつどなにかキーを押してください。
毎度ですがzipなんで解凍してから実行してください。
http://u7.getuploader.com/game/download/50/%E3%81%B7%E3%82%88%E5%86%8D%E7%8F%BE%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8%EF%BC%8310.zip
引き続きバグ取りしますW
地味に時間のかかる作業なので、ブログの更新が遅れるかも・・・
プログラムの設計について
睡眠時間を削りながら、僕なりにぶっ飛ばして作業してきたんで、一つ一つの処理についてはあまり触れてこなかったんだけども、よく考えたらブログのタイトルからしても僕のようにC言語やプログラミングを始めたばかりの人も見ていると思うので、少しだけ説明しとこうと思う。
もちろん僕の復習も兼ねる。
ベテラン・プログラマーの方には「何を今さら」的な内容だと思うんだけど、僕にとっては最新のトピックスなので偉そうな説明を笑って許してちょーだい。
で、例えば落下するぷよの回転について。
えっと、まず、今回の場合、厳密に言うと回転では無いです。
座標を中心点を軸にして回転する公式とかを使ってるわけじゃないってこと。
ぷよの場合、上下左右の4方向の要素しかないんで、んな面倒なことは必要ない。
落下スタート時点で下になってるぷよを軸にして、上のぷよをZキーが押されるたびに配置換えしてるだけ。
下のぷよを①、上のぷよを②、最初の縦に並んだ状態を状態0として、
状態0 状態1 状態2 状態3
②
① ②① ① ①②
②
こんな感じで①を中心に②の配置を状態別に決定している。
ぷよの状態を表す変数を用意してZキーが押されるたびに1を足してゆく、んで4になっちゃったら0に戻す。
僕のプログラムでは操作に対する座標の移動は①に対してのみやっていて、あとは状態変数の値から②の座標を求めるようになっている。
まず、これが原則になるルールね。
そして、それを踏まえた上で、例外状況の処理を考える。
どういった例外が考えられるだろうか。
例えば、状態0で左に壁がある時にZキーが押された場合。
そのまま、状態1に移行すると②が壁の中に入ってしまう。
そういった時にどういう処理をするか、ルールをあらかじめ決めておかないと実際プログラムを書く時に迷ってしまう。
僕のプログラムでは、この場合①と②を入れ替えて状態3になるように処理している。
手元に実物が無いので、本物がどういう処理をしているかはわかんないけど、まったく同じにしたければ調べて同じになるようにルールを決めれば良い。
ここで言いたいのは例外状況や決まりを、あらかじめ洗い出して、どう処理をするか決めておく事が大切だと言う事だ。
そうじゃないと今回作っている程度の規模のプログラムでさえ、途中から何処で何をしようとしていたかを把握できなくなる。
で、バグった時に前々回の僕の記事のように混乱するわけだ(笑)。
それでも解決できれば良いのだけど、そうじゃない時は何時間も間違い探しをしているうちにモチベーションが下がって投げ出してしまうかもしれない。
設計をあらかじめ考えて書き出しておくことは大切だなあと、本当に思った。







「試しにぷよを再現してみるか」ってボンヤリ考え出したころからのメモ。
ほとんどが色が同じで隣り合っているぷよを配列内でどうやって検索するのが効率的か検討する内容だ。
こういう工程が僕は一番楽しい。
解決法を発見できた時の達成感は名作ゲームをクリアできた時に匹敵するくらいだ。
って言うか、これがほぼ固まってしまうと、プログラムを書くこと自体は作業のよう。
睡眠時間を削りながら、僕なりにぶっ飛ばして作業してきたんで、一つ一つの処理についてはあまり触れてこなかったんだけども、よく考えたらブログのタイトルからしても僕のようにC言語やプログラミングを始めたばかりの人も見ていると思うので、少しだけ説明しとこうと思う。
もちろん僕の復習も兼ねる。
ベテラン・プログラマーの方には「何を今さら」的な内容だと思うんだけど、僕にとっては最新のトピックスなので偉そうな説明を笑って許してちょーだい。
で、例えば落下するぷよの回転について。
えっと、まず、今回の場合、厳密に言うと回転では無いです。
座標を中心点を軸にして回転する公式とかを使ってるわけじゃないってこと。
ぷよの場合、上下左右の4方向の要素しかないんで、んな面倒なことは必要ない。
落下スタート時点で下になってるぷよを軸にして、上のぷよをZキーが押されるたびに配置換えしてるだけ。
下のぷよを①、上のぷよを②、最初の縦に並んだ状態を状態0として、
状態0 状態1 状態2 状態3
②
① ②① ① ①②
②
こんな感じで①を中心に②の配置を状態別に決定している。
ぷよの状態を表す変数を用意してZキーが押されるたびに1を足してゆく、んで4になっちゃったら0に戻す。
僕のプログラムでは操作に対する座標の移動は①に対してのみやっていて、あとは状態変数の値から②の座標を求めるようになっている。
まず、これが原則になるルールね。
そして、それを踏まえた上で、例外状況の処理を考える。
どういった例外が考えられるだろうか。
例えば、状態0で左に壁がある時にZキーが押された場合。
そのまま、状態1に移行すると②が壁の中に入ってしまう。
そういった時にどういう処理をするか、ルールをあらかじめ決めておかないと実際プログラムを書く時に迷ってしまう。
僕のプログラムでは、この場合①と②を入れ替えて状態3になるように処理している。
手元に実物が無いので、本物がどういう処理をしているかはわかんないけど、まったく同じにしたければ調べて同じになるようにルールを決めれば良い。
ここで言いたいのは例外状況や決まりを、あらかじめ洗い出して、どう処理をするか決めておく事が大切だと言う事だ。
そうじゃないと今回作っている程度の規模のプログラムでさえ、途中から何処で何をしようとしていたかを把握できなくなる。
で、バグった時に前々回の僕の記事のように混乱するわけだ(笑)。
それでも解決できれば良いのだけど、そうじゃない時は何時間も間違い探しをしているうちにモチベーションが下がって投げ出してしまうかもしれない。
設計をあらかじめ考えて書き出しておくことは大切だなあと、本当に思った。
「試しにぷよを再現してみるか」ってボンヤリ考え出したころからのメモ。
ほとんどが色が同じで隣り合っているぷよを配列内でどうやって検索するのが効率的か検討する内容だ。
こういう工程が僕は一番楽しい。
解決法を発見できた時の達成感は名作ゲームをクリアできた時に匹敵するくらいだ。
って言うか、これがほぼ固まってしまうと、プログラムを書くこと自体は作業のよう。
バグ取り完了!
いや、本当に細かい数値のミスだった。
for文の繰り返し回数を間違えていたり、1X を 0Xって打ち間違えていたり、フィールドの枠表示と実際のフィールドの位置がずれていたり。
注意してやってても、細かいミスは出てくるもんだ。
問題はプログラムが問題無く実行されてしまう事だ。
文法上の問題じゃないから、当たり前なんだけど、コンパイル段階で出るエラーの方が原因が特定しやすくて楽だわ。
結局、今回実装した関数の呼び出し部分全てに、いったんコメントマークを入れて無効化し、1つずつコメントマークを外して動きを確かめながらデバッグした。
疲れた・・・。
今回のバージョンから、落下したぷよはフィールドに蓄積されてくようになった。
フィールドの状態を管理するのに2次元配列変数を使っている。
GameField[x][y]って感じで、xは8、yは14。
中身は初期状態でこんな感じ。
60000006 y0
60000006 y1
60000006 y2
~中略~
60000006 y11
60000006 y12
66666666 y13
ゼロの部分がフィールドの空白を現している。
ぷよが着地すると、その時点でぷよの位置と色が配列に記録される。
例えば右下に黄色、赤と縦に置いた場合、
60000006 y0
60000006 y1
60000006 y2
~中略~
60000036 y11
60000016 y12
66666666 y13
配列内はこうなる。
あとは、配列内容を調べてその通りに表示するだけだ。
また、落ちてきたぷよがいられる場所は空白のみなので、配列内では0の部分になる。
これを利用して落下中のぷよの当たり判定も全て配列変数を利用する形にした。
つまり、落下中のぷよの座標で配列内を調べて、0より大きい数が入っていれば当たり判定が発生すると言うような具合だ。

かなりゲームらしくなってきました。
ただ、今は積み上げられてゆくのみ・・・。
実行ファイルも置いときます。いつもどうりzipですので、解凍してからフォルダ内のexeファイルをダブルクリックで実行できます。
リリース構成でのデバッグの意味もいまいちよくわからないで使っているので、ダウンしたファイルが動かないと言う方がいたら、コメントいただけると有難いです。
(対処できるかどうかは別ですが・・・w)
http://u7.getuploader.com/game/download/44/%E3%81%B7%E3%82%88%E5%86%8D%E7%8F%BE%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8%EF%BC%838.zip
矢印キーの左右、下で落下中のぷよ移動
Zキーで回転
ESCキーを押すか、左から3番目の列が上まで積まれるとプログラムを抜けます。
その後、何かキーを押せばプログラムが終了します。
さあ、あと残った大きな実装は、ぷよを消す処理だ!
いや、本当に細かい数値のミスだった。
for文の繰り返し回数を間違えていたり、1X を 0Xって打ち間違えていたり、フィールドの枠表示と実際のフィールドの位置がずれていたり。
注意してやってても、細かいミスは出てくるもんだ。
問題はプログラムが問題無く実行されてしまう事だ。
文法上の問題じゃないから、当たり前なんだけど、コンパイル段階で出るエラーの方が原因が特定しやすくて楽だわ。
結局、今回実装した関数の呼び出し部分全てに、いったんコメントマークを入れて無効化し、1つずつコメントマークを外して動きを確かめながらデバッグした。
疲れた・・・。
今回のバージョンから、落下したぷよはフィールドに蓄積されてくようになった。
フィールドの状態を管理するのに2次元配列変数を使っている。
GameField[x][y]って感じで、xは8、yは14。
中身は初期状態でこんな感じ。
60000006 y0
60000006 y1
60000006 y2
~中略~
60000006 y11
60000006 y12
66666666 y13
ゼロの部分がフィールドの空白を現している。
ぷよが着地すると、その時点でぷよの位置と色が配列に記録される。
例えば右下に黄色、赤と縦に置いた場合、
60000006 y0
60000006 y1
60000006 y2
~中略~
60000036 y11
60000016 y12
66666666 y13
配列内はこうなる。
あとは、配列内容を調べてその通りに表示するだけだ。
また、落ちてきたぷよがいられる場所は空白のみなので、配列内では0の部分になる。
これを利用して落下中のぷよの当たり判定も全て配列変数を利用する形にした。
つまり、落下中のぷよの座標で配列内を調べて、0より大きい数が入っていれば当たり判定が発生すると言うような具合だ。
かなりゲームらしくなってきました。
ただ、今は積み上げられてゆくのみ・・・。
実行ファイルも置いときます。いつもどうりzipですので、解凍してからフォルダ内のexeファイルをダブルクリックで実行できます。
リリース構成でのデバッグの意味もいまいちよくわからないで使っているので、ダウンしたファイルが動かないと言う方がいたら、コメントいただけると有難いです。
(対処できるかどうかは別ですが・・・w)
http://u7.getuploader.com/game/download/44/%E3%81%B7%E3%82%88%E5%86%8D%E7%8F%BE%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8%EF%BC%838.zip
矢印キーの左右、下で落下中のぷよ移動
Zキーで回転
ESCキーを押すか、左から3番目の列が上まで積まれるとプログラムを抜けます。
その後、何かキーを押せばプログラムが終了します。
さあ、あと残った大きな実装は、ぷよを消す処理だ!
- ABOUT
やってやれないことはないっ!たぶん・・・
- カレンダー
06 | 2025/07 | 08 |
S | M | T | W | T | F | S |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- 最新コメント
[11/09 CALL MY NAME]
[11/09 erin]
[08/18 うずランド]
[07/11 うずランド]
[06/23 うずランド]
- プロフィール
HN:
Call my name
年齢:
51
性別:
男性
誕生日:
1974/05/22
職業:
スロ屋店員
趣味:
いろいろ
自己紹介:
やる気だけはあるつもりです。
はい。
はい。
- ブログ内検索
- カウンター
- アクセス解析