プログラミング入門(1)

下記のページを参考にプログラミングの勉強を始めます。
Rubyist Magazine - Ruby ではじめるプログラミング 【第 1 回】

初めてのプログラム


ソースファイルを作成


Cドライブのルートにsrcというフォルダを作成する。(C:\srcというディレクトリを作成する。)
エディタ(メモ帳)を起動して、下記のように入力する。ただし、すべて半角文字で入力する。大文字小文字も区別される。

puts 'hello world'

入力したファイルをC:\srcにhello.rbという名前で保存する。

実行


コマンドプロンプトを起動する。
cdコマンド(チェンジディレクトリ)でC:\srcに移動する。

cd C:\src

Rubyプログラムはコマンドプロンプトから次のように入力することで実行できる。

ruby ソースファイル名

ここでは、下記のように入力して実行する。

ruby hello.rb

画面にhello world と表示されれば上手く実行されたことになる。
f:id:ayaketan:20111207195913j:image

基礎


文字を表示する


test.rbというファイルを作成し、下記の1行を書き込む。

puts 'hello!'

ファイルを作成したら下記のコマンドで実行する。

ruby test.rb

実行すると、「hello!」という文字列が画面に表示される。
このputsは文字を表示するための命令で、Rubyではこのような命令のことをメソッドという。
数字を表示することもできる。
プログラムを下記のように書き換えて実行する。

puts 2004

今度は「2004」という数字が表示された。
プログラム中に文字列を書く場合は'(シングルコーテーション)で文字を囲む。
数字は囲まなくてもよいい。
f:id:ayaketan:20111207194046j:image

日本語の表示


Rubyでは日本語を表示することもできる。

puts '日本語を表示します'

ただし、プログラム中で日本語を使う場合、漢字コードを指定しないとプログラムが正しく動作しないことがある。
Windowsでは通常シフトJISSJIS)という漢字コードが使われる。
シフトJISを使用する場合は、Rubyのオプションに-KsをつけることでRubyの認識する漢字コードを指定できる。

ruby -Ks test.rb

なお、漢字コードにEUCを使う場合は-Ke、UTF-8を使う場合は-Kuをつける。
f:id:ayaketan:20111207194143j:image

コメントをつける


プログラム内にコメントをつけるには#(シャープ)を使う。
コメントはプログラムの実行に影響しないので、プログラム中に好きなことを書き込むことができる。

 # このプログラムは画面に2004を表示します
 puts 2004

Rubyでは#から行末までがコメントになるので、下記のような書き方もできる。

puts 2004 # は画面に2004を表示します

f:id:ayaketan:20111207194220j:image

プログラムの流れ


test.rbを下記のように書き換える。

puts 1
puts 2
puts 3

プログラムは上から順に実行されていくので、このプログラムを実行すると表示結果は次のようになります。
f:id:ayaketan:20111207194259j:image
また、putsの代わりにprintを使うと改行を行わずに文字を表示させることができる。

print '今は'
print 11
print '時です。'

このプログラムを実行すると、下図のように改行されない。
f:id:ayaketan:20111207194327j:image
このテストプログラムは一瞬のうちにすべて表示されてしまうので、sleepというメソッドを使って一時的に流れを止めてみる。
sleep 1と書くと、そこで1秒間プログラムが停止します。

print '私は'
sleep 1
print 15
sleep 1
print '歳です。'

f:id:ayaketan:20111207194406j:image
このサンプルを実行すると、「私は」「15」「歳です。」とそれぞれの文字が1秒置きに表示された。
プログラムは上から1行ずつ順番に実行されている。
;(セミコロン)で区切ると複数の行を1行にまとめることができます。

print '私は'     ; sleep 1
print 15         ; sleep 1
print '歳です。'

f:id:ayaketan:20111207194406j:image
このプログラムは先ほどのプログラムと同じようの動作した。
;で区切られたプログラムは左から順に実行される。
さらに、下記のようにすべての行をつなげることもできる。

