珍しく、このコーナーでプログラミングの話です。 プログラミングではなく、MA-CYさん作の「Racing双六」が面白いな、と思う人向けの読み物です。 MA-CYさんの「Racing双六」で起きている「Comプレイヤー動作中は一切のキー入力を受け付けない」という問題。 この問題は小さいようで大きな問題です。 なぜなら、「キー入力を受け付けない」と言うのは、単にボタンやキーボードの類だけの話ではなく、電源ボタンなどのシステム関連の「動作」も受け付けなくなるというお話だからです。 この解説はいなあもさんが解説されていますが、プログラムの動作という面白いテーマなので、非プログラマの人でも楽しめるようにmizuno-ami流で解説してみる事にしましょう。 ほとんどのプログラムが「何かあったら、何かして」という手順の連続で作られています。 難しい言葉でいえば「イベントドリブン」と言います。ま、キッカケを与えてあげないと処理しませんよ、と言っている訳ですが、Racing双六を大雑把な図で表してみると、実はこんなモノになります。 ここまで単純化してしまうと、作者のMA-CYさんに失礼かもしれませんが、説明用の材料として、実際の主たる部分はこんな関係になっていますよ、としても叱られる事はないでしょう。 さて、最大4人のプレイヤーで楽しめるRacing双六の「メインプログラム」をもう少し細かく図にしてみるとこんな感じになるでしょうか。 メインの部分が「誰の順番か」を管理する部分で、何らかのイベントによって「ルーレットを回す」処理を呼び出して使っている、という図として表現する事が出来ます。 「イベント」は言ってみれば「キッカケ」の事です。 例えば人間がプレイしている時は「ボタンを押したとき」という「外部からの入力」がキッカケになります。 Comプレイヤーがプレイしている時のイベントは……んーと、何だろう? 実は、このComプレイヤーがルーレットを回す「キッカケ」を、どうやって決めているのかは作者のMA-CYさんのみぞ知る、という部分です。 もちろん、使えるイベントの種類は限られていますから、おおよその目星はつけられますが、正解が1つじゃないので、ここで断定する事は出来ません。 ただ、具体的なことは分からなくても「何らかのキッカケ」によって、Comプレイヤーがルーレットを回している事は事実ですから、その点はあまり気にせずに、問題の本質に近づいて見ましょう。 作者MA-CYさんが何を困っておられるか、というと、実は「お邪魔虫」が存在するからです。 そのお邪魔虫とは、我らが「PalmOS」本人だったりする訳で、敵が味方の中に居た、という厄介な状態なのです。 この図のように「イベント」によってルーレットを回すようにしていると、もしかすると、PalmOSが発生させたイベント、例えば「電源ボタンが押された」「画面がタップされた」などのイベントによってもルーレットが回ってしまう可能性があります。 正確に言えば、そういう問題が発生する方法でプログラムが組まれている、と言わなければなりませんが、どちらにしてもMA-CYさんは、この「PalmOS」からのイベントを「無視」することで問題を回避されている訳です。 それは、イベントを無視している間は動作も機能しないという結果となり、つまり「Comプレーヤー動作中は一切のキー入力を受け付けない」問題を生じるわけです。 さて、この問題を何らかの形で修正したい訳ですが、元のプログラム、それも完成してしまったプログラムをできるだけ触らないようして修正するのは「プログラマの夢」です。 いや、人としてとても正しい方向でしょう。 誰しも、完成したものをもう1回解体してやり直すというのはやりたくない筈です。 世間一般でも、書類などを修正する場合「訂正印」を使ったり、また「修正液」なるものを使うわけですよね。許される範囲内で。 しかし、何らかの形で手を入れなければならない場合、直接的な作業の手間は当然ですが、その変更によって発生するトラブルを出来るだけ少なくなるように考える手間も大変です。 しかし、こういう場合、実は元の処理にちまちまと手を入れるより、むしろ新しい仕組みを挿入して作り変えてしまう方が楽だったりします。 例えば、今での処理とは全く別の機能を持った処理を新たに挿入してしまうような方法。 図にすると、こんな感じでしょうか。 この例で新たに挿入した「イベント処理ルーチン」は、与えられたイベントを処理して、必要ならば「ルーレット回しルーチン」を呼び出す仕組みです。 「えー?!その方が大手術だがや!」 と思わず名古屋弁で驚いてしまいます。 でも、プログラムで重要なのは、個々の処理が上手く作られている事はもちろんですが、それらの処理が集まった1つの集まりがキチンと働くか、という点も重要です。 「キチンと動く」と言うのはどういう事か、と言うと「与えた情報」に対して「決まった情報」が返る、という動作の確実さです。 例えば、キーボードで「Aのキーを押す」という情報に対し「Aという文字を表示する」という処理は当たり前のようで重要な話です。 このキーボードの「処理」をもう少し一般的に言えば「押されたキーと同じ文字を表示する」となる訳ですが、これが「押されたキーに対して、適当に画面に文字でも表示してみたりしなかったりしようかなぁ」では困るわけです。 (そういうデタラメを利用したのがゲームですが、それだってルールがあります。) そういう意味では「Racing双六」のように既に完成しているプログラムは、既に個々のパーツは無事に動いている訳ですから、その関係だけを見直して、別の仕組みを入れてしまった方が大手術かも知れなけれど、実は近道かもしれないのです。 ま、こういう点がプログラミングの醍醐味でもあり苦労する点でもあるのですが(笑) ポイント1.処理を上手に組み合わせること ポイント2.与えた情報に対し、確実な答えが返ってくること 例えばNS Basicの場合、入出力に絡んだ何らかのイベント処理は「フォームのイベント」というところに記述するという「決まり」があるのですが、それを大手術を施した後のルーチンに当てはめてみればこんな感じになるでしょうか。 この「イベント処理ルーチン」を、特定の「識別コード」を持ってないければ無視するように作っておけば、PalmOSなどの不要なイベントが来ても無視できるようになります。 ただし、ゲームの途中で電源やその他のボタンを受け付けられるようにすると、不用意にアプリを終了させてしまい、「ああ、最終コーナーで接戦だったのに!」という悲しい事になるかもしれません。 そうならないように、1つを修正すると新しい機能を追加しなきゃならなくなるという修正スパイラル。 実際、いなあもさんが言われる 「この問題は忘れると言うのもいい方法かもしれません。」
というのは1つの解決策として優れています。 もう少し専門的な用語を使えば、 「仕様です。」
ですね。 ま、そういう訳で、これらをどう手術するのかは、作者のMA-CYさんにお任せするとして、MA-CYさんのお悩みを拝借してプログラミングのお話をしてみました。 プログラムのことを「コンピュータに手順を教えるモノ」と表現する事がありますが、これを「Racing双六」に当てはめると、どうやって順番を回して、 誰がルーレットを回すのか、ルーレットを回したらどうなるのか、で、ルーレットって何?という色々な事を専用の言葉で分かり易く教えてあげるモノと言えま す。 そういう点では、この「Racing双六」は、面白い割にルールが単純なので、プログラムの概念的なものを示すのにちょうど良い素材でしょう。 とりあえず、難しそうなプログラミングのお話で、実際、誰の役に立つのか分からない内容ですが、へぇ、そんなものか、と読んで頂ければ幸いです。 ※尚、必要な方は、これらの図はご自由にお使い頂いて構いません。 また、実際の「Racing双六」の動作原理を解説している訳ではありません。 内容についての問い合わせは、全てmizuno-amiまでお願いいたします。 |