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.おわりに
次は勝敗結果に基づいて賭け金を移動させるメソッドをつくります!
今回のコードは以下のリポジトリにあります。どんどん追記していきます!