著者:だん
「これからプログラミングをはじめたい!」
「今までプログラムには興味があったけど難しそうでなかなか手を出せなかった……」
そんな人に Ruby のプログラミングを紹介します。
筆者はゲームプログラマー1 なので、簡単なゲームプログラムを作りながらプログラムの基本的な部分を連載形式で解説します。この連載では原則として Windows で Ruby を使うことを前提に解説します。 プログラミングははじめてだけど HTML くらいなら知っているというような、ある程度コンピュータを使い慣れている方が対象です。
:
プログラムはコンピュータを使う人にとって魔法です。その魔法は__○○○の血を引いた者にしか使うことのできない摩訶不思議な超能力__ではありません。決められたルールを覚えれば誰にでも唱えることのできる呪文です。
この呪文、つまりプログラムとはコンピュータを動かすために人間が作る命令のことです。この命令はコンピュータが理解する特別な言葉です。この言葉を「プログラム言語」といいます。
現在、より簡単で便利にプログラムが作れるようにたくさんのプログラム言語が開発されています。そして、Ruby もプログラム言語のひとつです。Ruby は__簡単に楽しく__プログラミングできることを目的として開発されました。
Ruby は、便利な機能がたくさんあって、いろいろな分野2で使うことができるとても強力なプログラム言語ですが、簡単な機能を使うだけでも十分にプログラミングを楽しむことができます。また、オブジェクト指向3を知らなくても大丈夫です。
Ruby はまつもと ゆきひろ氏が中心となって開発している__フリーソフトウェア__なので、誰でも無料で使用することができます。
Ruby のインストールにはさまざまな方法がありますが、ここでは One-Click Installer - Windows を使ったインストール方法を紹介します。 Windows 以外の OS にインストールする場合や他のインストール方法を試す場合は Ruby インストールガイドを参考にしてください。
RubyForge: Project Info- One-Click Ruby Installer のページからダウンロードすることができます。本稿執筆時点での最新版は 1.8.2-14_rc8 です。ここでは ruby182-14_RC8a.exe をダウンロードしたものとして話を進めます。
ダウンロードした ruby182-14_RC8a.exe を起動してください。英語のインストーラが立ち上がります。
Install を押すとインストールがスタートします。無事に終了したら Finish を押してインストーラを閉じます。これでインストールは完了です。
コマンド プロンプト を起動しましょう。Windows XP なら次の手順で起動することができます。
コマンド プロンプトが起動したらキーボードから、
と入力して Enter キーを押してください。
と表示されれば無事にインストールが完了しています。 以降ではコマンド プロンプトを使って Ruby のプログラムを実行することを前提に話を進めます。
コマンド プロンプトで動かす「文字の表示がメインのプログラム」は見た目が地味ですが、基本的な考え方は派手なグラフィックを扱うプログラムも__同じ__です。まずは簡単なプログラムでプログラミングの基礎をマスターしましょう。
プログラムを実行するにはプログラムが書かれたファイルを作成しなければなりません。 このプログラムが書かれたファイルのことを__ソースファイル__と呼びます。 ただ単に__ソース__と呼ぶこともあります。
ソースファイルはエディタ4というアプリケーションで作成します。 Windows には「メモ帳」というエディタがはじめから用意されています。プログラムのソースを書くにはあまり便利ではありませんが、今回はこれでも十分です。
ここでは C:\src というディレクトリ (フォルダ) 5にソースファイルを置くことにします。Cドライブのルートに src というディレクトリを作成してください。src は半角文字にしてください。
エディタ (メモ帳) を起動して次のように入力してください。必ず全ての文字を半角で入力してください。全角のスペースも使わないでください。アルファベットの大文字と小文字も区別されます。
入力し終わったらファイルを C:\src に hello.rb という名前で保存してください。
コマンド プロンプトを起動します。筆者の環境ではコマンド プロンプトを起動すると、このように表示されています。
まずは作業ディレクトリに移動します。ディレクトリの移動には cd コマンドを使います。
と入力して Enter を押してください。 cd とはチェンジディレクトリの意味です。ディレクトリを移動するとコマンド プロンプトに
と表示されるはずです。ではプログラムを実行しましょう。Ruby のプログラムはコマンド プロンプトから次のように入力することで実行できます。
次のように入力して hello.rb を実行しましょう。
画面に
と表示されればプログラムがうまく実行されたことになります。もし、
とエラーメッセージが表示されてしまった場合は、そこに hello.rb というファイルがないということです。もう一度手順やファイル名を確認してみましょう。
さっそく簡単なプログラムを作って実行してみましょう。
test.rb というファイルを作成し、次の一行を書き込んでください。
ファイルを作成したら
で実行してみましょう。実行すると「 __hello! __」という文字列が画面に表示されるはずです。この puts というのは文字を表示するための命令で Ruby ではこのような命令のことを__メソッド__といいます。
数字を表示することもできます。プログラムを次のように書き換えて実行してみましょう。
こんどは「 2004 」という数字が表示されたはずです。プログラム中に文字列を書く場合は ‘ (シングルコーテーション) で文字列を囲んでください。 数字は ‘ で囲まなくても OK です。
Ruby では日本語を表示することもできます。
ただし、プログラム中で日本語を使う場合、漢字コードを指定しないとプログラムが正しく動作しないことがあります。Windows では通常__シフト JIS (SJIS)__ という漢字コードが使われます。 シフト JIS を使用する場合は、Ruby のオプションに -Ks をつけることで Ruby の認識する漢字コードを指定できます。
漢字コードに EUC を使う場合は -Ke をつけます。UTF-8 を使う場合は -Ku をつけます。
プログラム中にコメントをつけるには # (シャープ) を使います。コメントはプログラムの実行には影響しないので、コメント機能を使うとプログラム中に好きな事を書き込むことができます。
Ruby では # から行末までがコメントになるので、このような書き方をすることもできます。
次に test.rb を次のように書き換えてください。
プログラムは上から順に実行されていきます。このプログラムを実行すると表示結果はこのようになります。
また、puts の代わりに print を使うと改行を行わずに文字を表示させることができます。print も文字を表示するメソッド (命令) です。
test.rb を書き換えてこのプログラムを実行してみましょう。
このように表示され、今度は改行されませんでした。
このテストプログラムは一瞬のうちに全てが表示されてしまいます。 このくらいの仕事は現代のコンピュータにとって朝飯前なのです。 そこで sleep というメソッドを使って一時的に流れを止めてみましょう。sleep 1 と書くとそこで 1 秒間プログラムが停止します。
このサンプルを実行すると「私は」「15」「歳です。」とそれぞれの文字列が 1 秒おきに表示されます。 sleep 1 の部分でプログラムの流れが 1 秒間止まっているのがわかると思います。 このようにプログラムは上から一行ずつ順番に実行されていきます。
; (セミコロン) で区切ると複数の行を一行にまとめることもできます。
このプログラムは先ほどのテストプログラムと全く同じように動作します。; で区切られたプログラムは左から順に実行されます。
さらに、このように全ての行を ; でつなげることもできます。
プログラムには流れがあります。どんなに大きなプログラムでも必ず流れがあり、一行ずつ (一文ずつ) 順番に実行されていきます。今回のサンプルは流れがひとつしかなく、このようなプログラムをシングルスレッド6と言います。Ruby では明示的にスレッド機能を使わない限り自動的にシングルスレッドのプログラムになります。
変数__はプログラムではとても重要な仕組みで、いろいろな場面で使用します。 ここでは数値や文字列の__データを入れることのできる箱7のようなものだと考えてください。
このプログラムでは、a という変数に 1 を、b という変数に 50 を入れています。この、変数にデータを入れる操作を__代入__と言います。
変数を puts や print 命令 (メソッド) に渡して内容を表示することもできま す。
変数にはもっと長い名前をつけることもできます。実際はその変数の中身を連想 できるような名前をつけて、プログラムがわかりやすくなるように工夫します。
変数名に使うことのできる文字はあらかじめ決められています。最もよく使 うローカル変数は先頭の文字をアルファベットの小文字にして、続く文字にはア ルファベットか数字かアンダースコアを使います。例えばこんな変数名を作るこ とができます。
これまでのテストプログラムに登場した puts 、print、sleep は__メソッド__と呼ばれます。 puts と print は文字を表示するメソッドです。 sleep はプログラムの実行を一時停止するメソッド8です。
メソッドの後ろに書くパラメータを__引数 (ひきすう) __といいます。puts メソッドでは引数に与える文字列や数字によっていろいろな表示を行うことができます。
テストプログラムではメソッドの後ろの () を省略していましたが、メソッドの引数は () で囲むこともできます。
sleep の引数はプログラムを停止させる秒数です。
:
プログラムの中では簡単に四則演算を行うことができます。次のプログラムを実行するとそれぞれの演算結果が表示されます。
演算と変数を組み合わせて使うこともできます。このプログラムでもそれぞれ puts の引数の演算結果が表示されます。
演算結果を変数に入れることもできます。
かけ算 (*)、わり算 (/) は 足し算 (+)、引き算 (-) よりも先に計算されます。次のプログラムを実行すると 30 が表示されます。
足し算を先に行いたい場合は () を使います。次のプログラムを実行すると (5 + 5) × 5 の計算結果の 50 が実行されます。
これまでは画面に文字を出力 (表示) するプログラムばかりだったので、今度はキーボードから文字を入力できるプログラムを作ってみましょう。
まずはこのプログラムを実行してみてください。実行したらキーボードから何か文字を入力して Enter キーを押してください。 Enter キーを押すと入力した文字列の下に同じ文字列が表示されたと思います。
今回のプログラムソースにはなにやら見慣れないコードがたくさん出てきましたが、落ち着いてひとつひとつ見ていきましょう。 まず、1 行目の = より右側に注目してください。
というコードがあります。 gets はコマンド プロンプトの端末から文字の入力を求めるメソッドです。 = より左側の input_value はただの変数です。とても偉そうな名前ですが、プログラムをわかりやすくするために格納するデータの内容を示した名前をつけてあります。もちろん input_value を a などの変数名に変えてもプログラムは同じように動作します。
入力された文字列は input_value という変数に代入されます。順序としてはまず gets が実行されて、そこで入力された文字列が input_value に渡されます。 このようなプログラムでは = の右側から実行され、その結果が左側の input_value に代入されます。
gets は文字列の入力処理を行い、入力された文字列を返すメソッドです。メソッドが返す値を__戻り値__といいます。メソッドの戻り値は = を使って変数に代入することができます。
2 行目は変数 input_value の中身をただ画面に表示しているだけですね。
ちょっと難しくなるのでここは読み飛ばして頂いても結構です。興味ある方は次 のプログラムを見てください。入力された数字を 2 倍して表示するプログラム です。
:
プログラムを実行したら、数字を入力して Enter キーを押してください。例え ば 100 と入力すれば 200 という数字が表示されると思います。
このプログラムは 2 行目で入力された文字列を数値 (整数) に変換しています。 変数の内容を数値として計算するにはデータが数値である必要があります。
表示された結果は__文字列__も__数値__も同じ文字列に見えますが、プログラム中では文 字列と数値は明確に区別されています。gets が返すデータ (戻り値) は文字列に なります。100 と入力しても input_value には必ず文字列の ‘100’ が代入され ます。
そこで 2 行目の
で文字列から整数を作り出しています。この to_i はメソッドです。文字列から 数値を作り出すメソッドです。
そして .(ドット) でつながれた to_i は input_value 、つまり ‘100’ という文 字列データに対する操作になります。 (何か文字列).to_i は、その文字列を整 数に変換して返すメソッドです。その戻り値が変数 num に代入されます。つまり、num は 100 になるわけです。
3 行目ではこの整数が格納された変数 num と 2 をかけ算して結果を表示してい ます。
ちなみに、こんな書き方もできます。次のプログラムも文字列と .to_i を使っ た例です。
少し複雑な話になってしまいましたが、慣れるとプログラムの流れが直感的に見 えてくるようになります。
はじめのサンプルプログラムはこのように書き換えることもできます。num を 省略してしまった形です。
input_value を省略してしまうこともできます。最初のプログラムはこの一行だ けでも全く同じ動作をします。
前に説明したとおりプログラムには流れがあります。プログラムにはその流れに変化を与えるための__制御構造__という仕組みがあります。制御構造を使ってプログラムの流れをコントロールしましょう。
if を使うとプログラムを分岐させることができます。プログラムを分岐させるには条件が必要です。 数値が代入されている変数 a があった場合、例えばこのような条件が指定できます。
これは if を使ったプログラムの例です。
このプログラムでは 2 行目で条件判断が行われます。このとき a の内容が 0 であれば 3 行目の puts メソッドが実行されます。 if 文では if の後に書かれた条件が成立したときだけ if と end に囲まれた部分9が実行されます。2 行目の条件の部分で a と 0 の間に == が使われています。 この == は a と 0 が__等しかったら__という意味を表す記号で__比較演算子__といいます。このプログラムでは1行目で a の中身には 0 がセットされているので if 文の条件が成立し、 3 行目が実行されます。比較演算子にはいくつか種類があります。
== | 等しい |
!= | 等しくない |
> | より大きい |
< | より小さい |
これは比較演算子に != を使ったプログラムです。
if 文では変数と変数を比べることもできます。
else を使うと if の条件が成立しなかった時の処理を実行することもできます。
このプログラムでは if の条件が成立しないので else と end にはさまれた puts が実行されます。
Ruby のループ処理にはいくつかの方法がありますが、ここでは while を紹介します。 次のプログラムは while を使ってループ処理を行うプログラムです。 2 行目から 5 行目までが while によるループ処理です。
書き方は if と同じです。 while の後ろに条件を書きます。while と対になる end も必要です。 ct はただの変数です。プログラムが実行されて処理が while の行まで来ると条件判定が行われます。条件が成立するとまず end の一行手前までが実行されます。プログラムの処理が end まで来るとプログラムの流れは while の行にジャンプします。そこでまた条件判定が行われ条件が成立していれば end 手前までの行が実行されます。そしてまた while の行までジャンプして条件判定が行われます。while の後ろの条件が成立している限りはこの繰り返しです。
4 行目にこのような処理があります。
この処理は変数 ct の内容を 1 加算するという意味です。ct には、はじめ 0 が代入されているのでここを通ると ct の内容は 0 に 1 が足されて 1 に変わります。次に通るときは 1 に 1 が足されるので ct の中身は 2 に変わります。また次に通るときにはさらに 1 が足されて ct が 3 に変わります。
while の条件は ct < 5 となっています。つまり ct が 5 より小さければ条件成立です。ct の内容はループする度に 1 ずつ加算されていき ct が 5 になったときに条件が成立しなくなります。するとプログラムは while の行から end の次の行へジャンプします。
次のプログラムでは条件が必ず成立するのでプログラムが終了しません。このようなループを無限ループといいます。 このプログラムを停止させるには Ctrl キーを押しながら C キーを押して Ruby を強制終了させてください。10
1 > 0 は必ず成立する条件です。これは 100 > 10 でも 5 == 5 でも OK です。また、必ず成立する条件を書く場合、普通は true を使います。
これも無限ループのプログラムです。
times はある決まった回数だけループさせたいときに便利なメソッドです。次のプログラムは 10 回の繰り返し処理を行います。
10 の部分には変数を書くこともできます。
これまでの知識を使ってじゃんけんゲームに挑戦します。 グー、チョキ、パーのいずれかを出してくる__じゃんけんロボット__とプレイヤーがじゃんけん対決をして、勝敗結果を表示するプログラムを作ってみましょう。
じゃんけんゲームを作る前に乱数という機能を説明します。 じゃんけんロボットはグー、チョキ、パーの三つのうちのどれかひとつを出してきます。 プログラムが実行されるまで何が出されるかわからないようにするために乱数を使用します。
これは 1 ? 6 の数値をランダムで画面に表示するプログラムです。rand(6) は 0 ? 5 の整数をランダムで返します。 rand の引数に1 以上の整数を与えると「 0 以上で __与えた引数 -1 __以下の整数」のいずれかの値が取得できます。
次のプログラムでは画面に 0 ? 19 の数値がランダムで表示されることになります。
ループを使えばさいころを 10 回繰り返して振ることもできます。
じゃんけんゲームを作る前にじゃんけんロボットを作ってみます。じゃんけんロボットはグー、チョキ、パーのいずれかを画面に表示するプログラムです。
puts 'じゃんけん'
sleep 1
r = rand(3) + 1
if r == 1
puts 'グー'
elsif r == 2
puts 'チョキ'
elsif r == 3
puts 'パー'
end
3 行目で変数 r に 1 か 2 か 3 のどれかの数字が代入されます。6 行目と 8 行目ではじめてみる elsif というコードがあります。これは 4 行目の if に対応していて 4 行目の if の条件が成立しなかった場合に elsif までプログラムの処理がジャンプしてきます。 elsif の行までくると if 文と同じようにここで条件判定が行われます。つまりこの if から end までの処理はこういう意味です。
整理するとこういうことです。
先ほどのじゃんけんロボットのプログラムは case 文を使って書くこともできます。
puts 'じゃんけん'
sleep 1
r = rand(3) + 1
case r
when 1 # r が 1 のとき
puts 'グー'
when 2 # r が 2 のとき
puts 'チョキ'
when 3 # r が 3 のとき
puts 'パー'
end
ひとつの同じ変数を何度も == で比較する場合は case 文を使ったほうが便利です。
以下が完成したじゃんけんプログラムです。
puts 'じゃんけんゲーム開始'
sleep 1
# プレイヤーのじゃんけん入力
puts '何を出しますか?'
puts '1 グー'
puts '2 チョキ'
puts '3 パー'
input_value = gets
# じゃんけんロボットの処理
robo = rand(3) + 1
case robo
when 1
puts 'ロボットはグーを出した!'
when 2
puts 'ロボットはチョキを出した!'
when 3
puts 'ロボットはパーを出した!'
end
# じゃんけん結果判定
player = input_value.to_i
case player
when 1
puts 'あなたはグーを出した!'
case robo
when 1 # ロボットがグーなら
puts '引き分けです'
when 2 # ロボットがチョキなら
puts 'あなたの勝ちです'
when 3 # ロボットがパーなら
puts 'あなたの負けです'
end
when 2
puts 'あなたはチョキを出した!'
case robo
when 1 # グー
puts 'あなたの負けです'
when 2 # チョキ
puts '引き分けです'
when 3 # パー
puts 'あなたの勝ちです'
end
when 3
puts 'あなたはパーを出した!'
case robo
when 1 # グー
puts 'あなたの勝ちです'
when 2 # チョキ
puts 'あなたの負けです'
when 3 # パー
puts '引き分けです'
end
else # どの when の条件も成立しなかったとき
puts 'あなたは何も出さなかった!'
puts 'あなたの負けです'
end
case 文の中に case 文が入っていることに注意してください。
55 行目の else は 24 行目の case に対応していて変数 player が 1、2、3 ではなかったときに else と end に囲まれた部分が実行されます。
最後に、今まで紹介した機能を使ってゲームブックプログラムを作ってみました。 まずはこのプログラムを実行してみてください。 選択肢が表示されたら数字を入力してから「Enter」を押してください。
scene = 'opening'
while true
case scene
when 'opening'
puts '3本の分かれ道があります。どの道を進みますか。'
puts " 1 左の道"
puts " 2 真ん中の道"
puts " 3 右の道"
input_value = gets
case input_value.to_i
when 1
scene = 'left'
when 2
scene = 'center'
when 3
scene = 'right'
end
when 'left'
puts 'あっ!'
sleep 1
puts '落とし穴に落ちてしまいました。'
puts '〜 GAME OVER 〜'
exit # プログラムを終了
when 'center'
puts '真ん中の道をまっすぐ歩いていくと……'
sleep 1
puts '宝箱をみつけました!'
puts " 1 そのままにしておく"
puts " 2 あける"
input_value = gets
case input_value.to_i
when 1
scene = 'leave'
when 2
scene = 'ending'
end
when 'right'
puts 'しばらく歩き続けると もとの場所にもどってしまいました。'
sleep 1
scene = 'opening'
when 'leave'
puts '宝箱には見向きもせず お家に帰りました。'
puts '〜 GAME OVER 〜'
exit # プログラムを終了
when 'ending'
puts 'パカッ'
sleep 1
puts 'まばゆい光があふれだす……'
sleep 1
puts '100枚の金貨を手に入れました!'
sleep 2
puts '〜 CONGRATULATIONS! 〜'
sleep 2
puts ' シナリオ だん'
sleep 2
puts ' プログラム だん'
sleep 2
puts ' 〜 END 〜'
exit # プログラムを終了
end
end
乱数を使っていないので、同じ選択肢を選べば毎回同じ結果になります。
exit はプログラムを終了させるメソッドです。
exit 以外はこれまでに紹介した機能しか使っていないのでじっくりソースを読んでみてください。 一行ずつ理解しながら読んでいけば頭の中でプログラムの流れをイメージすることができると思います。
読者のみなさんもこのプログラムを参考にゲームブックプログラムを是非作ってみてください11。乱数の機能を使えば新たなゲーム性をプラスすることもできるでしょう。
だん (dan at dgames dot jp)
ゲームメーカーに勤めるゲームクリエイター。
最近までずっとコンシューマーゲームソフトの開発という閉じた世界にいた。この春からこっち、オープンソースというものに興味を持ちはじめオープンソースで面白いゲームが作れないかと開発日記にて試行錯誤している。
プログラムを書いていることが多いのでそう言われますが、自分ではあくまでゲームデザイナーだと思っています! ↩
もちろんゲームだって作れます。 ↩
オブジェクト指向プログラミングとはプログラミング技法のひとつです。 ↩
エディタとはテキストファイルを編集するツールのことです。 ↩
ディレクトリとはフォルダのことです。 ↩
流れが複数あるプログラムはマルチスレッドと言います。 ↩
実はこのたとえは正確ではありません。 Ruby の世界では、複数の箱に同時に同じデータが入ることがあります。変数とはオブジェクトに付ける名札と言ってもいいかもしれません。 ↩
ここでは詳しい解説はしませんが、オブジェクト指向プログラミングにおいてメソッドとはデータに対する「手続き」のことを指します。 ↩
上のプログラムでは puts の前にスペースが挿入してありますが、これはプログラムを見やすくするためのものでインデント (字下げ) といいます。インデントをしなくてもプログラムは同じように動作します。 ↩
Windows の場合です。例えば Linux ならばターミナル画面で、Ctrl + D です。 ↩
このゲームを作るのに一番気を使ったのは sleep です。sleep のタイミングは何度もプログラムを実行しながら調整しました。微妙な数値で印象がガラリと変わってしまうからアプリケーションって不思議ですね。 ↩