もしも××なら…
5ページの答えを紹介。
| A4 | X = "0123"
mes "Xには" + X + "が入っています"
stop |
Xが数値になっていて「Xには123が入っています」となってしまった人がいたことだろうね。
「もしも武器Aを手に入れていたら」
「もしも敵Bに倒されたら」
「もしも所持金がC以上あれば」
もし、ある事象が起こっていれば、起こっていなかったら
という2つ以上の選択肢について説明していきたいと思う。
どんなゲームでもシステム・シナリオ等が1つしかない、というものはない。
完全にないとは言い切られないのだが。
一本道でなくいろいろ枝分かれしているからおもしろい。
書かなくてもいいと思うがRPGを例にしてみよう。
敵と遭遇するのはいつも同じタイミング。
自分・敵の攻撃順、ダメージなど全てにおいて同じ。
倒した時に入手する経験値等がすべて同じで、
敵とのエンカウントが一定なのでレベルアップのタイミングも同じ…。
道を戻ることも外れることもできない。
ただひたすらに前へ進むのみ…。
こんなのってゲームとは言えないよねぇ?
クイズゲームなんて分岐しているのがゲームのウリなのに
回答が一つしかないなんてゲームでもなんでもない。
小説と同じで結果は毎回同じなのだが
一度は見たいと言うのがあるかもしれないけど。
まぁこの先どうなるか分からないって言う
ハラハラドキドキのスリルがあるほうが絶対いいよね。
与えるダメージが一定でないというのだけでも
倒す・倒されるターンが変わる可能性があるので
十分な分岐ポイントであると言えよう。
…でHSPでどうやって分岐させるかと言うと
下記の2つの命令があるのでどちらかを使ってくれればOKだ。
1つはif命令と呼ばれるもの。
1つの条件からYESorNOの2つに分岐するもので
一度に多分岐には向いていない。
もう1つはswitch命令と呼ばれるもの。
HSP2.6から新出した(内部でif命令を実行している)もので
範囲指定ができないのだが大量分岐に向いている。
ただswitch命令以外にcase,default,swbreak,swend命令がセットで
1つの処理をする為に5つの命令を覚えなければならない。
とりあえず1つ目のif命令から説明する。
他言語知っている人にはお馴染みの命令だね。
使い方・構文の書き方も他言語のものと
ほぼ同じなので説明無用だろう。
それ以前にそういった人をターゲットにしてないから見てないか。
英語で「もし〜なら」っていう時に
「if〜」(イフ)って使うよね。そのifと同じだ。
if命令の書式は「if 条件」となっていて、
条件に定数又は変数を指定する。
定数・変数については前のページでやったよね。
定数は「コレが定数」というのがなかったからわかりにくかったかも。
「1+1」を表示するといった「1+1」部分が定数(式)だ。
この結果が3や10に変わることがないよね?
書かなくてもいいだろうけど文字・文字列も指定できるよ。
条件を書くことで命令文が出来るわけだが、
まだ未完成なんだ…。
何が足らないかと言うと、分岐後の処理がないということ。
分岐されても結果が同じだと分ける意味がないよね。
分岐後の書き方なんだけど2通りある。
1つは他言語でもある様にココからココまでが分岐1の処理、
コレが分岐2の処理、といったカッコで範囲を示すやり方。
カッコと言ってもどんなカッコでも良いというわけではない。
始まりは左ブレイス。…と言ってもピンと来る人は少ないよね。
始め中カッコと言えば「あぁアレか」となるかな?
それでも分からない人の為に実際のカッコを書くと「{」となる。
当然、対応する終わりのカッコも右ブレイス「}」となるよ。
実際のサンプルスクリプトを書いてみるとこんな感じだ。
if 1 = 1 {
mes "if文のカッコ内に通過しました"
}
stop
流れを見てみよう。
1行目にif命令が書かれているね?
その条件式を見てみると「1=1」と書かれている。
if命令の条件が正しい場合、
すぐ後のカッコ部分を通過することとなる。
当てはまらない場合、カッコ内全ての処理が無視される。
定数だと条件が変わることないので結果はいつも同じだ。
コレは分岐とは言えないね。使うのはほぼ変数の方だろう。
hensuu = 1
if hensuu = 1 {
mes "こんなスクリプトじゃこの部分を一度しか通らないから"
mes "定数をしているのと何も変わらないんだけど"
mes "これから先きっと使う時が来るから覚えておこう"
}
stop
4ページで演算子が書いてあったのを覚えているかい?
あれらの演算子を利用して式が正しいかを判定する。
これからは式が正しいことを「真」の状態であると呼ぶよ。
式が誤っている場合は「偽」の状態である、となる。
あ、あそこで1つ書き忘れていたものがあったのを思い出したよ。
書き忘れていたものとは「!」(NOT)演算子だ。
左辺と右辺の式の結果が一致しないかを見るもの。
一致しない場合は真、一致する場合は偽を返す。
真は0以外の数値、偽は0と言うことを知っているかな?
真の場合は0以外の代表としては1となる。
条件部の演算子として「=」「>=」「<=」「!=」というのもあるね。
hensuu = 2
if hensuu != 1 {
mes "上にも書いてた様に「!」だけでもいけるよ"
mes "実際に結果が見たい場合は下記のようにしよう"
mes hensuu ! 1
mes "↑\n1と出ていたら「真」だ"
}
stop
4ページの演算子の最後の方にビット演算子がある。
「左ビットシフト」以下のものだね。
普通に使うには2進数やらビット演算やらを覚えなきゃ
使えないから少し難しいかな。
ただAND,OR演算子は複数の条件を扱うのに
必要なものなので重要なんだよ。
「変数Aと1が同じか」という条件と
「変数Bと2が同じか」という2つの条件が
両方とも真だと実行したい場合は下記のようにする。
A = 1
B = 2
if A = 1 & (B = 2) {
mes "2つの条件が両方とも「真」のようだ"
}
if A = 1 & (B = 1) {
mes "変数Bの方が「真」ではないのでココは実行されない"
}
stop
1つ目以降の条件式は
必ずカッコ(「小カッコ」「パーレン」)で括らなければいけないよ。
理由はまたこの後で書くから今は覚えておくだけでOK。
演算子に「&」が使われてるけど「&&」「AND」「and」でもいいんだ。
どれか1つでも真の場合実行するというのも書いてみよう。
A = 1
B = 2
C = 3
if A = 2 | (B = 1) | (C = 3) {
mes "3つの条件のうちココでは変数Cが「真」なので実行される"
}
stop
さて、なぜカッコで括らなければならないか話そう。
また話が4ページに戻っちゃうんだけど、
HSPは基本的に計算手順が前からとなるんだったよね?
if命令の条件部もそうなっている。
Aが1かつBが2の場合にどうなるか考えてみよう。
A = 1
B = 2
if A = 1 & B = 2 {
stop
mes "2つの条件が両方とも「真」のようだ"
}
とりあえず実行してみると何も表示されないね。
つまり条件が「偽」の状態であるというのがわかる。
なぜこうなったか条件部分を詳しく見てみる。
とりあえず左から判定されるのだから「A = 1」を判定。
コレの結果は真なので例によってココに1が入るんだね。
次に先ほどの結果1と変数Bを判定する。
「1 = B」の結果は偽なので0が入る。
最後に先ほどの結果0と2を判定するわけだ。
「0 = 2」の結果は偽、つまり最終的に偽となる。
言葉の説明だと「?」ってなる人の為に展開すると、
| (1) | 「A = 1」か? |
| (2) | 「A」は1により「1 = 1」は「真(=1)」 |
| (3) | 「真(=1) = B」か? |
| (4) | 「B」は2により「1 = 2」は「偽(=0)」 |
| (5) | 「偽(=0) = 2」か? |
| (6) | 「0」と「2」は同じではないので,最終結果として「偽(=0)」となる |
難しいんだけど分かってもらえたかな?
条件が真の場合に実行されるのはわかったのだが、
偽の場合に実行させるにはどうすればよいだろう。
偽の場合だけ実行させるにはNOT演算子でいけるのだけど、
真の場合にある処理を実行し、
同時に偽の場合に別のものを実行。
そういうのを実現するにはelseを入れるんだ。
書く位置は真の場合の終わりカッコの後に書くんだよ。
つまり下記の感じだぞ。
if 条件 {
真の時に実行するもの
}
else {
偽の時に実行するもの
}
if命令の実行部分のカッコ内に
別のif命令を入れ子に(ネスト)することができる。
パッと想像しにくいだろうからサンプル書いてみるよ。
A = 1
B = 2
C = 3
if A = 1 {
mes "とりあえず変数Aは真"
if B > 1 {
mes "変数Bも真のようだ"
if C <= 3 {
mes "変数Cも真のようだ(結果として全てが真だった)"
}
else {
mes "変数Cだけ真でない"
}
}
else {
mes "変数Bは真でない(Cの判定はしていない)"
}
}
else {
mes "変数Aは真でない(B,Cの判定はしていない)"
}
stop
このネストは10重までしか使えない。
11重以上使おうとしてもhsed.exeのエラーとなる。
別エディターでもダメな所を見るとhspcmp.dllのエラーなのかな?
また、条件部のネストも可能だ。
A = 1
B = 3
C = 3
if A = 1 & (B = 2 | (C = 3)) {
mes "変数Aが1で、なおかつ変数Bが2または変数Cが3の時に実行"
}
stop
こうすることで複雑な条件が設けられる。
このネストは8重までしか利用できないぞ。
9重以上だと「カッコの記述が違う」というエラーになる。
ブレイスを使った1つ目の書き方はコレくらいでいいかな?
もう1つの書き方はif命令以外でも利用できるので
今のうちに絶対覚えておいてね。
さて、カッコを使わないもう1つの書き方とは…?
それは「:(コロン)」を利用するといったやり方。
どう違うのかと言うと1行に複数の処理が書ける。
マルチステートメントと呼ばれているよ。
variable = 5
if variable >= 3 : mes "1行で書くとスッキリするね"
stop
1行にたくさん書けるしelseも当然書けるよ。
var = "あ"
if var = "い" : mes "変数varには「い」が入っています" : else : mes "「い」以外の文字です"
stop
たくさん書くと見にくいだけだからほどほどにね。
一応if命令以外のものも書いておく。
mes "こんな風に書けるけど" : mes "みにくいだけだよね" : mes "2つの意味で" : stop
複数のif命令を1行で使う時はカッコを使おう。
var = 10
if var > 5 { if var < 50 { mes "OK" } else { mes "OUT"} } else { mes "OUT" }
stop
当然だけどプレイスもコロンも半角で書くんだよ?
何度も書くようだけど全角ではないので間違えないでね。
if命令はどんなに複雑な条件であっても
結果がどちらであるかだけを判断している。
つまり、if命令の条件に数値・変数だけで
条件式になっていなくてもいいわけだ。
たまに「if variable」と書かれたif文を見る。
コレは変数の値が0かそれ以外かだけを判断している。
a = 2
if a : mes "変数aは真(0以外)です" : else : mes "変数aは偽(0)です"
stop
初めに言っていたswitch命令に入ろうか。
言ってた様に付随の命令が多いけど頑張ってくれ。
switchと書いて「スイッチ」と読むんだよ。
「そのスイッチ押して」って言う時のスイッチと同じだ。
ホントはちょっと違うんだけどね…。
書式を書いてみると「switch 比較対象」となり、
バラメーター部には変数や式を書くことができる。
ああいうときに言うスイッチっていうのはON・OFFの2パターンしかない。
ココでは1つの比較対象を条件に多分岐させる。
case命令を使ってね。どうでもいいけどケースと読む。
「〜のケースは」って言うよね?「〜パターンは」って感じかな。
書式は「case 比較値」だ。
これでswitchの比較対象と一致する所を通過するよ。
switchの所で式を指定できるのだが、初めに言ったように
実際のcaseの所の範囲指定が出来ないぞ。
switch命令は5つで1セットと書きましたが、
最低限のものはswitch,case,swendの3つだけです。
…ってことで3つ目のswend命令を説明しサンプルを書いてみましょ。
switchの頭2文字とendを組み合わせたもので「スイッチの終わり」だ。
swend命令は簡単。
「swend」とパラメーターがなくswitch文の最後に書くだけ。
if命令でカッコを最初と最後につけたよね?
あれと同じ感じでココからココまでがswitch文というのを示す。
hensuu = "B"
switch hensuu
case "A" : mes "A"
case "B" : mes "B"
case "C" : mes "C"
swend
stop
一応聞いとくけど「文法が間違っている」となってないよね?
半角で書いてるのにエラーというパターンね。
2ページで書いたんだけど「HSP拡張マクロを使用する」って奴に
チェックが入っていないと使えないぞ。
上のサンプルを試せばcaseのBを通過しているのが分かると思う。
しかしcaseのCも通過しているようだ。
そう、実は比較値が真のところからswendまでが実行されるのだ。
これで使える時があるが使えない場合が多いだろう。
比較値が真のところだけ通るようにはできないだろうか?
それをするのが5つある命令の中のswbreakだ。
これもswitchとbreakを混ぜたもので「スイッチを抜ける」といった感じかな?
swbreak命令の書式も「swbreak」だけである。
hensuu = "う"
switch hensuu
case "あ"
mes "「あ」だけ通過"
swbreak
case "い"
mes "「い」だけ通過"
swbreak
case "う"
mes "「う」だけ通過"
swbreak
case "え"
mes "「え」だけ通過"
swbreak
case "お"
mes "「お」だけ通過"
swbreak
swend
stop
これで真のところだけ通過できたね。
真の場合はコレでいけたんだけど偽の場合、
つまりif命令で言う所のelseに当たるのはどうすれば…?
それをしてくれるのが最後のセット命令defaultだ。
デフォルト・初期といった意味で知られた命令だね。
default命令も「default」だけで他には書かない。
hensuu = 8
switch hensuu
case 0
mes "値は0でした"
swbreak
case 1
mes "値は0でした"
swbreak
case 2
mes "値は1でした"
swbreak
case 3
mes "値は2でした"
swbreak
default
mes "値は0〜3以外でした"
swbreak
swend
stop
e>
この様にdefaultは最後に書くのが普通である。
形的にはcaseで当てはまらなければ通過となっているが、
実際は比較対象が何であれ必ず通過する。
なのでcaseよりも先にあるとおかしい。
先にcaseを通してswbreakでswitch文を抜けよう。
言っておくがcase,default,swbreak,swend命令は
単体で使用することは出来ないぞ。セットで使う様にしよう。
このページの問題は次の通り。
| Q5 | ifを使い変数「X」が「3以下」の時だけ終了するプログラムを書け。 |
| Q6 | 下記のif構文をswith命令に書き直せ |
|
if X = 1 {
mes "1"
} else {
if X = 2 {
mes "2"
} else {
mes "1、2以外"
}
}
|