超初心者が0からRPGを作る

ゲームプロデューサー志望が日々の悪戦苦闘を綴る。

生死を分かつはその一文【第伍歩】

好きな野菜はダントツでタマネギ、次点でネギのHeptagonDだ。

 

さて、今回は分岐反復について学んでいく。

 

なんでも、構造化定理とかいうものによると分岐反復、そして順次*1の3つの手段さえあれば、如何なるプログラムであろうと作り上げることが可能であるらしい。

つまり、今回の内容を頭にしっかり叩き込めば、何でもできる…というのは言い過ぎだが、理論上はどんなプログラムでも作ることができるということだ。

ということで、今回は普段以上に力を入れて学んでいくぞ。

 

 

【分岐、其れすなわち選択の因果】

まずは、条件によって処理を変える分岐だ。

人生は選択の連続 ー シェイクスピアハムレット王の台詞であるが、まさにこれがプログラムにおける分岐の形であろう。

RPGに例えると、プレイヤーは「体力が減ったから回復する」「勝てそうにないから逃げる」という選択をしている。

 

それと同じくして、ゲーム内部でも条件に応じて処理が選択されているのだ。

具体的には「体力が0になったから倒れる」「レベルが十分に達したので魔法を覚える」などが挙げられるな。

 

 この仕組みを支えるのが「if文」ないし「switch文」だ。

それぞれの構文を見ていく前に、if文に必要となる条件式の書き方を記しておく。

 

変数が条件に合うかどうかの判断には、関係演算子というものを使用する。

主な物は以下の通りだ。

 

 A == B     /  A != B

 AとBが等しい / AとBが等しくない

 

 A > B           /  A < B

AがBよりも大きい / AがBよりも小さい

 

 A >= B / A <= B

  AがB以上  /  AがB以下

 

 

基本的には上の通りで良いが…また引っ掛かった箇所があったのでノートをとっておく。

どうやらJavaでは文字列の条件のみ、 == ではなく特別な書き方をするようだ。

なぜこのようなややこしい仕組みになっているのか…とも思ったが、Javaの根幹の規則に則った結果こうなっているようなので従うほかあるまい。

その特別な書き方というのは以下の通りだ。

 

A.equals( B )

AとB、それぞれの文字列が等しい

 

 

さて、前置きが長くなってしまったな。それでは分岐の本文に入っていこう。

 

《if文》

if、和訳するならば「もし~であれば」といったところだろうか。

実際、if文でもまさにそのままの意味で使われている。

次のコードがif文の作りだ。

 

if ( 条件式 )

{

 条件が成立していたときの命令

}

else

{

 条件が成立していないときの命令

}

 

elseという語が出てきたが、こちらを和訳してみると「他」だ。

つまり、ここでは「ifではない、他の場合」と読み取れる。

 

要するにif文とは「条件が満たされていればifのブロック({と}の間)を、条件が満たされていなければelseのブロックを実行するのだ。

 

例えば、RPGにおいて攻撃が命中することを条件にしたとしよう。

すると、ifのブロックには命中した際の処理。

つまり、ダメージの計算やHPを減らす等の命令を書き込めば良い。

逆にelseのブロックはほとんど命令が必要ないな。

"ミス!"とでもテキストを出しておこうか…となるわけだ。

 

それでは、命中したとして防御されてしまったらどうだろう。

今度は、命中のif文の中に、さらに防御されたかどうかのif文を作成することになる。

このようにif文を上手く組み合わせることで、できることの幅が大きく広がるだろう。

 

 

それでは、仮に敵が8体いたとして、あなたは対象がランダムな単体攻撃を行ったとする。

すると、乱数によって8つのパターンが生まれる訳だが…まさかプログラムを8体分書くわけにはいくまい。

このような場合に役立つのがswitch文なのだ。

 

《switch文》

こちらの文はtrue/false*2の二択であるif文と異なり、三択以上の条件にも対応している。

早速そのコードを見てみよう。

 

switch ( 条件に使いたい変数の名前 )

{

 case A:

      変数の値がAの際の命令

      break;

 case B:

      変数の値がBの際の命令

      break;

 case C:

      変数の値がCの際の命令

      break;

        ︙

 default:

      変数の値がA、B、C、…のどれでもない際の命令

}

 

よくよく見てほしいのだが、case 〇の後ろについているのはセミコロン(;)ではなくコロン(:)だ。

間違えやすいと思われるので注意しよう。

また、break;の書き忘れもミスとして多いようだ。これを忘れると、次のcaseの命令も行ってしまうことになる。

逆にこのことを利用する猛者もいるそうだが…慣れないうちはしっかりbreak;することを習慣づけるのが良いだろう。

 

 

さて、分岐に関してはこのくらいで良いだろう。

