このページでは、前回に引き続き、監督スクリプトの仕事の一つである、ぷよの落下が完了次第、同色ぷよが4個以上隣り合っているぷよを消滅させるスクリプト文を書いていきます。
前回、同色ぷよが何個隣り合っているかをカウントするスクリプトを書く前に、大まかな書き方の方針の話、そして再帰呼び出しという書き方の紹介まで終わりました。まだお読みでない方は本記事を読まれる前に前回の記事を先に読んでおいて下さい。
今回は、もう少しスクリプトの書き方を決めていきます。具体的には、前回の記事中にあった、寸劇の内容をスクリプト文で再現するにはどのように書けばよいか?という考え方で書いていきます。
ではまず寸劇をスクリプトで再現するに当たり、突然ですが、ここで問題です。
寸劇の内容の内、再帰呼び出しを用いて書いていくのはどの部分でしょうか?
ヒントは、再帰呼び出し=自身のメソッドを呼び出す、なので、再帰呼び出しを用いる部分は(条件を満たせば)何回も繰り返し処理を行うことになります。よって、前回の寸劇中で何度も出てきた処理(言葉)を再帰呼び出しで書いていけば良さそうです。寸劇中でよく出てきた言葉と言えば…
監督「では0番のぷよさん、自分の左右上下を確認して下さーい」
監督「では次に2番ぷよさん、自分の左右上下(左の0番除く)を確認して下さーい」
監督「それでは次の1番ぷよさん、自分の左右上下を確認して下さーい」
前回の記事中でも青太字になってましたね(笑)。ということで上の問題に対する答えは、「自分の左右上下を確認する作業」を再帰呼び出ししていけば良い、ということになります!!!
てなわけで、同色ぷよが何個隣り合っているかをカウントするメソッド(ここではCheckメソッドと名付けます)の大まかな構成は以下のような感じになります。
void Check(i番ぷよについて){ if(左のぷよ(j1番ぷよ)と色が同じ?) Trueなら→Check(j1番ぷよについて); if(右のぷよ(j2番ぷよ)と色が同じ?) Trueなら→Check(j2番ぷよについて); if(上のぷよ(j3番ぷよ)と色が同じ?) Trueなら→Check(j3番ぷよについて); if(下のぷよ(j4番ぷよ)と色が同じ?) Trueなら→Check(j4番ぷよについて); }
このメソッドの流れをご理解頂くために、寸劇の話(0番ぷよの確認作業)で例を出しますと、(右図も見ながら読み進めて下さい)
①0番ぷよにCheckメソッドを適用した結果
i=0:赤(0番ぷよについて)
j1(左ぷよの番号)=×(左隣はカベ)/ j2(右ぷよの番号)=2:赤…同色→次は2番ぷよにCheckメソッドを適用する
j3(上ぷよの番号)=9:緑…異色 / j4(下ぷよの番号)=1:青…異色
②2番ぷよにCheckメソッドを適用した結果
i=2:赤(2番ぷよについて)
j1(左ぷよの番号)=0(0番ぷよは調査済)/ j2(右ぷよの番号)=14:黄…異色
j3(上ぷよの番号)=8:青…異色 / j4(下ぷよの番号)=3:緑…異色
⇒同色が隣に無いためCheckメソッド終了
よって、0番ぷよと隣り合っている同色ぷよは0番と2番で合計2個になります。
この感じ、確かにスクリプト文で寸劇の流れを上手く再現出来ているのがお分かり頂けますでしょうか??まだまだ完成には遠いですが、少しずつやりたいことがスクリプト文に書ける状態に近付きつつありますね!
ではいよいよ具体的ににスクリプト文を書いていこう…という段階ですが、ゴメンナサイ、今回は少し短いですがここまでにします!次回、いよいよスクリプトを書いていきます!!
本記事は以下に参考を掲載します。ご興味ある方は是非ご一読下さい!
隣り合う同色ぷよ数をカウントするアルゴリズムは色々なブログにて説明されていますが、大半のブログでは本記事と同様、再帰呼び出しを用いた説明がなされています。理由は色々あると思いますが、要するに再帰呼び出しを用いた書き方が一番シンプルに纏められるからだと私ワガハイは考えています。
極端な例としてもし最初の確認で左右上下全部同色の場合、次に左右上下のぷよ各々がさらに左右上下の確認をする、つまり4×4=16回の追加作業が発生します(もちろん、中には実質意味のない確認作業もあります)。要するに16個の追加if文が発生します。
さらに先程確認したぷよの各々左右上下を確認すると4×4×4=64回の追加作業→64個の追加if文、さらに確認したぷよが左右上下を確認すると…(((( ;゚Д゚)))ガクガクブルブル
つまり、作業の試行回数(=if文の数)は4の○乗的に、つまり指数関数的に増大していきます。そんなのクソ真面目に沢山のif文書いてたら、ただただスクリプトが長くなるだけですし、さらには書き間違い等によるバグ発生の温床にもなりかねません。
そこで、再帰呼び出しの登場です。結局、今回の隣り合う同色ぷよのカウント作業って、左右上下の確認作業(作業回数4回)の繰り返しなんです。いつもなら繰り返し→for文!と言いたい所ですが、今回のように試行回数が指数関数的に増えていく場合は、for文での表現が困難になります(書ける場合はワガハイまで教えて下さい)。なので、代わりに再帰呼び出しを使っていきます。実際、上のようにスクリプトを書くだけで、16回とか64回の追加作業にも簡単に対応してくれますよね!
なので、今回のように試行回数が指数関数的に増えていく作業を簡潔にプログラミングするためには、再帰呼び出しがピッタリだと私ワガハイは考えているので、今回の隣り合う同色ぷよのカウント作業に再帰呼び出しを使用しました。ご参考にして頂けると幸いです。