print '私は' ; sleep 1 ; print 15 ; sleep 1 ; print '歳です。'

f:id:ayaketan:20111207194406j:image
プログラムには流れがあり、1行ずつ(1文)ずつ順番に実行されていく。

変数


変数は数値や文字列のデータを入れることのできる箱のようなもの。
変数をputsやprintメソッドに渡して内容を表示することもできる。

a = 1
s = 'こんにちは'
puts a # 1 を表示
puts s # こんにちは を表示

f:id:ayaketan:20111207194508j:image
変数にはもっと長い名前を付けることもでき、実際はその変数の中身を連想できるような名前を付けて、プログラムがわかりやすくなるよう工夫する。

length = 25
message = ' 南に行くと洞窟があるよ'
print length
puts message

f:id:ayaketan:20111207194532j:image
変数名には通常頭文字をアルファベットの小文字にして、続く文字にはアルファベットか数字かアンダースコアを使う。

メソッドと引数


これまでに登場したputs、print、sleepはメソッドと呼ばれ、メソッドの後ろに書くパラメータを引数という。
テストプログラムではメソッドの後ろの()を省略していましたが、引数は()で囲むこともできます。

puts 'おはようございます'
puts 100
puts('おはようございます')
puts(100)

f:id:ayaketan:20111207194605j:image

演算


プログラムの中では簡単に四則演算を行うことができる。

puts 5 + 5 # 足し算
puts 5 - 5 # 引き算
puts 5 * 5 # かけ算
puts 5 / 5 # わり算

f:id:ayaketan:20111207194654j:image
下記のように演算と変数を組み合わせて使うこともできる。

a = 3
b = 2
puts a + b
puts a - b
puts a * b + 5

f:id:ayaketan:20111207194716j:image
下記のように演算結果を変数に入れることもできる。

a = 5 + 3
b = a * 2
c = a + b
puts c

f:id:ayaketan:20111207194820j:image
かけ算(*)、わり算(/)は足し算(+)、引き算(-)よりも先に計算される。

puts 5 + 5 * 5

f:id:ayaketan:20111207194840j:image
足し算を先に行いたい場合は、()を使う。

puts (5 + 5) * 5

f:id:ayaketan:20111207194856j:image

文字を入力する


今度はキーボードから文字を入力できるプログラムを作る。
下記のプログラムを実行する。

input_value = gets
puts input_value

実行したら、キーボードから文字をと入力し、ENTERを押すと入力した文字列の下に同じ文字列が表示される。
私はtestと入力したので、testが表示された。
f:id:ayaketan:20111207194930j:image
1行目の=より右側にあるgetsはコマンドプロンプトの端末から文字の入力を求めるメソッド。
=より左側のinput_valueは変数。
getsは文字列の入力処理を行い、入力された文字列を返すメソッド。
メソッドが返す値を戻り値という。
メソッドの戻り値は=を使って変数に代入することができる。

入力された文字列を数値にして2倍する


下記のプログラムを実行する。

input_value = gets
num = input_value.to_i
puts num * 2

実行したら数値を入力してENTERを押下すると、下に2倍の数値が表示される。
私は100を入力したので、200が表示された。
f:id:ayaketan:20111207194950j:image
getsの戻り値は文字列で、to_iは文字列から数値を作り出すメソッド。
1行目でgetsから文字列'100'がinput_valueに代入される。
2行目でinput_value.to_iで変換された数値100がnumに代入される。
3行目で変数numと2をかけ算して200という結果が得られた。

はじめのサンプルプログラムはnumを省略して次のように書き換えることもできる。

input_value = gets
puts input_value.to_i * 2

f:id:ayaketan:20111207194950j:image
さらにinput_valueも省略することもできる。

puts gets.to_i * 2

f:id:ayaketan:20111207194950j:image

制御構造


if文を使って条件分岐


ifを使うと条件を分岐させることができる。
数値が代入されている変数aがあった場合、例えばこのような条件が指定できる。
・aがある値だったら
・aがある値でなかったら
・aがある値より大きかったら