尺も押しているので(!)、さっさと反復に移るとする。

 

 

【反復、その輪廻に終わりはあるか】

反復については繰り返し、ループの一言で説明がつくな。

もう少し踏み込むと、先程if文で扱ったような条件式を満たしている間命令を繰り返す、ということになる。

反復の構文は、大きく2つ。細かく分ければ3つだな。

まずは最も簡単な無印のwhile文から学んでいこう。

 

《while文》

早速コードを記載しよう。以下のコードがwhile文の基礎となる。

 

while ( 条件式 )

{

 反復する命令

}

 

これだけだ。簡単だろう?

しかし、反復には最大の敵がいることを覚えていてくれ。

それは、無限ループ

一度実行してしまったが最後、強制的にプログラムを終了させる他ないのだ。

 

無限ループとは少し違うが、RPGにおいて眠ってしまった場合について考えてみよう。

眠ってしまった場合、基本的には何も行動することができないだろう?

そのため、ターン終了時「一定確立で起きる」や「ダメージを受けると起きる」などの処理の記載が無い場合、そのキャラクターは延々と眠り続けてしまうのだ。

 

逆に言えば、いずれは必ず反復から抜け出すことができる命令がきちんとその反復の命令内に入っていれば、無限ループは恐れる相手ではないということだ。

 

 

《do-while文》

こちらはwhile文の亜種だ。コードは次の通り。

 

do

{

 反復する命令

}

while( 条件式 );

 

条件式が後に来ているな。

そう、do-while文条件式が満たされていようが満たされていまいが、一度は命令を実行してしまうのだ。

その後、条件式に合わせて反復するかどうかが判断される。

 

…果たして需要はあるのだろうか。

どうせ実行してしまうのであれば、順次でコードを書いてしまってからwhile文を使えば良いのではないか…

 

っと、書いている途中で気づいた。

while文でdo-while文を表現しようと思うと、コードを余分に書く必要があるのだな。

do-while文は必須ではないが、開発者が楽をするための構文だったのだ。

 

さて、残すところはあと1つ。もう少しだけお付き合い願いたい。

 

 

《for文》

こちらは条件の設定がやや厄介なため、慣れない内は暗記でも構わない。

が、もう暫し後に「配列」という物を勉強するのだが、それまでにはしっかりと理解しておいてほしい。

 

さて、コードは次のようになる。

 

for( int i = 0; i < 繰り返したい回数; i++ )

{

 反復する命令

}

 

見てわかったと思うが、for文はwhile文と違い、指定回数分反復させるための構文だ。

こちらもwhile文で再現可能だが、コードが長くなってしまうな。

 

さて、それではややこしくなっている()の中身について見ていこう。

 

 

int i = 0;

最初の一文はもう理解できるな?

そう、int型変数iを0として初期化している。

 

それでは、二文目。

i < 繰り返したい回数;

これは先程使用した条件式と同じだな。

 

三文目は…

i++

こちらは前回学んだインクリメント演算子だな。

iに+1していることになる。

 

 

つまり、流れはこうだ。

 

  1. int型変数iを宣言、0を代入
  2. i に1を足す
  3. iが指定数に届いていなければ反復

 のぉんど、おんごいこんとんじょのいこ

 

ゴホン、このことを応用すれば、さらに複雑怪奇な反復が実現できるが…

これはあまりにも複雑すぎるので、現状では使用機会はないだろう。

そのようなこともあったな、と後々思い出す程度で問題ないと思われる。

 

 

ところで、この変数i…上手く使ってやれば面白いと思ったのだが、そうはいかなかった。

 というのも、変数には寿命があることが原因なのだ。

変数の寿命は、宣言したブロックが終わるまで。

また、変数が宣言されてから寿命が尽きるまでの範囲をスコープというらしい。

 

ともかく、for文では少々特殊ではあるものの、int iの寿命はその反復条件の範囲でしか使えない、ということだ。

まぁ、for反復内に新たに変数を宣言し、+1していけば問題ないのだが。

 

 

さて、なんだかんだで分岐反復を押さえることができただろうか。

今回学んだことは非常に重要なため、今までの復習も兼ねて次回は適当なミニゲーム(のようなもの)を作ってみるぞ。

 

ここまでのお目通し、ご苦労であった。

また会えることを楽しみに待っているぞ。

 

…長い。今回は長い。1回でやる内容じゃなかった。

 

【次回はこちら】

机上に踊れ、小人形【第陸歩】 - 超初心者が0からRPGを作る

【前回はこちら】

傀儡の呪言を頭に刻め【第肆歩】 - 超初心者が0からRPGを作る

*1:分岐でも反復でもない、上から下へ進んでいく通常の進行

*2:プログラムにおけるYesNo