配列 12. 配列の技

このステージは特にクリア条件はありません。どこか一ヶ所でも変更すればクリア扱いになるようです。好きなようにコードを修正してみましょう。
以下、英文コメントの日本語訳だけ追加しておきます。

19、24、29行目のfor〜in文で、ループ内の一時変数名がどれもcoorとなっていますね。coordinateの略でしょう。別々のループで同じ変数名を使ってますが、それぞれの中で使い捨てなので構いません。ただしあるループの中で他のループをネスト(入れ子)する時は気をつけましょう。

配列 11. 違う方法で配列を作る

新規要素は2つ。

まず、今ステージ上にいる全キャラクターを配列に入れるメソッドです。world.allPossibleCoordinatesのキャラクター版といったところです。17行目まででブロックやキャラクターを条件に従って配置した後、20行目で、その時点の全キャラクターをcharactersという名前の配列を作って格納します。.existingCharacters()メソッド(existingは存在する、という意味)のパラメーターとして、allCordinatesを指定することで全マスが対象になるようですね。

そして、22行目でそのcharactersに入った個々のキャラクターについて、for〜in文を使ってアクションをさせます。このステージで新登場のメソッド、

  • danceLikeNoOneIsWatching()
  • turnUp()
  • breakItDown()
  • grumbleGrumble()
  • argh()

などが使えます。それぞれどんなアクションをしてくれるか試してみましょう。

その他、6行目は最初、列の値しかheightに入っていないので、コメント支持にあるように行の値も足すように書き換えましょう。

実行後はこんな状態になってると思います。

配列 10. ランダムな地形

新登場要素は、毎回ランダムな数字(乱数)を返すrandomInt関数です。

などとすると、randomNumber変数に、0から12までのうちのどれかの整数が入ります。プログラムを実行する度に毎回違った数字になるので、サイコロを振るなどゲーム的なアプリには欠かせない関数です。
このステージでは、7行目で.appendメソッドのパラメータとして使っています。前後のfor文で20回繰り返されるので、9行目の時点でheights配列には0〜12の中のどれかの数字が20個入っていることになります。続くループの中で、これを先頭から取り出し、積み上げるブロックの高さとして利用しているのです。前ステージ同様、コマが20個目以降になるとindexがheights配列がもっている要素数を超えて範囲外エラーになってしまうので、12-14行目のif文で0に戻しています。

ステージとしては、何か所かあるコメント文の下に、その条件に当てはまるコマの時になにかしらの処理(world.place()的なこと)をしろとあります。自分のセンスで好きな処理を書きましょう。また40行目のところには、if文の条件そのものを自分で決めてなにか処理を追加しましょう(以下のコードでは書いてありません)。

上記のコードの実行結果はこんな感じになります。ただし乱数を使っているので、実行する度に各コマの高さが変わり、毎回違った風景になるでしょう。

配列 9. 地形を作る

これまたややこしいコードですが、indexという変数を増やしていくことで、heights配列に入れた適当な数字を順番に先頭から使っていきます。ここではわかりやすくする為に、3,4,5と3つだけの数字をセットしておきます。つまり、heights[0]が3、heights[1]が4、heights[2]が5ということになります。この数字だけ12行目のfor文で繰り返されるので、ブロックの積まれる高さが、3個、4個、5個と増えていき、3つ使い切ると、9〜11行目のif文でindexが0に戻り、また3個になり以降、3,4,5,3,4,5,3,4,5…と繰り返されます。

完成写真はこちら。

1行目の3,4,5を変えてみると出来上がる景色もかわります。数が3つでなくても大丈夫です。9行目でheights.countで個数を調べて上限値を決めているからです。これがもし、

だったら最初の3つしか使われないことになります。3,4,5なら問題ありませんが、もし7,3,1,4にしても4が使われないままになります。5,1にしてしまったら数が足りなくてエラーになります。heights.countでその都度調べているので、1行目にいくつの数字をセットしても柔軟に対応できるわけです。

[2,5,1,7,4]に変えてみるとこんな形になります。

配列 8. 配列の範囲外エラーを直す

配列の真骨頂、番号によるアクセスについて説明されています。今までも複数のキャラクターを作る時、名前にexpert1、expert2と通し番号をつけたことはありましたが、配列を使ってその番号を指定すると、for文などで繰り返すのに非常に便利になります(このステージではまだその恩恵はありませんが)。
今回は、for文で1〜9繰り返して.appendメソッドでteamBlu配列の中にBlu型のインスタンスを誕生させています。ここで非常に重要なのは、配列の通し番号は0から数えるという点です。for文に1〜9と書いているので、[1]〜[9]となると思いがちですがそうではありません。このコードだと9つのBlu型インスタンスがteamBlu配列内にできますが、その指定方法はteamBlu[0]〜teamBlu[8]となります。
それを踏まえて19行目以降をみると、最後の24行目でteamBlu[10]という背番号を指定しています。存在しない番号を読んでしまうと、そのプログラムは即クラッシュしてしまう深刻なバグとなります。行ごと削除してしますか、[0]〜[8]の範囲内に数字を変更してやればエラーは消えます。

ちなみに、今までエラーがあった場所はコードの行頭に赤丸がついて教えてくれました。しかしここではそうならず、実行してその行を処理しようとした瞬間にエラーとなりコードの実行が停止します。これは配列の中身の数が実際に実行してその行を処理する瞬間になってみないと10あるかないかわからないからです。まぁ、この例ではわからなくもないですが、例えばユーザがボタンを押す度に新しいキャラクターが生まれるようなプログラムを作った場合、いつどのタイミングでキャラクター数がいくつになるかは事前には予測できません。

という一行そのものは文法としてなにもおかしいところはないので、書いただけの時点でエラー判定して赤丸で教えることはできないのです。こういう実行してみないとわからないエラーは非常に発見が難しく、色々なパターンで検証しなければならず、それが足りないと、リリースした後でクラッシュしてしまうアプリとして問題になるのです。