1.はじめに
今回は勝敗結果と役に基づいて賭け金を移動させるメソッドを書きます。カイジのチンチロは役とその倍率は以下のようになっています。
役 | 倍率 |
---|---|
ピンゾロ (1,1,1) | 5倍づけ |
ゾロ目 (2~6) | 3倍づけ |
シゴロ (4,5,6) | 2倍づけ |
通常の目 (3個中2個がおなじ目) | 1倍づけ |
目なし | 1倍払い |
ヒフミ(1,2,3) | 2倍払い |
〜づけというのは買った場合に賭け金の◯倍で返ってくるという意味です。〜払いというのは負けた場合にマイナスになります。
2. メソッドの作成
メソッドを作成します。引数は相手と自分の役、賭け金、勝敗結果となります。前回の記事と同様に、クラスのなかにメソッドを作成します。そのため引数は以下のようになります。
def transfer_money(opponent,win_or_lose)
# 相手の役 : opponent.hand
# 相手の賭け金 : opponent.bet_money
# 自分の役 : @hand
# 自分の賭け金 : @bet_money
# 勝敗結果 : win_or_lose
以下、とりあえず作ってみます。
def transfer_money(opponent,win_or_lose)
strength_relationship = [
'ヒフミ','目なし',
'通常の目(1)','通常の目(2)','通常の目(3)',
'通常の目(4)','通常の目(5)','通常の目(6)',
'シゴロ','ゾロ目','ピンゾロ'
]
dividend_table = [
-2,-1,
1,1,1,
1,1,1,
2,3,5
]
my_hand_rank = strength_relationship.index(@hand)
opponent_hand_rank = strength_relationship.index(opponent.hand)
my_dividend_ratio = dividend_table[my_hand_rank]
opponent_dividend_ratio = dividend_table[opponent_hand_rank]
move_money = 0
case win_or_lose
when '勝ち'
move_money = my_dividend_ratio * bet_money
when '引き分け'
move_money = 0
when '負け'
move_money = - opponent_dividend_ratio * opponent.bet_money
end
puts <<~TEXT
自分: #{@hand} / 相手: #{opponent.hand} / #{win_or_lose} ... #{move_money}ペリカ
TEXT
move_money
end
自分と相手の役を調べて、それぞれをdividend_table
から持ってきます。勝敗結果に基づいてmove_money
の値を計算します。 負けた場合はマイナスになります。
ちょっとメソッドを使ってみましょう。クラスの外に以下の内容を書きます。
player_A = Player.new(money:1000,bet_money:100,hand:'ピンゾロ',name:'カイジ')
player_B = Player.new(money:3000,bet_money:300,hand:'目なし',name:'班長')
player_A.transfer_money(player_B,'勝ち')
実行します。実行結果は以下のようになります。
自分: ピンゾロ / 相手: 目なし / 勝ち ... 500ペリカ
賭け金100ペリカに対して5倍付の500ペリカ。問題ありませんね。それではこれはどうでしょうか。
player_A = Player.new(money:1000,bet_money:100,hand:'ヒフミ',name:'カイジ')
player_B = Player.new(money:3000,bet_money:300,hand:'通常の目(2)',name:'班長')
player_A.transfer_money(player_B,'負け')
自分: ヒフミ / 相手: 通常の目(2) / 負け ... -300ペリカ
あれ?2倍払いではなく、3倍払いになっていますね。 さらにこれはどうでしょうか。
player_A = Player.new(money:1000,bet_money:100,hand:'ヒフミ',name:'カイジ')
player_B = Player.new(money:3000,bet_money:300,hand:'目なし',name:'班長')
player_A.transfer_money(player_B,'負け')
自分: ヒフミ / 相手: 目なし / 負け ... 300ペリカ
む? ヒフミで負けたのにペリカがプラスになってしまいますね。
3. メソッドの修正(例外処理)
ヒフミと目なしはちょっと特殊な役なので、相手の役によっては賭け金の計算がふつうのものと異なります。以下に表を書きます。
自分 | 相手 | 勝敗 | オッズ |
---|---|---|---|
ヒフミ | 目なし | 負け | 2倍払い |
ヒフミ | シゴロ | 負け | 2倍払い |
ヒフミ | ゾロ目 | 負け | 3倍払い |
ヒフミ | ピンゾロ | 負け | 5倍払い |
目なし | ヒフミ | 勝ち | 2倍づけ |
シゴロ | ヒフミ | 勝ち | 2倍づけ |
ゾロ目 | ヒフミ | 勝ち | 3倍づけ |
ピンゾロ | ヒフミ | 勝ち | 5倍づけ |
これを踏まえて例外をメソッドに加えます。
# ....略
move_money = 0
if @hand == 'ヒフミ' || opponent.hand == 'ヒフミ' then
if @hand == 'ヒフミ' && (opponent.hand != 'シゴロ' && opponent.hand != 'ゾロ目' && opponent.hand != 'ピンゾロ') then
opponent_dividend_ratio = 2
end
if @hand == '目なし' && (opponent.hand == 'ヒフミ') then
my_dividend_ratio = 2
end
if (@hand != 'シゴロ' && @hand != 'ゾロ目' && @hand != 'ピンゾロ') && opponent.hand == 'ヒフミ' then
opponent_dividend_ratio = 2
my_dividend_ratio = 2
end
end
case win_or_lose
# ....略
これでOK。次にテストをしてみましょう。
4.テスト
テストコードを書きます。
require 'minitest/autorun'
require './lib/transfer_money'
class DiceTest < Minitest::Test
def test_transfer_money
roll_map = [
'ヒフミ','目なし',
'通常の目(1)','通常の目(2)','通常の目(3)',
'通常の目(4)','通常の目(5)','通常の目(6)',
'シゴロ','ゾロ目','ピンゾロ'
]
win_lose_map = [
['引き分け','負け','負け','負け','負け','負け','負け','負け','負け','負け','負け'],
['勝ち','引き分け','負け','負け','負け','負け','負け','負け','負け','負け','負け'],
['勝ち','勝ち','引き分け','負け','負け','負け','負け','負け','負け','負け','負け'],
['勝ち','勝ち','勝ち','引き分け','負け','負け','負け','負け','負け','負け','負け'],
['勝ち','勝ち','勝ち','勝ち','引き分け','負け','負け','負け','負け','負け','負け'],
['勝ち','勝ち','勝ち','勝ち','勝ち','引き分け','負け','負け','負け','負け','負け'],
['勝ち','勝ち','勝ち','勝ち','勝ち','勝ち','引き分け','負け','負け','負け','負け'],
['勝ち','勝ち','勝ち','勝ち','勝ち','勝ち','勝ち','引き分け','負け','負け','負け'],
['勝ち','勝ち','勝ち','勝ち','勝ち','勝ち','勝ち','勝ち','引き分け','負け','負け'],
['勝ち','勝ち','勝ち','勝ち','勝ち','勝ち','勝ち','勝ち','勝ち','引き分け','負け'],
['勝ち','勝ち','勝ち','勝ち','勝ち','勝ち','勝ち','勝ち','勝ち','勝ち','引き分け']
]
bet_map = [
[0,-2,-2,-2,-2,-2,-2,-2,-2,-3,-5],
[2,0,-1,-1,-1,-1,-1,-1,-2,-3,-5],
[2,1,0,-1,-1,-1,-1,-1,-2,-3,-5],
[2,1,1,0,-1,-1,-1,-1,-2,-3,-5],
[2,1,1,1,0,-1,-1,-1,-2,-3,-5],
[2,1,1,1,1,0,-1,-1,-2,-3,-5],
[2,1,1,1,1,1,0,-1,-2,-3,-5],
[2,1,1,1,1,1,1,0,-2,-3,-5],
[2,2,2,2,2,2,2,2,0,-3,-5],
[3,3,3,3,3,3,3,3,3,0,-5],
[5,5,5,5,5,5,5,5,5,5,0]
]
player_A = Player.new(money:1000,bet_money:100,hand:'目なし',name:'カイジ')
player_B = Player.new(money:1000,bet_money:300,hand:'目なし',name:'班長')
new_bet_map = bet_map.map { |x|
x.map { |y|
if y > 0
y * player_A.bet_money
elsif y < 0
y * player_B.bet_money
else
y = 0
end
}
}
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 new_bet_map[i][j], player_A.transfer_money(player_B,win_lose_map[i][j])
end
end
end
end
each_with_index
を二回重ねることでfor文を二回回すのと同じ構造にしています。また、map
を二回重ねて二次元配列に賭け金をかけています。
これでテストが通りました。
5. おわりに
これでチンチロのおおまかな機能をつくることができました。次回はゲーム進行にかかわる諸々の処理をつくります。あと記事2つくらいで終わりそうです!
コードは以下に追記していきます。