Rubyでチンチロゲームを作る 　第2回　勝敗判定

# 1.はじめに
　前回にひきつづきチンチロゲームをつくります。今回は自分と相手の役を比較し、どちらが強いかを判定させます。

# 2.勝敗判定の概要
　登場する役を書き出すとこんなかんじになります。
```
（最弱）　ヒフミ < 目なし < 通常の目(1)...通常の目(6) < シゴロ < ゾロ目 < ピンゾロ (最強)
```
　サイコロを3つ振ってそれぞれの目が「1,2,3」となるヒフミが最弱。すべての目が1のピンゾロが最強となっています。

　勝敗判定は自分と相手の役を引数とし、勝ち負けを出力させます。やってみましょう。

# 3.メソッドの作成

　はじめにメソッドをこんな感じで考えました。

```ruby
def check_win_lose(my_hand,opponent_hand)
    strength_relationship = [
      'ヒフミ','目なし',
      '通常の目(1)','通常の目(2)','通常の目(3)',
      '通常の目(4)','通常の目(5)','通常の目(6)',
      'シゴロ','ゾロ目','ピンゾロ'
    ]
    my_hand_rank = strength_relationship.index(my_hand)
    opponent_hand_rank = strength_relationship.index(opponent_hand)

    if(my_hand_rank > opponent_hand_rank)
       '勝ち' 
     elsif(my_hand_rank == opponent_hand_rank)
       '引き分け'
     else
       '負け'
     end
  end
```

 `strength_relationship` に役を弱い順に入れておき、indexで強弱関係を判定します。やっていることは単純ですね。

　これでできました。

# 4.メソッドの改良
## 4-1.Playerクラスの作成
　でもこれだとあまりよくなさそうです。メソッドの引数の順序によって、自分と相手の役を逆にしてしまうおそれがあります。あと、今後の賭け金の移動のことなども考えるとクラスをつくったほうがいい気もします。
ちょっとやってみましょう。

　まずはPlayerクラスを作成します。

```ruby
class Player
  attr_reader :name
  attr_accessor :money,:bet_money,:hand
  def initialize(**params)
    @name = params[:name]
    @money = params[:money]
    @bet_money = params[:bet_money]
    @hand = params[:hand]
  end
end
```

　クラスには名前、所持金、賭け金、役を入れておきます。
ためにしにカイジと班長をつくってみましょう。さきほどのコードの下に追記します。

```ruby
player_A = Player.new(money:1000,bet_money:100,hand:'目なし',name:'カイジ')
player_B = Player.new(money:3000,bet_money:300,hand:'目なし',name:'班長')
puts <<~TEXT
名前： #{player_A.name} 
　所持金:#{player_A.money} ペリカ
　賭け金：#{player_A.bet_money} ペリカ
　役： #{player_A.hand}
--------------------------
名前： #{player_B.name} 
　所持金:#{player_B.money} ペリカ
　賭け金：#{player_B.bet_money} ペリカ
　役： #{player_B.hand}
TEXT
```

実行してみると以下のように表示されるはずです。

```
名前： カイジ 
　所持金:1000 ペリカ
　賭け金：100 ペリカ
　役： 目なし
--------------------------
名前： 班長 
　所持金:3000 ペリカ
　賭け金：300 ペリカ
　役： 目なし
```

無事にクラスが作成されていますね。班長の所持金は多めです。

## 4-2. クラス内のメソッド作成
　次に作成したクラスの中にメソッドを書いていきます。

```ruby
class Player
  attr_reader :name
　# 略.....

  def check_win_lose(opponent)

    strength_relationship = [
      'ヒフミ','目なし',
      '通常の目(1)','通常の目(2)','通常の目(3)',
      '通常の目(4)','通常の目(5)','通常の目(6)',
      'シゴロ','ゾロ目','ピンゾロ'
    ]
    my_hand_rank = strength_relationship.index(@hand)
    opponent_hand_rank = strength_relationship.index(opponent.hand)

    if(my_hand_rank > opponent_hand_rank)
       '勝ち' 
     elsif(my_hand_rank == opponent_hand_rank)
       '引き分け'
     else
       '負け'
     end
  end
  # 略....
end
```

 ちょっと引数が変わっていますね。 まず、このメソッドは以下のように呼び出します。

