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

ケースバイケースですよ!

今までのスクリプトは、いわば一方通行でした。
repeat で巻き戻る時もありましたが、結局、同じことを繰り返しているだけでした。
何度やっても同じ結果になるのです。
本当に単純なスクリプトなら何とかなっていましたが、少しでも複雑にしようとすると、すぐに行き詰まります。

そこで、「場合によって処理を分ける」if 文というものをマスターしましょう。
これ無しではプログラミングが大変というほどの重要なものです。
がんばりましょう! 意外と簡単です!

とりあえず、サンプルから。

#const IDW_Main 0
	
	screen IDW_Main, 320, 240
	syscolor 15 : boxf : color
	
	dim year		// int 型にします
	
	pos  20,  20 : input year, 80, 25, 4
	pos 120,  20 : button "調べる", *CheckOlympicOpened
	stop
	
*CheckOlympicOpened
	// 画面をいったんリセット
	syscolor 15 : boxf : color
	
	// 位置は固定する
	pos  30,  60 : mes ""+ year +"年"		// とりあえず年を表示する
	
	if ( year \ 2 == 0 ) {			// 2で割り切れる (= 2で割ったら余りがない)
		mes "オリンピックが開催されます。"
		
		// どっちか調べる
		if ( year \ 4 == 0 ) {		// 夏季五輪の年は 4 で割り切れる
			mes "夏季五輪です。"
		} else {				// 夏季じゃなかったら冬季です
			mes "冬季五輪です。"
		}
		
	} else {
		// なし
		mes "オリンピックが開催されません。"
	}
	stop

ここから先、if について覚える前に
前段階として、「演算子 (Operator) について知っていた方がいいです。
別ページにまとめたので、参考にしてください。
  →演算子について(前編)


もしも……

	int1 = 4
	int2 = 9
	str1 = "あいうえお"
	str2 = "かきくけこ"
	
	if ( str1 == "あいうえお" ) : mes "str1 は \"あいうえお\" です。"
	if ( str2 != "かきくけこ" ) : mes "str2 は \"かきくけこ\" ではありません。"
	if ( int1 <  3 ) : mes "int1 より 3 の方が大きいです。(3ではありません)。"
	if ( int1 >  3 ) : mes "int1 は 3 より大きいです。(3ではありません)。"
	if ( int2 <= 3 ) : mes "int2 は 3 か、それ以下です。"
	if ( int2 >= 3 ) : mes "int2 は 3 以上です。"
	stop

※関係演算子のサンプル・スクリプト

これが ifです。

if ( 条件式 ) : 成立する時の処理 (処理 = やりたいことを命令にしたもの)

という形で書きます。
条件式が正しい (成立する) ときだけ、 : [コロン]の後の文を実行します。
間違っている場合、その行の文は無視します。

+参考:なぜ " \" string \" " のように書いているのか
エスケープシーケンス


違ったときの処理

これまでに、条件式が成立するときの分岐はやりました。
しかし実際には、成立しないときも分岐したいことが多いのです。
と言うわけで、試してみましょう。
でも、こんなの簡単ですね。条件を「逆」にすれば良いわけですから。

	a = 3		// 比較する値
	if (a == 3) : mes "a は 3 です。"
	if (a != 3) : mes "a は 3 ではありません。。"
	stop

へい、完了。

うーん。なんか嫌な感じがしませんか? 原因は、似た条件をいちいち書いているところです。
こんなもの、無駄でしかありません。
もったいないの精神に欠けています! もったいないおばさんに怒られます。

	a = 3		// 比較する値
	if (a == 3) : mes "a == 3" : else : mes "a != 3"
	stop

else
直前の if 文の逆を判定する命令 else
違ってた時の命令も書きたいときは、else
if : 文 : else
何度でも言います。else
覚えてね。
else
else
else
……


一つの判定で複数の処理

さて、今までの方法では、一つの if 文ごとに、一つの命令しか実行できませんでした。
解決策として、命令の数だけ if文を並べるという方法があります。
今回も簡単でしたね。やってみましょう。

	a = 3
	if ( a == 3 ) : mes "a"
	if ( a == 3 ) : mes "は"
	if ( a == 3 ) : mes "3"
	if ( a == 3 ) : mes "で"
	if ( a == 3 ) : mes "す"
	if ( a == 3 ) : mes "。"
	stop

酷いスクリプトですね。
もちろん、もっとスマートなやり方があります。

	a = 3
	b = 6
	if ( a == 3 && b == 6 ) : mes "a = 3" : mes "b = 6"
	stop

これで、一回のifだけで mes 命令が2回実行できます。
オブジェクト編で、マルチステートメントと言っていたのを覚えていますか?
このサンプルは、それを使っただけです。
もちろん、else も使えます。

この方法、やっぱり駄目です。無意味なマルチステートメントは、極力避けましょう。
それに、if 文には特別、見やすくするための文法が存在します。
波括弧、ブレイス { } で処理を囲みます。

	a = 3
	b = 12
	
	if ( a == 7 || b < 11 ) {
		mes "a == 7 もしくは"
		mes "b < 11 の条件が成立します。"
	} else {
		mes "a != 7"
		mes "b > 11"
	}
	stop

