今日はこちらの記事を参考にしてトランプのブラック・ジャックを作ってみました。
仕様
・初期カードは52枚。引く際にカードの重複は無いようにする
・プレイヤーとディーラーの2人対戦。プレイヤーは実行者、ディーラーは自動的に実行・
・実行開始時、プレイヤーとディーラーはそれぞれ、カードを2枚引く。引いたカードは画面に表示する。ただし、ディーラーの2枚目のカードは分からないようにする
・その後、先にプレイヤーがカードを引く。プレイヤーが21を超えていたらバースト、その時点でゲーム終了
・プレイヤーは、カードを引くたびに、次のカードを引くか選択できる
・プレイヤーが引き終えたら、その後ディーラーは、自分の手札が17以上になるまで引き続ける
・プレイヤーとディーラーが引き終えたら勝負。より21に近い方の勝ち
・JとQとKは10として扱う
・Aはとりあえず「1」としてだけ扱う。「11」にはしない
・ダブルダウンなし、スプリットなし、サレンダーなし、その他特殊そうなルールなし
コード
require './black_jack/player'
require './black_jack/card'
require './black_jack/controller'
p '今からブラックジャックを始めます'
p 'ディーラーとプレイヤーに2枚ずつカードを配ります。'
@dealer = create_player
@player = create_player
p "ディーラーの#{@dealer.hand_index(0)}"
p "あなたの#{@player.hand_index(0)}"
p "あなたの#{@player.hand_index(1)}"
2.upto(15) do |i|
p 'カードを引きますか?(y/n)'
input = gets.chomp
if input == 'y'
@player.draw
p "あなたの引いたカードは#{@player.hand[i][0]}の#{@player.hand[i][1]}です"
else
break
end
if @player.card_sum > 21
p '合計が21を超えました!!!'
p 'プレイヤーの負けです!!!'
exit
end
end
p 'では、次にディーラーが引いていきたいと思います。'
while @dealer.card_sum < 17
@dealer.draw
end
p '両者引き終わりました。'
p '勝者は....'
p @player.battle(@dealer)
p 'プレイヤーのカード'
p @player.card_index
p 'ディーラーのカード'
p @dealer.card_index
require './black_jack/player'
require './black_jack/card'
def create_player
@player = Player.new
@player.draw
@player.draw
@player
end
class Card
MARK = ['spade', 'heart', 'diamond', 'club'].freeze
NUMBER = [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13
].freeze
attr_reader :mark, :number
def initialize(mark,number)
@mark = mark
@number = number
end
end
class Player
attr_reader :hand
# 引いたカードを入れる配列
def initialize
@hand = []
end
# カードを引く処理。既に持っているカードを引いたらやり直し
def draw
@hand.uniq!
card = Card.new(Card::MARK.sample, Card::NUMBER.sample)
@hand << [card.mark, card.number]
unless @hand.count == @hand.uniq.count
draw
end
@hand
end
# 手札の内容
def hand_index(i)
"#{i + 1}枚目は#{self.hand[i][0]}の#{self.hand[i][1]}です"
end
# プレイヤーのカードの合計がディーラーのカードの合計と比較する
def battle(other)
result = (card_sum - 21).abs <=> (other.card_sum - 21).abs
if result == -1
'プレイヤーです!!!'
elsif result == 0
'引き分けです!!!'
else
'ディーラーです!!!'
end
end
# カードの合計を出す。
def card_sum
sum = 0
@hand.each do |num|
if num[1] > 10
sum += 10
else
sum += num[1]
end
end
sum
end
# 手札の一覧を返す
def card_index
hand.map { |num| "#{num[0]}の#{num[1]}" }.sort.join(',')
end
end
完成動画
実際にやってみると以下のような動画になります(リンクですいません)。
トランプのブラック・ジャックを作った!!!
— あるくまくん (@kesuike713) 2019年5月26日
ルール合っているか分からないけど!!! pic.twitter.com/UAl8mQfCmv
まとめ
今回は処理と出力で別のファイルにすることを特に意識しました。
実際に出力されるのはview.rbに、処理はその他のファイルに書きました。
ただ、create_playerメソッドの為だけにlogic.rbを作る必要はなかったかな〜と反省中です。
本当はplayerのインスタンスが作成された時点でdrawメソッドを2回実行させたかったけど、どうすればいいか分かりませんでした汗
後、view.rbに少しだけ処理が残ってしまいました。
こちらも今後リファクタリング 必須ですね。
ブラック・ジャックはこちらの記事にも書いてある通り、基本的な文法が理解出来ていれば出来るので、ぜひやってみてください!!!!