下記のプログラムを実行してみた。

a = 0
if a == 0
  puts 'a は 0 です'
end

f:id:ayaketan:20111207195116j:image
2行目の==はaと0が等しかったらという意味で、比較演算子と呼ばれる。
比較演算子には下記のようなものがある。
== 等しい
!= 等しくない
> より大きい
< より小さい

if文では変数と変数を比べることもできる。
また、elseを使うと、ifの条件が成立しなかったときの処理を実行することができる。

a = 10 ; b = 5
if a > b
 puts 'a は b より大きいです'
else
 puts 'a は b と同じか小さいです'
end

f:id:ayaketan:20111207195154j:image

a = 5 ; b = 10
if a > b
 puts 'a は b より大きいです'
else
 puts 'a は b と同じか小さいです'
end

f:id:ayaketan:20111207195213j:image

whileで繰り返し


下記のプログラムを実行した。

ct = 0
while ct < 5
  puts ct
  ct += 1
end
puts 'ループが終了しました'
puts ct

f:id:ayaketan:20111207195230j:image
while の条件は ct < 5 となっています。つまり ct が 5 より小さければ条件成立です。ct の内容はループする度に 1 ずつ加算されていき ct が 5 になったときに条件が成立しなくなる。するとプログラムは while の行から end の次の行へジャンプする。

無限ループ


次のプログラムでは条件が必ず成立するのでプログラムが終了しない。
このようなループを無限ループという。
このプログラムを停止させるには Ctrl キーを押しながら C キーを押して Ruby を強制終了させる。

while 1 > 0
  puts 'とまらないよ'
  sleep 1
end

f:id:ayaketan:20111207195254j:image
1 > 0 は必ず成立する条件。これは 100 > 10 でも 5 == 5 でもよい。
また、必ず成立する条件を書く場合、普通は true を使う。

while true
  # 繰り返したい処理
end

timesを使ったループ


times はある決まった回数だけループさせたいときに便利なメソッド。
次のプログラムは 10 回の繰り返し処理を行う。

10.times do
  # 繰り返したい処理
  puts 'hello'
end

f:id:ayaketan:20111207195319j:image
10の部分には変数を書くこともできる。

じゃんけんゲーム


グー、チョキ、パーのいずれかを出してくるじゃんけんロボットとプレイヤーがじゃんけん対決をして、勝敗結果を表示するプログラムを作ってみた。

さいころ

puts rand(6) + 1

これは 1 〜 6 の数値をランダムで画面に表示するプログラム。
rand(6) は 0 〜 5 の整数をランダムで返す。
rand の引数に1 以上の整数を与えると「 0 以上で 与えた引数 -1 以下の整数」のいずれかの値が取得できる。
ループを使えばさいころを 10 回繰り返して振ることもできる。

10.times do
  puts rand(6) + 1
end

じゃんけんロボット


じゃんけんゲームを作る前にじゃんけんロボットを作る。
じゃんけんロボットはグー、チョキ、パーのいずれかを画面に表示するプログラム。

puts 'じゃんけん'
sleep 1
r = rand(3) + 1
if r == 1
  puts 'グー'
elsif r == 2
  puts 'チョキ'
elsif r == 3
  puts 'パー'
end

f:id:ayaketan:20111207195441j:image
1.r が 1 なら ⇒ 「グー」を表示する
2.r が 1 ではないときに r が 2 なら ⇒ 「キョキ」を表示する
3.r が 1 ではなくかつ r が 2 ではないときに r が 3 なら ⇒ 「パー」を表示する

整理すると
1.r が 1 なら ⇒ 「グー」を表示する
2.r が 2 なら ⇒ 「キョキ」を表示する
3.r が 3 なら ⇒ 「パー」を表示する

caseとwhenを使う


先ほどのじゃんけんロボットのプログラムは 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

f:id:ayaketan:20111207195517j:image

ゲームブックを作る


最後に、今までの機能を使ってゲームブックプログラムを作成。

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

f:id:ayaketan:20111207195541j:image