Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
1
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

Rubyでじゃんけんアプリを作ってみた(1)

Progateも一通り回ったのでサンプルアプリを作ってみる。

簡単だけど調べないとできなさそうなアプリはなにか?と考え、まずは「じゃんけん」かなと考えました。
シンプルだけど得られるものはありそう。

ではいってみよう!!

仕様要件

・プレイヤーは標準入力で使用する手を選択する
・選択せずにEnterを押下、もしくは想定外の値では次に進まないようにする
・勝負がついたらおしまい、あいこになったら決着がつくまでおこなう

実際に書いてみた

janken.rb
# ゲーム開始文言
puts "相手「最初はグー、じゃんけん・・・」\n\r"

# While文を使ってループ処理を行う
loop_flg = true
while loop_flg do

  # 自分の手(入力処理)
  player = nil
  # 未入力、もしくは指定外の値を入れるとループする
  while player.nil? || player > 3 || player == 0 do
    puts "[1]グー\n[2]チョキ\n[3]パー"
    player = gets.to_i
  end

  # 相手の手(乱数処理)
  enemy = nil
  # 未入力、もしくは指定外の値を入れるとループする
  while enemy.nil? || enemy > 3 || enemy == 0 do
    enemy = rand(4)
  end

  # 固定文言
  puts "\n\r相手「ぽん!」\n\r"

  # 勝負
  jankens = ["", "グー", "チョキ", "パー"]
  puts "プレイヤー:#{jankens[player]}"
  puts "相手   :#{jankens[enemy]}\n\r"

  # 判定
  if player == enemy
    puts "相手「あいこで・・・」\n\r"
  elsif (player == 1 && enemy == 2) || (player == 2 && enemy == 3) || (player == 3 && enemy == 1)
    loop_flg = false
    puts "You win!!"
  else
    loop_flg = false
    puts "You lose."
  end

end
exit

ソースコードで使ったもの

putsメソッドを使って文字出力を行う

出力系メソッドはいくつかあるが下記のように使い分ける。

メソッド 特徴
print 改行を入れずに引数に指定した値を出力される
puts 末尾に改行が入る形で出力される
p 出力する値と共に型情報(文字列や数値型など)を一緒に出力される
printf 書式を指定して出力するためのメソッド
sprintf 文字配列に対して出力するためのメソッド

今回は、全てputsを使用している。
また改行はMac OSなので「\n\r」を使用している。

ソースコード
puts "相手「最初はグー、じゃんけん・・・」\n\r改行"
出力例
相手「最初はグー、じゃんけん・・・」
改行

while文を使ってループ処理を行う

ループメソッドはいくつかあるが下記のように使い分ける。

メソッド 扱う内容 特徴
times 回数を指定して繰り返す場合に使用する
for 指定した条件が満たされている間は繰り返しを続ける(1周すると条件が数値の場合はカウントアップされていく)
while 指定した条件が満たされている間は繰り返しを続ける(繰り返し回数以外の条件で用いられる)
until 指定した条件が満たされるまで繰り返しを続ける
each オブジェクトの集まりに対して繰り返し処理を行う場合に使用される
loop 一度呼び出したら後戻りはできない(command + c も効かない)

今回は、全てwhileを用いている。
ループする箇所はじゃんけんの手とあいこの場合に使っている。

ソースコード
  while player.nil? || player > 3 || player == 0 do
    puts "[1]グー\n[2]チョキ\n[3]パー"
    player = gets.to_i
  end

補足すると、上記の場合は3つの条件のいずれかを満たしていると繰り返すようになっている。逆に言うと条件を満たしていない時が正しい挙動である。
①変数が空っぽである(最初は空っぽの状態なので1周目用)
②入力した値が3より大きいこと(許可しているのは、1/2/3のみのため)
③入力した値が0の場合(何も入力せずEnterを押下した場合も同様の挙動になる)

特に③の「何も入力しない場合」を考慮すると、必然的に「0」が使えなくなるので、条件は1〜3のいずれかにしている。

getsメソッドを使ってキーボードで入力した文字列を取得する

getsメソッドはキーボードで入力した文字列を取得することができる。
getsgets.chompの違いは、「.chomp」を付けると改行をなくしてくれる。

ソースコード
player = gets.to_i

今回は、改行をしたかったのでgetsを使用している。

また、このままだと文字列として認識してしまうため、「.to_i」を付加させて数値に変換させる。
数値に変換されたのがプレイヤーの手として代入されるようになる。

randメソッド使ってランダム処理を行う

randを使うと乱数を生成できること。

ソースコード
enemy = rand(4)

randメソッドに引数として数を渡すと「0」から「渡した数 - 1」の間でランダムに数を返せる。

ソースコード
  # 相手の手(乱数処理)
  enemy = nil
  # 未入力、もしくは指定外の値を入れるとループする
  while enemy.nil? || enemy > 3 || enemy == 0 do
    enemy = rand(4)
  end

ソースでは、0〜3の数値をランダムで変数に代入するようにして、プレイヤーと同じく1〜3の何れかが代入するまでやり直させるようにした。

配列の変換

自分の手と相手の手は、数値1/2/3の何れかなので文字列に変換させる。
0は前の処理でない想定になっているのが、愚直に処理を行うとする。

ソースコード
  # 勝負
  jankens = ["", "グー", "チョキ", "パー"]
  puts "プレイヤー:#{jankens[player]}"
  puts "相手   :#{jankens[enemy]}\n\r"

0:nil
1:グー
2:チョキ
3:パー

といった具合に、変数の数値が配列番号となって変換される。

if文を用いて勝敗の判定処理を行う

if文を用いて下記のパターン分けを行う。
①あいこ
②プレイヤーの勝ち
③プレイヤーの負け

ソースコード
  # 判定
  if player == enemy
    puts "相手「あいこで・・・」\n\r"
  elsif (player == 1 && enemy == 2) || (player == 2 && enemy == 3) || (player == 3 && enemy == 1)
    loop_flg = false
    puts "You win!!"
  else
    loop_flg = false
    puts "You lose."
  end

①あいこの場合だが、プレイヤーと相手の手が同じ場合のみ発生するので、ここで文言を出力して繰り返すようにする。

色んなループメソッドがあるが、ここでもwhileメソッドを用いる。
条件として最初からループフラグがONの状態でスタートするので、処理を終えれば最初から繰り返すようにしている。
逆に①以外の結果になった場合はループフラグをOFFにして処理を終えるようにしている。

ソースコード
if player == enemy

②プレイヤーの勝ちの場合だが、下記のパターンのみ発生する。
a.プレイヤーが「グー」、相手は「パー」
b.プレイヤーが「チョキ」、相手は「グー」
c.プレイヤーが「パー」、相手は「チョキ」

これしかないので、3パターンの何れかが該当したら勝利パターンに分岐に処理するようにする。

ソースコード
elsif (player == 1 && enemy == 2) || (player == 2 && enemy == 3) || (player == 3 && enemy == 1)

③プレイヤーの負けの場合だが、①②の何れかに該当しない場合発生するので、条件分岐はせずに敗北パターンの処理を行うようにする。

完成して…

これで、なんとかじゃんけんが完成するが、もう少し次は踏み込んでみるとする。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
1
Help us understand the problem. What are the problem?