初めに作ったブラックジャック↓↓
Rubyでブラックジャック作ってみた(minitest使ってみた)
アップデートの内容
-
100万円稼いだら勝ち、所持金0円になったら負けというルールを追加。
-
play.rb(ゲーム起動クラス)
- ディーラーターンを同じ文で2箇所書いていたため、ディーラーターンメソッドを作り、よりコードを読みやすくした。
- カードを引いたときのドキドキ感を増す為に、waitメソッドを作り、ディーラーがドローする前にEnterを押さないと進めないようにした。
- 指定した金額をベットできるようにした。
-
card.rb(カードクラス)
- マークがわかりやすくなるように「スペード」「ハート」の、様にカタカナ表記を追加。
-
deck.rb(デッキクラス)
- プレイクラスを作った為、プレイヤーが毎回リセットされなくなった為、デッキをリセットできるように、リセットメソッドを作成した。
-
player.rb(プレイヤークラス)
- デッキクラスと同様プレイヤーが毎回初期化されなくなった為、テスト用に使っていたリセットメソッドをゲーム中にも使うようにした。
- 「A」はバーストした際に「1」になるようにスコア計算メソッドに機能を追加。
- ベット金額の計算機能を追加。
-
judge.rb(ジャッジクラス)
- 勝敗が決まったときのベットの計算機能を追加。
- 所持金でゲームクリアかゲームオーバーかを判定する機能を追加。
-
test.rb(動作確認テスト)
- ベットの計算機能のテストを追加。
-
main.rb(ブラックジャックを動かすメインファイルだったが、プレイクラスを作った為、削除)
ルール
- 所持金が100万以上で勝利。0円になったら敗北
- 「A」は「1」は都合良い数字に変換。というよりトータルスコアを変換。
- ヒットかスタンドのみ
- トータルスコアが高い方が勝ち
- ブラックジャック勝ちでベット金額3倍もらえる。通常2倍。
play.rb(プレイクラス)
play.rb
require './card'
require './deck'
require './judge'
require './money'
require './player'
class Play
def initialize
@player = Player.new
@dealer = Player.new(name: 'ディーラー')
play
end
def message(title, choice1="ヒット", choice2="スタンド") # win or lose or draw or error
case title
when :win
puts 'あなたの勝ちです'
when :lose
puts 'あなたの負けです'
when :draw
puts '引き分けです'
when :error
puts '無効です。もう一度入力してください'
when :choice
puts "選択してください\s\sPush「 1 」→ #{choice1} 、Push「 2 」→ #{choice2}"
end
end
def dealer_turn
# スタンド時の処理(ディーラーのターン)
puts 'ディーラーのターンです'
wait
# プレイヤーがブラックジャックだった場合のディーラーの処理
if @player.blackjack?
@dealer.draw
@dealer.show
if !@dealer.blackjack?
message :win
@player.money.stock = @player.bet_judge(@@bet, :blackjack)
@player.money.show
return
else
message :draw
@player.money.stock = @player.bet_judge(@@bet, :draw)
@player.money.show
return
end
end
# プレイヤーに勝つまでディーラーはヒットし続ける処理
while true
@dealer.draw
@dealer.show
wait
if @dealer.burst?
puts 'バースト!'
message :win
@player.money.stock = @player.bet_judge(@@bet, :win)
@player.money.show
break
elsif @dealer.total_score == 21 && @player.total_score == 21
message :draw
@player.money.stock = @player.bet_judge(@@bet, :draw)
@player.money.show
break
elsif @player.total_score < @dealer.total_score
message :lose
@player.money.stock = @player.bet_judge(@@bet, :lose)
@player.money.show
break
end
end
end
def bet_turn
@player.money.show
puts "いくらベットしますか?"
while true
bet = gets.to_i
if bet < 1
message :error
redo
elsif bet > @player.money.stock.to_i
puts "賭け金が手持ち金額を上回っています。もう一度入力してください。"
redo
else
puts <<~TEXT
#{bet} 円ベットしました。
#{'-' * 41}
TEXT
return bet
end
end
end
def play
while true # 再プレイのためのループ処理
# 手札リセット
@player.reset
@dealer.reset
# 初ターンの処理
puts "ようこそ、ブラックジャックへ"
puts "ルール:手持ち資金が100万円を超えたら勝ちです。0円になったら負けです。"
puts "カードを配ります"
@player.draw
@player.draw
@dealer.draw
@dealer.show
@@bet = bet_turn
@player.bet_calc(@@bet)
@player.money.show
# プレイヤーがブラックジャックじゃないか確認の処理
if @player.blackjack?
puts "ブラックジャック!"
@player.show
else
@player.show
message :choice
end
# ヒット、スタンドの処理(プレイヤーのターン)
while true
# ブラックジャックの場合は強制的にスタンドさせる処理
if @player.blackjack?
command = 2
else
command = gets.to_i # ヒットかスタンドか選択
end
# ヒットの場合の処理
if command == 1
while true
@player.draw
if @player.burst? # バーストしていないか確認
@player.show
puts "バースト!!"
message :lose
@player.money.stock = @player.bet_judge(@@bet, :lose)
@player.money.show
break
end
# ドロー後のトータルスコアの確認
@player.show
# 最大値(21)の場合は強制的にスタンドの処理
if @player.total_score == 21
puts 'トータルスコアが最大値に達しました'
command = 2
break
end
# 最大値ではない場合は、再度ヒットするか処理
puts "もう一度引きますか?"
message :choice
while true
command = gets.to_i # 再度、ヒットかスタンドの選択
if command == 1
break
elsif command == 2
break
else
message :error
redo
end
end
# ヒットかスタンドの処理
if command == 1
redo
elsif command == 2
break
end
end
# バースト時の強制終了処理
if @player.burst?
break
end
elsif command == 2
dealer_turn
command = nil
break
else
# h,s以外が入力されたときの処理
message :error
redo
end
if command == 2
dealer_turn
break
end
end
# ゲームオーバーか判定
if @player.gameover?
puts "所持金が0円になりました。"
puts "ゲームオーバーです。"
break
elsif @player.win?
puts "所持金が100万円を超えました。"
puts "あなたの勝ちです!!!!!!おめでとう!!!!!!!!!!!!"
break
end
# 再プレイの処理
puts "もう一回遊びますか?"
message :choice, "遊ぶ", "遊ばない"
while true
command = gets.to_i # 再プレイするか選択
if command == 1
command = nil
break
elsif command == 2
break
else
message :error
redo
end
end
# 再プレイの処理
command == nil ? redo : break
end
end
def gameover
end
def wait(words='Enterキーを押してください')
puts words
c = gets
end
end
Play.new
card.rb(カードクラス)
card.rb
class Card
attr_reader :mark, :number
def initialize(mark, number)
@mark = mark.freeze
@number = number.freeze
end
def convert
if @number == 'J' || @number == 'Q' || @number == 'K' || @number == 'A'
10
else
@number.to_i
end
end
end
deck.rb(デッキクラス)
deck.rb
class Deck
attr_accessor :cards
@@draw_count = 0
def initialize
@cards = []
create
@cards = @cards.shuffle
end
def create
nums = ['A', 2, 3, 4, 5, 6, 7, 8, 9, 10, 'J', 'Q', 'K']
mark = ["❤ ハート\s\s\s\s", "♦︎ ダイヤ\s\s\s\s", "♤ スペード\s\s", "♧ クローバー"]
mark.each do |m|
nums.each do |n|
@cards << Card.new(m, n)
end
end
end
def draw
cards[@@draw_count]
end
def draw_count
@@draw_count += 1
end
# テスト用のカード参照メソッド
def show
52.times do |n|
puts "[ #{cards[n].mark} #{cards[n].number} ]"
end
end
def reset
@cards = @cards.shuffle
@@draw_count = 0
end
end
player.rb(プレイヤークラス)
player.rb
class Player
include Judge
attr_accessor :hands, :total_score, :name, :money
@@deck = Deck.new
def initialize(name: "プレイヤー")
@hands = []
@total_score = 0
@name = name
@money = Money.new
end
def draw
self.hands << @@deck.draw
self.total_score = self.total_score_calc
@@deck.draw_count
end
def show
hands = []
self.hands.each do |hand|
hands << "#{hand.mark} #{hand.number}"
end
puts "#{self.name}の手札です"
puts hands
puts <<~TEXT
#{puts "[ トータル #{@total_score} ]"}
-----------------------------------------
TEXT
end
def a_count
a = 0
self.hands.each do |card|
if card.number == 'A'
a += 1
end
end
a
end
def reset
self.hands = []
self.total_score = 0
@@deck.reset
end
def total_score_calc
@total_score = 0 # 複数回計算した場合に、加算しないように、毎回トータルスコアをリセットする
self.hands.each do |hand| # @numberに「A」があり、トータルスコアが22以上ある場合、「A」の数だけ、トータルスコアから-9する。「A」の数をカウントするメソッドを作る。
@total_score += hand.convert
end
if self.burst? && self.in_a?
@total_score -= (self.a_count * 9) # 「A」の数だけ、トータルスコアから-9する。「A」の数をカウントするメソッドを作る。
end
@total_score
end
def bet_calc(bet)
self.money.stock = self.money.stock.to_i - bet
end
# テスト用メソッド
def test
puts "テストーーーーーー"
end
def reset_score
self.total_score = 0
end
def in_blackjack
self.hands << Card.new("♦︎", "J")
self.hands << Card.new("♦︎", "A")
end
end
# player = Player.new
# enemy = Player.new
# player.draw
# player.draw
# enemy.draw
# enemy.draw
# player.hands
# player.total_score_calc
# enemy.total_score_calc
# p player.blackjack?
# p enemy.blackjack?
judge.rb(ジャッジモジュール)
judge.rb
module Judge
def bet_judge(bet, judge)
stock = self.money.stock
case judge
when :win
stock += bet * 2
when :lose
stock += 0
when :blackjack
stock += bet * 3
when :draw
stock += bet
end
end
def blackjack?
if self.hands[1].number == "A" || self.hands[0].number == "A"
if self.hands[0].number == "J" || self.hands[0].number == "Q"|| self.hands[0].number == "K" || \
self.hands[1].number == "J" || self.hands[1].number == "Q"|| self.hands[1].number == "K"
self.total_score = "ブラックジャック"
true
else
false
end
else
false
end
end
def burst?
self.total_score > 21 ? true : false
end
def in_a?
self.hands.map do |card|
if card.number == 'A'
return true
end
end
false
end
def gameover?
self.money.stock <= 0 ? true : false
end
def win?
self.money.stock > 1000000 ? true : false
end
end
test.rb(minitest)
test.rb
require 'minitest/autorun'
require './card'
require './deck'
require './judge'
require './money'
require './player'
class BlackJackTest < Minitest::Test
# テストカードのマークは「 ♦︎ 」で統一
@@test_J = Card.new('♦︎', 'J')
@@test_Q = Card.new('♦︎', 'Q')
@@test_K = Card.new('♦︎', 'K')
@@test_A = Card.new('♦︎', 'A')
@@test_5 = Card.new('♦︎', 5)
@@test_10 = Card.new('♦︎', 10)
@@test_player = Player.new
def test_blackjack?
blackjack_player = Player.new
blackjack_player.hands << @@test_A
blackjack_player.hands << @@test_J
assert blackjack_player.blackjack?
blackjack_player.reset
blackjack_player.hands << @@test_J
blackjack_player.hands << @@test_A
assert blackjack_player.blackjack?
blackjack_player.reset
blackjack_player.hands << @@test_Q
blackjack_player.hands << @@test_A
assert blackjack_player.blackjack?
blackjack_player.reset
blackjack_player.hands << @@test_A
blackjack_player.hands << @@test_Q
assert blackjack_player.blackjack?
blackjack_player.reset
blackjack_player.hands << @@test_A
blackjack_player.hands << @@test_K
assert blackjack_player.blackjack?
blackjack_player.reset
blackjack_player.hands << @@test_K
blackjack_player.hands << @@test_A
assert blackjack_player.blackjack?
# false パターン
# blackjack_player.reset
# blackjack_player.hands << @@test_A
# blackjack_player.hands << @@test_10
# assert blackjack_player.blackjack?
# blackjack_player.reset
# blackjack_player.hands << @@test_5
# blackjack_player.hands << @@test_5
# assert blackjack_player.blackjack?
# blackjack_player.reset
# blackjack_player.hands << @@test_J
# blackjack_player.hands << @@test_Q
# assert blackjack_player.blackjack?
end
def test_burst?
burst_player = Player.new
burst_player.hands << @@test_J
burst_player.hands << @@test_J
burst_player.hands << @@test_5
burst_player.total_score_calc
burst_player.total_score
assert burst_player.burst?
# false
# burst_player.reset
# burst_player.hands << @@test_10
# burst_player.total_score
# assert burst_player.burst?
end
def test_total_score_calc
total_score_calc_player = Player.new
total_score_calc_player.hands << @@test_10
total_score_calc_player.hands << @@test_5
total_score_calc_player.total_score_calc
assert_equal 15, total_score_calc_player.total_score
total_score_calc_player.reset
total_score_calc_player.hands << @@test_A
total_score_calc_player.hands << @@test_10
total_score_calc_player.hands << @@test_5
total_score_calc_player.total_score_calc
assert_equal 16, total_score_calc_player.total_score
total_score_calc_player.reset
total_score_calc_player.hands << @@test_A
total_score_calc_player.hands << @@test_J
assert_equal 20, total_score_calc_player.total_score_calc
total_score_calc_player.hands << @@test_5
assert_equal 16, total_score_calc_player.total_score_calc
total_score_calc_player.hands << @@test_A
assert_equal 17, total_score_calc_player.total_score_calc
# false
#assert_equal 10, total_score_calc_player.total_score
end
def test_convert
assert_equal 10, @@test_J.convert
assert_equal 10, @@test_Q.convert
assert_equal 10, @@test_K.convert
assert_equal 10, @@test_A.convert
assert_equal 5, @@test_5.convert
end
def test_draw_count
deck = Deck.new
assert_equal 1, @@test_player.draw
assert_equal 2, @@test_player.draw
assert_equal 3, @@test_player.draw
end
def test_a_count
a_player = Player.new
a_player.hands << @@test_A
a_player.hands << @@test_A
a_player.hands << @@test_A
assert_equal 3, a_player.a_count
end
def test_bet_calc
#assert_equal 19000, @@test_player.bet_calc(1000)
end
def test_bet_judge
p @@test_player.money.stock -= 250 # ベット
assert_equal 20250, @@test_player.bet_judge(250, :win)
assert_equal 19750, @@test_player.bet_judge(250, :lose)
assert_equal 20500, @@test_player.bet_judge(250, :blackjack)
assert_equal 20000, @@test_player.bet_judge(250, :draw)
end
end