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 はこれに含みます。
反復
繰り返しです。同じところを何度も何度も実行します。
ここで言っているのは、終点から始点に戻ることでしょう。
forwhile という文が有名ですが、HSPでは repeat を使うと非常に楽です。
分岐
分かれ道です。
以前長々と説明した回がありましたが、そのときの ifelse のことです。
if文は条件分岐の基本です。また、switch も非常に有名な条件分岐の文です。

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



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

ではまた次回。

by 上大

第八章へ   第十章へ