【Ruby】じゃんけんアプリを作る（戻り値・while文など・・・）

教えてもらって、やっと理解できたので備忘録として。

```ruby:janken.rb

def janken
    puts "[0]:グー\n[1]:チョキ\n[2]:パー"
    player_hand = gets.to_i

    program_hand = rand(3)

    jankens = ["グー", "チョキ", "パー"]

    puts "あなたの手:#{jankens[player_hand]}, わたしの手:#{jankens[program_hand]}"

    if player_hand == program_hand
      puts "あいこで"
      return true
    elsif (player_hand == 0 && program_hand == 1) || (player_hand == 1 && program_hand == 2) || (player_hand == 2 && program_hand == 0)
      puts "あなたの勝ちです"
      return false
    else
      puts "あなたの負けです"
      return false
    end
  end

  next_game = true

  puts "最初はグー、じゃんけん..."

  while next_game do
    next_game = janken
  end
```

#必要な予備知識

###乱数の作り方
乱数を使うとプログラムの出す手をランダムに定義することができる
**randメソッド**使うと手軽に乱数を生成できる。

randメソッドに引数として数を渡すと、**「0」～「渡した数－1」**の間でランダムに数を渡す

`rand(欲しい乱数の数)`

```ruby:例
rand(100)
# => 0～99の中から1つの数字をランダムに返す
```

###改行コード
`\n `（OSがWindowsの場合は「\」部分が「¥」）
※ダブルクオーテーション「"」で囲んだ場合のみ有効。シングルクオーテーション「`」で囲んじゃダメ

###gets または　gets.chomp
入力待ち状態。入力されるまでプログラムは動かない。
**「変数 = gets」**とすることで、エンターキーを押すと入力された値を変数に代入することができる。
getsメソッドはキーボードで入力した**文字列**を取得する。

