Home -> HSP講座 -> 初級編 No.9

組み合わせ大爆発?

さて、前回の講座では、「数当てゲーム」を通して、スクリプトの書き方を教えました。
ただしあの書き方は、もう「時代遅れ」です。
見てください、前回のスクリプトを。
若干の if - else文があっただけで、ほとんど一本道でしたね?
簡潔で良いんじゃないかと思うかもしれませんが、それは逆に、とてつもなく複雑で、難解で、無駄です。
あのまま未来永劫追加・修正しないなら良いかもしれませんが、もし修正するとなると、スクリプトを一旦、すべて解読しなければ、正常に動かないように改悪してしまう危険があります。
すべて解読することに関しては仕方のないことで、コメント・変数名・ラベル名などをしっかり考えて、内容を解説した文章などを残しておけば、ある程度緩和できるでしょう。
しかし、解読するということは、スクリプトを読む、ということが必ず必要です。効率よく読むには、いらない部分を見ない事が大切です。
というわけで、いらない部分、つまり細かい実装は別の場所に書きます。
これにより、ブロック単位でスクリプトを読むことが出来ます。

途中で意味不明になってきた人も多いと思うので (僕含む)、例を書いてみました。

今と昔のプログラム方式の対比

時代遅れのプログラム

比較的新しいプログラム

何で画像を使ったのか分かりませんが、(-o-?) とりあえず、左右を見比べてみてください。

左側(昔)は処理ごとの間隔が広く、無駄な部分まで見えていたので、全体像がつかみにくそうです。
対して右側(今)は、処理が連続していて、処理の順番・効果などが素早くで理解できます。

gosubは、これをHSPで実現するための命令です。


構造化するということ

右側のようなプログラムの書き方・考え方を「構造化プログラミング」といいますが、覚える必要はありません。
こんなもの、今となっては基本中の基本なので、名前なんて必要ないからです。( 今の主流はオブジェクト指向ですね、どうでもいいですが )

前回の最後に、「理解しなくてもいい」と追記しておいたのは、
あのままだと理解しにくいから、がんばらなくてもいい。
という意味だったんです。

さて、実際に構造化したサンプルを組んでみましょう。こんな感じです。

// No.3 ラベル編より
*main
	gosub *SetWindow	// 画面を構築
	stop
	
//################################################
//    サブルーチン
//################################################
// 画面をセットする
*SetWindow
	mes "スクリプトにしるしを付けます。"
	mes "どちらに進みますか?"
	pos  20, 100 : button gosub "goto Mark1", *Mark1
	pos 100, 100 : button gosub "goto Mark2", *Mark2
	return
	
*Mark1
	dialog "Mark1に来たよー!", 0, "報告"
	return
	
*Mark2
	dialog "ここは Mark2 ですか??", 2, "質問"
	return

※あんまり有効利用とはいえないか。

一つ、今までと全く違う、新しい文法のようなものがあります。
ずばり、

	button gosub "goto Mark1", *Mark1

これです。明らかにおかしいですね。もちろん、僕のミスではありません。(^ー^)/
これは HSP3 で導入された、goto gosub キーワードです。
ラベルにジャンプする命令などに付けることがあります。
付けなければ goto 扱いとなるので今までは放っておきましたが、「構造化」するためには必要なので、今回は付けました。付ける位置は、主に命令の直後です。ワンキー・ヘルプを活用しましょう。(おい

※goto gosub 命令とは一切関係ありません。
 それでも命令と同じ色にしているのは、スクリプトエディタにあわせているからです。

今回のスクリプトは解説が必要そうです。

まず、一番上から実行するので、*mainラベルをほっといて
gosub *SetWindow
を実行します。
gosub 命令はサブルーチン・ジャンプという特殊なジャンプを行います。
これはなんと、ジャンプ元に返ってくることができます。
「サブルーチン・ジャンプ」した先を、「サブルーチン」といいます。
return 命令は、現在のサブルーチンから、前いたところに戻ります。


構造化したプログラムの処理フロー

右側の処理の並びは、やや複雑そうに見えますが、実際には、複雑なのは線の本数だけであって (申し訳ない)、処理の順序・効果などは、よく分かります。
そもそも、僕らプログラマが見るのは左側だけなので、
実行している位置の移り方などは、あまり気にしません。

右への矢印が gosub、
左への矢印が return です。
戻っている矢印は、二本の矢印をつなげただけです。(めんど……ry)

*SetWindow では、ウィンドウの装飾などをしています。
その次の return で、gosub の次の stop に行き、そこで停止します。

画面上のボタンが押されると、下の「サブルーチン」にジャンプします。
さっきいったとおり、gosub でのサブルーチン・ジャンプなので、ダイアログを表示したら、また stop に戻ります。

この通り、ずっとstopにいます。
この性質を利用して、メインをrepeatループにしておくと、一定時間ごとに何かしながら、ボタンのジャンプもしっかり受け付けることが出来ます。
※いちいちgotoしていると、ジャンプするたびにループの始めに戻るしかありません。


「構造化」の定義

「構造化」するというのは、サブルーチンに分けることではありません。
サブルーチン化して、処理を纏めるのは、構造化の一つの方法です。

「構造化プログラミング」とは、プログラムの流れを以下の3つだけにすることを言います。

順次
普通です。上から下へ流れていくだけです。たぶん gosub はこれに含みます。
反復
繰り返しです。同じところを何度も何度も実行します。
ここで言っているのは、終点から始点に戻ることでしょう。
for や while という文が有名ですが、HSPでは repeat を使うと非常に楽です。
分岐
分かれ道です。
以前長々と説明した回がありましたが、そのときの if と else のことです。
if文は条件分岐の基本です。また、switch も非常に有名な条件分岐の文です。

前述の3つの中には、「跳躍」なんてのがなかったので、goto の使用は認められていません。
※gosub は戻ってくるのでよい。
サブルーチン化には、goto を使わずにジャンプできるという利点もあるのです。



以上。いつもより短かったですが、今回の講座は終了です。……退屈だったと思います。
予定では、僕がこれから先にあるサンプルを出来る限り「構造化」するので、嫌でも覚えると思います。

ではまた次回。

by 上大

第八章へ   第十章へ