LoginSignup
3
1

More than 3 years have passed since last update.

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

Posted at

1.はじめに

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

2.勝敗判定の概要

 登場する役を書き出すとこんなかんじになります。

(最弱) ヒフミ < 目なし < 通常の目(1)...通常の目(6) < シゴロ < ゾロ目 < ピンゾロ (最強)

 サイコロを3つ振ってそれぞれの目が「1,2,3」となるヒフミが最弱。すべての目が1のピンゾロが最強となっています。

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

3.メソッドの作成

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

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クラスを作成します。

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

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

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. クラス内のメソッド作成

 次に作成したクラスの中にメソッドを書いていきます。

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

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

 player_A.check_win_lose(player_B)

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

 p player_A.check_win_lose(player_B)

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

5.テストコード

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

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

 やっていきましょう。


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で回します。
 まずはひとつだけテストします。無事に通ったら以下のやつにつけかえてテストします。

   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.おわりに

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

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

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1