Ruby で創る RPG 第十章 勇者がコマンドを選び直せるようにする
Ruby で創る RPG
十四歳のお誕生日のお祝いにとMacBook Air を贈られた 未來(みらい)。
憧れの遙香(はるか)お姉様から、プログラミングを教えてもらえることに。
コンピュータの仕組みを学ぶところから始まり、RPG(ロールプレイングゲーム)を創り上げてます。
本日は配列を学ぶことに。
毎週木曜日の掲載予定です。お楽しみに。
配列の基礎を学ぶ
「とてもよくできたわね。 勇者が攻撃するか回復するか逃走するか選べるようになったのね。」
「うん、そうなんだ。そしてね、勇者が回復しなくちゃいけないところで、間違えて攻撃しちゃったり、逃げ出しちゃったりするとやり直しが聞かないんだけれど、どうしたらいいのかな?」
「そうね。そうすると、コマンド選択を繰り返すことができるようにすると良いわね。」
「うん、そうだね。どうやったらできるの?」
「そうね〜、みっくんはどうやったらできると思う?」
「もう一回繰り返しを入れるといいのかな〜」
「そうね。ひとまずそれでやってみましょうか。RPGのプログラムもだいぶ長くなってきたので、前回同様、小さなプログラムで練習していきましょう。」
「うん、そうだね。」
「まず、コマンドメニューの表示のところだけれど、こんな感じで書いていたわよね。」
# コマンドを表示する
puts "1: 攻撃"
puts "2: 回復"
puts "3: 逃走"
「うん、そうだよ。」
「前にも少し話したけれども、こういった時に配列を使うととても簡単に描けるようになるわ。」
「そうなんだね。配列ってどうやって書くの?」
「** 配列は、複数のデータを順番に並べたデータ構造・入れ物**って、紹介したけれど、Ruby
の場合だと、配列はこんな感じで書くわ。」
menus = ["攻撃", "回復", "逃走"]
puts menus[0]
puts menus[1]
puts menus[2]
「配列は、複数のデータを順番に並べたデータ構造・入れ物ってあるけれど、入れ物の中に入っているそれぞれのデータが"攻撃"
、"回復"
、"逃走"
っていう三つの文字列ね。で、これらが一緒になっている入れ物、配列を作るためには []
で囲むと、配列ができるというのが、Ruby
の文法よ。」
「そうなんだね。なので["攻撃", "回復", "逃走"]
って書くと、三つの文字列が一緒になった配列ができるんだね。」
「ええ、そうよ。」
「そして、配列を作ったので、後からいろいろ使うのが便利なように、menus
っていう変数に代入しているんだね。」
「ええ、その通り。」
「で、次の行なんだけれど、puts
は画面に表示する命令だったよね。その後のmenus[0]
というのは何?」
「これね、配列の中に入っているそれぞれのデータのことを、要素と言うふうに言ったりもするんだけれど、0番目の要素って言う意味よ。」
「0番目の要素?」
「ええ、あたしたちが話している日本語の世界だと、一番目、二番目という風にいうけれど、コンピュータの世界では、最初の要素を指し示す時に、0番目っていうことも良くあるわ。」
「そうなんだね。じゃあ、これは配列の最初の要素のことだから、"攻撃"
って表示されるってことだね。」
「ええ、その通り。」
「じゃあ、puts menus[1]
で"回復"
が、puts menus[2]
で"逃走"
が表示されるんだね。」
「ええ、そうよ。」
「配列は、array
っていうから、array.rb
って名前のファイルを作りましょう。ruby array.rb
ってすると実行できるわ。」
「うん。やって見る」
「どう、実行できたかしら。」
「うん、できたよ。」
irb (Interactive Ruby) で練習する
「さて今までは、新規作成してコードを書いて実行してきたけれども、Ruby
には、irb
という手軽にコードを実行できる機能があるの。ターミナル画面から、Command + N
を押すと別のウィンドが開けるの。Command
キーとN
を一緒に押すのね。やってみて。」
「うん、もう一つ別のウィンドウが開いたよ。」
「ええ、開いたら 今の時刻などメッセージが表示されていると思うけれど、clear
ってタイプすると、画面の表示を消してスッキリすることができるわ。」
「うん、何も表示されなくなってスッキリしたよ。」
「そしたら、irb
ってタイプするの。」
「うん、入れて見る。」
「どうかしら。立ち上がったみたいね。これがirb
の画面。左端に表示されているのがプロンプトって呼ばれる画面よ。」
「そうなんだね。プロンプトってなに?」
「プロンプトは、促すっていう意味なんだけれど、これからいろいろ入力してねって、促してくれているのね。irb
は Interactive Ruby の 略なんだけれど、その名の通り、対話的に双方向で簡単なRuby
のコードを入力して結果を見ることができるわ。早速やってみましょうか。」
「うん。」
配列を作成する
「じゃあ、menus = ["攻撃", "回復", "逃走"]
って入れて、エンターキーを押してね。」
「うん、エンターを押したよ。」
「["攻撃", "回復", "逃走"]
って表示されたわよね。」
「うん」
「じゃあ、次にmenus[0]
って入れてみて。」
「うん。"攻撃"
って表示されたよ。」
「ええ、irb
が、応答を返してくれるの。最初の例だと menus = ["攻撃", "回復", "逃走"]
を実行した結果を、次の例だと menus[0]
が返ってくるの。これが Interactive 対話 っていう意味よ。」
「puts menus[0]
って書かなくても、menus[0]
だけでいいんだね。」
「そうね。変数の値を知るだけなら、menus
やmenus[0]
と直接、変数名を入力するだけで良いから、簡単よね。」
「うん、そうだね。」
「ファイルを作って、実行させてっていう手間もないから、ちょっとした結果を知るにはとっても便利よ。」
「そうだね。」
「短いコードなら直接irb
に打ち込んだらいいし、ちょっと長いコードを試したい時には、今使っているpulsar
エディタの上で入力してコピーしたのを、irb
に貼り付けるようにすると楽だわ。」
「うん、わかったよ。」
「じゃぁ、練習を兼ねて、このままirb
上で配列についていろいろ学んでいきましょう。」
「うん。」
配列要素の追加
「配列への要素の追加は、いろいろな方法があるわ。配列の添字を使ってmenus[5] = "魔法"
なんてする方法もあるの。やってみて。」
「うん、やって見る。」
「どのように配列に追加されたか見たかったら、menus
ってすると、見ることができるわ。」
「うん、"魔法"
が追加されているよ。この間にある nil
っていうのは何?」
「nil
は、ラテン語由来なんだけれど、何もない を表しているの。数で言ったら0に相当するわ。お皿の上に林檎が三つあることを、3
と書くわよね。」
「うん、そうだよ。」
「じゃあ、お皿の上に全くりんごがなかったら?」
「うん、0
だよ。」
「ええ、それと一緒で、配列は複数のデータを格納できるデータ構造・入れ物って紹介したけれど、そこには何も要素がない、データがないということを示しているのが、nil
なの。」
「そうなんだね。ええ、林檎がないことを0
という数を使って表したように、オブジェクトが存在しないことを表すのがnil
よ。」
「そうなんだね。」
「ちなみに、今は配列の要素として、文字列を追加しているけれど、数を一緒にすることもできるわ。」
「そうなの。」
「ええ、じゃあ、menus[6] = 6
なんてやってみましょうか。」
「うん、やって見るよ。」
「配列に6
が追加されたかどうかみてみましょう。もう一度 menus
って入力すれば良いの。」
「うん、6
も表示されているよ。」
「他の言語だと、配列の中に入れられるのは同じ種類だけ、数字用の配列、文字列用の配列なんてしなくちゃいけなかったりするけれど、ここでもRuby
はとっても柔軟でいいわね。」
配列要素の取得
「配列の要素を取得するには、添字というのだけれど、何番目の要素を取得したいのか、番号でしていするのが簡単だわ。0番目、1番目、2番目の要素を取得するために、menus[0]
、menus[1]
、menus[2]
って書けばいいの。」
「うん、そうだね。」
「他にも最後の要素を指定したかったら、menus[-1]
なんて指定方法もあるわ。負の数の添字を使うと最後の要素から数えてくれるわ。」
「すごい、便利だね。」
「ええ、プログラマが楽しくコーディングできるよう、柔軟性に富んでいるところがRuby
の良いところよね。」
配列要素の更新
「要素の更新も簡単に行えるわ。menus[0] = "物理攻撃"
、menus[1] = "魔法"
って感じで書くの。」
「うん、やって見る。」
「どう? menus
ってすると、確認できるわ。」
「うん、更新できたよ。簡単だね。」
「ええ、そうね。ちなみに"魔法"
っていう要素が二つあるけれど、同じ要素が二つできてもOKよ。」
配列要素の更新
「じゃあ、最後は要素の削除をしましょう。」
「うん」
「要素の削除には二通りの方法があるわ。1つは添地で添事を指定して削除する方法、もう一つは値を削除して値を指定して削除する方法よ。」
「そうなんだね。」
「ええ、順番に見ていきましょう。」
「delete_at
メソッドを使うと、指定した位置にある要素を削除できるわ。menus[6] = 6
って書いて、要素を追加したじゃない。この追加した要素を削除してみましょう。」
「うん、どうやるの?」
「menus.delete_at(6)
で、削除できるわ。やってみて」
「うん。menus
ってタイプして配列の要素を確認してみたけれど、最後の要素が消えているね。」
「ええ。添字を指定して要素を削除することができるの。」
「じゃあ、もう一つの方法は?」
「値を指定して削除することができるわ。魔法
が二つあるので、これを消すことにしてみましょうか。」
「うん」
「menus.delete("魔法")
って入力してみて。」
「うん、やって見る。」
「お〜、二つ消えているね。」
配列の要素数を取得する
「ということで、配列の要素数が、4つになっているわね。」
「うん、そうだね。」
「配列の要素数を数えるには、size
またはlength
メソッドを使うといいわ。」
「どっちでもいいの?」
「ええ、どちらでもいいの。配列の大きさだからsize
、配列の長さだからlength
どちらも自然よね。なので、どちらを使ってもいいように別名(alias)として定義されているの。」
「そうなんだね。」
「どちらも4
と返ってくるはずよ。やってみて。」
「うん」
irb を終了する
「それでは配列の作り方、要素の追加・取得・更新・削除、要素数を学んだところで、irb
を終了してみましょう。終了するには、exit
コマンドで終了できるわ。やってみて。」
「うん、終了できたよ。」
「ええ、対話的に簡単にRuby
のコードを実行できるのがirb
の良いところよ。ちょっと動作を確認したいなって時にも重宝するわ。どんどん活用していってね。」
学習した内容
irb
# 配列を作成する
menus = ["攻撃", "回復", "逃走"]
menus[0]
menus[5] = "魔法"
menus
menus[6] = 6
menus
menus[0] = "物理攻撃"
menus[1] = "魔法"
menus
menus.delete_at(6)
menus
menus.delete("魔法")
menus
menus.size
menus.length
exit
実行結果
配列と繰り返し
「配列の基礎も学んだわね。」
「うん。こんなふうに書けば表示できるんだったよね。」
menus = ["攻撃", "回復", "逃走"]
puts menus[0]
puts menus[1]
puts menus[2]
「ええ、そうよ。そしてね、Ruby
には配列を使った繰り返しが簡単にできる、素敵なメソッドも用意されているの。」
「そうなの。どんなふうに使うの?」
「each
メソッドというのがそれよ。こんな風に書くといいわ。」
menus = ["攻撃", "回復", "逃走"]
menus.each do |menu|
puts menu
end
「each
はそれぞれっていう意味なんだけれど、その名の通り、menus
っていう配列の先頭から順番にそれぞれの要素を取り出してくれるの。do
から始まってend
までで囲まれている部分をブロックっていうけれど、配列から取り出したそれぞれの要素はmenu
っていう ブロック変数 に入るの。ブロックパラメタとも行ったりするわ。なので、menu
には、最初は "攻撃"
が入っているから、puts "攻撃"
となって、"攻撃"
が表示されて、次は "回復"
が入っているから、puts "回復"
となって、"回復"
が表示されて、最後は "逃走"
が入っているから、puts "逃走"
となって、"逃走"
が表示されることになるわ。」
「そうなんだね。」
「もし100個の要素がある配列だとしたら、puts menus[0] puts menus[1] puts menus[2] ... puts menus[99]
なんて書いていられないもの。」
「うん、そうだね。100個も書くのはとっても大変そう。」
「あ、そして、これはちょっとしたポイントなんだけれど、配列名は複数形、ブロック変数は単数形 で命名するのがおすすめよ。複数形になっていると、たくさんの要素を中に持っている入れ物なんだなって、目印になって、コードを読む時の理解を助けてくれるわ。」
「うん、複数形にするんだね。わかったよ。」
「ええ、そして、ここでは、配列をmenus
って変数に代入してから使ったけれど、配列だけでコードを書くこともできるわ。」
["攻撃", "回復", "逃走"].each do |menu|
puts menu
end
「あとから、配列を特に使わないのであれば、もっと簡潔に書けるこちらの書き方もおすすめね。」
「うん。」
配列と繰り返し、添え字も添えて
「最初にやった時のように、番号をつけるにはどうするの?」
# コマンドを表示する
puts "1: 攻撃"
puts "2: 回復"
puts "3: 逃走"
「each
メソッドに続けてwith_index
メソッドを使うといいわ。こんな風に書くの。」
["攻撃", "回復", "逃走"].each.with_index do |menu, index|
puts "#{index}: #{menu}"
end
「もし 1
から始めたかったら、こんな感じね。」
["攻撃", "回復", "逃走"].each.with_index(1) do |menu, index|
puts "#{index}: #{menu}"
end
実行結果
「each
メソッドに続けて、.
を入れてwith_index
メソッドで繋げるの。前にも話したけれど、メソッドチェーンがここでも使われているのよ。」
習得したい基本的なショートカット
「さて、irb
での実行例を出したけれど、irb
やターミナル画面での入力は、何度も同じコマンドを入力することがよくあるわ。もちろん同じコマンドは何度も入力しても良いのだけれど、ちょっと手間と感じることもあるわよね。そういった時のために、履歴を活用する方法もあるわ。」
「そうなんだね。どうやってやるの?」
「簡単な上矢印キー↑を押すということなんだけれど。やってみて。」
「あ、ほんとだね。前に入れたコマンドを覚えているんだね。」
「ええ、そうよ。入力したいコマンドのところにたどり着いたら、そのままエンターキーを押せばいいわ。修正もできるから、バックスペースで消したりして試してみてね。」
「うん、やってみる。」
「戻り過ぎた時は下矢印キー↓を押せばいいわ。」
「ありがとう。」
「ということで、カーソルキーを使って履歴を移動する方法だったわ。 そしてね、ちょっとキーボードのホームポジションから離れたところにあるじゃない。」
「うん、そうだね。」
「だからね、なるべくなら指はポジションに置いたまま、操作したいわ。」
「うん、そうだね。」
「だからね。ショートカットキーって呼ばれるんだけれど、カーソル移動のためのショートカットキーも用意されているの。」
「そうなんだね。」
「ええ、例えば、次のような感じよ。」
ショートカットキーの表記
名前 | 記号 |
---|---|
Control | ^ |
Shift | ⇧ |
Command | ⌘ |
Option | ⌥ |
カーソル移動
キーバインド | 動作 | 意味 |
---|---|---|
Ctrl + F | カーソルを右へ移動 | Forward 先へ進んで |
Ctrl + B | カーソルを左へ移動 | Backward 後方へ |
Ctrl + P | カーソルを上へ移動 | Previous 以前の行へ |
Ctrl + N | カーソルを下へ移動 | Next 次の行へ |
Ctrl + A | カーソルを行頭へ移動 | Ahead 前方へ |
Ctrl + E | カーソルを行末へ移動 | End 行末へ |
「カーソルを上に移動する代わりにCtrl + P
を押せばいいのよ。あ、Ctrl
キーとP
キーを一緒に押すことを、Ctrl + P
って書くわ。Ctrl
キーは、左の小指の横にあるし、P
の位置はもうみっくん、覚えているわよね。」
「うん、もう体が覚えているよ。毎日こつこつ見ないでタイプできるよう、練習したんだ。」
「みっくん、えらいわ。練習したのね。」
と、お姉様が褒めてくれる。
「他にも良く使うショートカットキーを紹介するから、是非習得してね。」
入力ソース切替
キーバインド | 動作 |
---|---|
Ctrl + Space | 日本語入力と英数入力を切替 |
ファイル操作
キーバインド | 動作 | 意味 |
---|---|---|
Command + O | ファイルを開く | Open 開く |
Command + S | ファイルを保存する | Save 保存する |
テキスト編集
キーバインド | 動作 | 意味 |
---|---|---|
Command + Z | 元に戻す | |
Command + X | 切り取り | |
Command + C | コピー | Copy |
Command + V | 貼付 | |
Command + A | 全選択 | All |
Ctrl + H | カーソルの左の文字を削除 | |
Ctrl + D | カーソルの右の文字を削除 | Delete |
Ctrl + K | カーソル以降を切り取り | Kill line |
Ctrl + T | カーソル前後の文字を入替 | Transpose 転置 |
Pulsarエディタの基本操作
キーバインド | 動作 | 意味 |
---|---|---|
Shift + Command + D | 行の複製 | Duplicate |
Shift + Ctrl + K | 行の削除 | Kill line |
Command + / | コメントアウト | |
Ctrl + F | 検索(ファイル内) | Find 見つけ出す |
Shift + Ctrl + F | 検索(プロジェクト内) | Find 見つけ出す |
Ctrl + G | 任意行へカーソルを移動 | Go |
Command + ] | インデントを追加 | |
Command + [ | インデントを削除 | |
Command + K → | 画面分割 | |
Command + W | 画面を閉じる | Window close |
Shift + Ctrl + P | コマンドパレット | Pallet |
Shift + Command + C | 色を選択 | pigments |
「じゃあ、次回は、今学んだ配列を使って、勇者がコマンド選択をやり直せるように作っていきましょうか。」
「うん、そうだね。 今日もいろいろ学べてよかったです。」
「こちらこそ。みっくんと楽しくお話しできて嬉しかったわ。」
そう言って、夕日と共にお姉さまは去っていく。
コンピュータは現代の魔法使い。
世界を救う勇者のように、いつか僕もすごいプログラムを作ってみたいなー。
そう、僕はワクワクしながら眠りについた。。。
Discussion