数値を取得する場合：**gets.to_i (またはgets.chomp.to_i）**
→入力された内容を数値に変換し、計算などにも使える

※gets と gets.chompの違い→**改行されるかされないかの違い**
gets：改行される
gets.chomp：改行されない

【参考】https://qiita.com/Take-st/items/26f29a6dea622d1e7e8d


###while文（繰り返し処理）

```ruby:while文
while 条件式 do # doは省略可
  実行する処理
end
```
条件式→true/falseに変わるもの。実行したらtrueかfalseになる
・false→falseかnil(何もない状態）
・上記以外はすべてtrueになる


#じゃんけんアプリを作る際のポイント

###①自分と相手のじゃんけんの手をつくる

この部分

```ruby:janken.rb
puts "最初はグー、じゃんけん..."
  puts "[0]:グー\n[1]:チョキ\n[2]:パー"
  player_hand = gets.to_i #自分の手の数値を入力 Point.1

  program_hand = rand(3) #0～2の数値の間でランダムに数値が返される　Point.2 

  jankens = ["グー", "チョキ", "パー"]

  puts "あなたの手:#{jankens[player_hand]}, わたしの手:#{jankens[program_hand]}" #Point.1、2の数値に対応する文字（グー、チョキ、パーのいずれか）が入る
```

じゃんけんをする自分の手と相手の手を作る。

【自分の手】0〜2までの手をターミナルから入力する
【相手の手】乱数で0〜2までの数値を生成する

ここで重要なのは今回じゃんけんの手を数値(0〜2)で扱うということ。グー、チョキ、パーという文字列ではない。これはプログラムでは数値のほうが扱いやすく、比較なども簡単なため。

###②勝ち、負け、あいこの条件を作る

前提：今回は条件の順番は特に関係ないので、**簡単な条件を先に書いていく**

※**条件分岐の注意点**：条件は必要な数だけ並べることができるが、複数の条件に合致したとしても、実行されるのは最初に合致した条件の処理のみ。そのため条件の順番を間違えると、期待した分岐がなされないことがあるので条件を書く順番には気を付ける。（今回は順番関係ないので特に気にしなくてよし）

```ruby:janken.rb
if player_hand == program_hand #あいこの条件
      puts "あいこで"
     
    elsif (player_hand == 0 && program_hand == 1) || (player_hand == 1 && program_hand == 2) || (player_hand == 2 && program_hand == 0) #勝ちの条件
      puts "あなたの勝ちです"
     
    else
      puts "あなたの負けです"
    
    end

#勝ちの条件は下記のようにも書けるが、イメージがつきにくい条件式になるので上記のパターンのが〇
player_hand - program_hand == -1 || player_hand - program_hand == 2
```
何個かの条件を組み合わせる場合は、
`(条件式) || (条件式) || (条件式)`のように書けばOK

また、「勝ちの条件式」を別のメソッドに逃がしてすっきりさせる方法もある

```ruby:janken.rb

def win?(player_hand , program_hand)
   (player_hand == 0 && program_hand == 1) || (player_hand == 1 && program_hand == 2) || (player_hand == 2 && program_hand == 0)
end

if player_hand == program_hand #あいこの条件
      puts "あいこで"
     
    elsif win?(player_hand , program_hand) #勝ちの条件
      puts "あなたの勝ちです"
     
    else
      puts "あなたの負けです"
    
    end
```
または、次のように変数に代入して逃がす場合でもOK

```ruby:janken.rb

win = (player_hand == 0 && program_hand == 1) || (player_hand == 1 && program_hand == 2) || (player_hand == 2 && program_hand == 0)

if player_hand == program_hand #あいこの条件
      puts "あいこで"
     
    elsif win #勝ちの条件
      puts "あなたの勝ちです"
     
    else
      puts "あなたの負けです"
    
    end
```

###③あいこの時にもう1度じゃんけんをさせる
・勝ち、負けの場合→プログラムを終了
・あいこの場合→じゃんけんを繰り返す。決着がつく(勝つか負けるか)までじゃんけんを続けるようにプログラムを作る

```ruby:janken.rb

def janken # jankenメソッドの中でじゃんけん中の処理を書く
    puts "[0]:グー\n[1]:チョキ\n[2]:パー"
    player_hand = gets.to_i

    program_hand = rand(3)

    jankens = ["グー", "チョキ", "パー"]

    puts "あなたの手:#{jankens[player_hand]}, わたしの手:#{jankens[program_hand]}"

    if player_hand == program_hand
      puts "あいこで"
      return true # あいこの場合、trueを返す(ここは true のみでもOK)
    elsif (player_hand == 0 && program_hand == 1) || (player_hand == 1 && program_hand == 2) || (player_hand == 2 && program_hand == 0)
      puts "あなたの勝ちです"
      return false # 勝ちの場合、falseを返す(ここは false のみでもOK)
    else
      puts "あなたの負けです"
      return false # 負けの場合、falseを返す(ここは false のみでもOK)
    end
  end # jankenメソッド終わり

  next_game = true # 1回目を実行するためにtrueをnext_gameに代入

  puts "最初はグー、じゃんけん..."

  while next_game do # next_gameがtrue(あいこ)の間は繰り返し。false(勝ち・負け)になれば繰り返し終了
    next_game = janken # jankenメソッドの返り値(true/false)がnext_gameに代入される
  end
```

・じゃんけん用のメソッドを定義する(janken)。この中は①、②で部分的に作っていた「じゃんけんの内容」。
そして、jankenメソッド内にまだ次のゲームがあるか、すなわちあいこかどうかをtrueかfalseで返す。あいこならtrue、決着がついたらfalse。trueになれば、繰り返し処理が実行されるようにする。

・while文では、まず1回目のじゃんけんは行われるためにnext_game = true を代入する。
2回目以降は、jankenメソッド内のtrueかfalseがnext_gameに代入される。
falseが代入されればそこで終了、trueが代入されれば同じことが繰り返される。