```ruby
 player_A.check_win_lose(player_B)
```
　先頭のplayer_Aの役が`@hand`、player_Bの役が`opponent.hand`に格納されています。そして上記だけではなにも表示されないので、あたまに表示させるメソッド `p`をつけます。

```ruby
 p player_A.check_win_lose(player_B)
```

　これで、勝ち/負け/引き分けが表示されるはずです。


# 5.テストコード

　最後にテストをしましょう。前回にひきつづきminitestを利用します。（本当はRSpecをやってみたいですが勉強できてないので…）　今までのコードとは別ファイルにテストファイルを作成します。位置はこんなかんじです。

```
-lib
--transfer_money.rb
-test
--check_win_lose.rb
```

　やっていきましょう。

```ruby

require 'minitest/autorun'
require './lib/transfer_money'
class DiceTest < Minitest::Test
  def test_win_lose
    roll_map = [
      'ヒフミ','目なし',
      '通常の目(1)','通常の目(2)','通常の目(3)',
      '通常の目(4)','通常の目(5)','通常の目(6)',
      'シゴロ','ゾロ目','ピンゾロ'
    ]
    win_lose_map = [
      ['引き分け','負け','負け','負け','負け','負け','負け','負け','負け','負け','負け'],
      ['勝ち','引き分け','負け','負け','負け','負け','負け','負け','負け','負け','負け'],
      ['勝ち','勝ち','引き分け','負け','負け','負け','負け','負け','負け','負け','負け'],
      ['勝ち','勝ち','勝ち','引き分け','負け','負け','負け','負け','負け','負け','負け'],
      ['勝ち','勝ち','勝ち','勝ち','引き分け','負け','負け','負け','負け','負け','負け'],
      ['勝ち','勝ち','勝ち','勝ち','勝ち','引き分け','負け','負け','負け','負け','負け'],
      ['勝ち','勝ち','勝ち','勝ち','勝ち','勝ち','引き分け','負け','負け','負け','負け'],
      ['勝ち','勝ち','勝ち','勝ち','勝ち','勝ち','勝ち','引き分け','負け','負け','負け'],
      ['勝ち','勝ち','勝ち','勝ち','勝ち','勝ち','勝ち','勝ち','引き分け','負け','負け'],
      ['勝ち','勝ち','勝ち','勝ち','勝ち','勝ち','勝ち','勝ち','勝ち','引き分け','負け'],
      ['勝ち','勝ち','勝ち','勝ち','勝ち','勝ち','勝ち','勝ち','勝ち','勝ち','引き分け']
    ]
    
    player_A = Player.new(hand:'目なし',name:'カイジ')
    player_B = Player.new(hand:'目なし',name:'班長')
    player_A.hand = roll_map[0]
    player_B.hand = roll_map[1]
    assert_equal win_lose_map[0][1], player_A.check_win_lose(player_B)
  end
end
```

　急に大きな配列があってびっくりしたかと思いますが、ただの勝敗表です。前回の反省を踏まえて、少しでもテストを楽にしようとあらかじめ表をつくりました。これをloopで回します。
　まずはひとつだけテストします。無事に通ったら以下のやつにつけかえてテストします。

```ruby
   player_A = Player.new(hand:'目なし',name:'カイジ')
   player_B = Player.new(hand:'目なし',name:'班長')
   roll_map.each_with_index do |value_1,i|
       player_A.hand = value_1
       roll_map.each_with_index do |value_2,j|
         player_B.hand = value_2
         assert_equal win_lose_map[i][j], player_A.check_win_lose(player_B)
       end
   end
```

　あとはテストをします。無事に通りました！！！

# 6.おわりに

　次は勝敗結果に基づいて賭け金を移動させるメソッドをつくります！

　今回のコードは以下のリポジトリにあります。どんどん追記していきます！

https://github.com/kyokucho1989/ruby-game