明らかに見やすくなりました。これによって、いくらでも処理を書くことが出来ます。
当然 else も使えます。 (使い方はサンプルの通り)
自分はマルチステートメントが好きではないので、常にこの書式を使うことを奨めます。


いくつも条件を重ねる

社員「部長、これでどうですか!?」
部長「その方法じゃコストが掛かりすぎるんでね?」
社員「部長、こっちはどうですか!?」
部長「非効率だよぉ〜」
社員「部長、それでは、これは!?」
部長「時間ロスが大きすぎやしねぇか?」
社員「では、今までの方法でよろしいですか……?」
部長「無難にそうすっか。」

いきなり何? っと思ったでしょうが、このように、いくつもの条件を提示して、どれも駄目なら最後のものを実行する、という処理を考える前振りだったのです! ※(分かるかよっ!)

それでは、どういった処理になるでしょうか。
条件判断なので、当然 if 文を使うわけですが、普通にすると、一つの条件しか判定出来ません

if 文一つに付き、条件が一つということは、何個も if 文を使えばいいのです!
使う位置は、前の if が駄目だった時なので、elseの中になります。

	a = 2		// 比較する値
	
	if ( a == 0 ) {
		mes "a == 0"
	} else {
		if ( a == 1 ) {
			mes "a == 1"
		} else {
			if ( a == 2 ) {
				mes "a == 2"
			} else {
				if ( a == 3 ) {
					mes "a == 3"
				} else {
					// どれも当てはまらなかったら
					mes "a の値は不明です"
				}
			}
		}
	}
	stop

びっくりするぐらい見にくいですね。通常は、次のように書きます。

	a = 2		// 比較する値
	
	if ( a == 0 ) {
		mes "a == 0"
	} else : if ( a == 1 ) {
		mes "a == 1"
	} else : if ( a == 2 ) {
		mes "a == 2"
	} else : if ( a == 3 ) {
		mes "a == 3"
	} else {
		// どれも当てはまらなかったら
		mes "a の値は不明です"
	}
	stop

この書き方を俗に、else-if文と呼びます。
else のブロックに {} を使わず、マルチステートメントにしています。


値で判定する

先ほどのサンプルでは、( a == ? ) という条件式をいくつも書きました。
これはどう見ても無駄ですし、このような比較はよく行われるので、
構文( 決められた特別な書式 )にしておくと、楽になります。
switch文というものです ( これの名前は、プログラミング言語によって揺れます )

	a = 2
	
	// switch - case - swend
	switch ( a )		// 比較元の値
		case 0: mes "a == 0"	: swbreak
		case 1: mes "a == 1"	: swbreak
		case 2: mes "a == 2"	: swbreak
		case 3: mes "a == 3"	: swbreak
		case 4: mes "a == 4"	: swbreak
		case 5: mes "a == 5"	: swbreak
	defualt
		mes "a の値は 0〜5 ではありません。"
	swend
	
	stop

※switch などの色が違うのは気にしないでください。

やたらと新規キーワードが多いですが、
一つ一つはたいしたことありません。
順に軽く説明していきます。

switch
switch 文の開始と比較元の値を設定します。
case
比較元の値を使って比較します。等しければその後の処理を実行し、
違えば、次の case までジャンプします。
通常、処理の最後にswbreakを置きます。
そうしないと、次の case の先まで実行してしまいます。
default
必ず次の処理を実行します。switch文の、最後に置きます。(無くても良い)
swbreak
swendまでジャンプします。
swend
switch 文の終了を示します。

整数値(int)だけでなく、文字列や実数なども比較できます。
比較元の値と case の値で、型が違う場合、後者が変換されます。


おわりに

今回の講座はこれで終わりです。
「演算せよ(前編)と分割したので、若干短かったですね。
演算子もエスケープシーケンスも大事なので、覚えておいてください。

大切な内容なので、復習してから終わりましょう。さようなら〜〜。

……て、最初のサンプルにはノータッチですかい。
まぁ、これは各自でスクリプトを読んでおいてください。難しいことは特に書いていませんので。

では、また次回をお楽しみに。

まとめ
命令 パラメータ 効果
if ( 条件式 ) 比較して、成立するなら次の文を実行する。
else --- 直前のifの条件が成立しないときに実行する処理を書く。
else : if ( 条件式 ) 前のifの条件が成立しないとき、
別の条件で分岐するときに使う定石。
switch 比較元の値 switch文を始める。
case 比較値 switch の値と比較値が等しいかどうかを調べ、
等しければ次から swbreak までの処理を実行します。
等しくなければ、次の case までジャンプします。
default --- switch 文の最後に、どの case も非成立の時に実行する処理を書きます。
swbreak --- switch 文を抜けます。
swend --- switch 文を終了します。

by 上大

第六章へ   第八章へ