Last active
March 17, 2019 12:46
-
-
Save obelisk68/7d7e32833ad780495c56d735390840ee to your computer and use it in GitHub Desktop.
カードゲーム「ブラックジャック」の実装
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
deck = nil #カードの山 | |
shuffle = lambda do | |
print "カードをシャッフルします\n\n" | |
deck = 4.times.flat_map {|i| (1..13).map {|j| i * 100 + j} }.shuffle | |
end | |
# 一回の勝負 | |
game = lambda do | |
dealer, player = [], [] | |
show_card = ->(card) { | |
suit = %W(♠ ♣ ♥ ♦) | |
efuda = %W(J Q K) | |
a = card % 100 | |
i = case | |
when a == 1 then "A" | |
when a > 10 then efuda[a - 11] | |
else a.to_s | |
end | |
suit[card / 100] + i | |
} | |
# cardsの得点を返す | |
point = ->(cards) { | |
result = 0 | |
cards = cards.map {|c| c % 100} | |
n = cards.count(1) | |
cards -= [1] | |
cards.each {|c| result += (c > 10) ? 10 : c} | |
return result if n.zero? | |
result1 = result + n | |
result2 = result + n + 10 | |
(result2 <= 21) ? result2 : result1 | |
} | |
is_natural21 = ->(person, cards) { | |
if point.(cards) == 21 | |
puts "#{person}はナチュラル21です" | |
true | |
else | |
false | |
end | |
} | |
get_card = ->(person) { | |
if deck.empty? | |
puts "(カードがなくなりました)" | |
shuffle.() | |
deck = deck - dealer - player | |
end | |
card = deck.shift | |
puts "#{person}の引いたカードは #{show_card.(card)} です" | |
card | |
} | |
puts "=== カードを配ります ====" | |
dealer = deck.shift(2) | |
puts "ディーラーの一枚は #{show_card.(dealer[0])} です" | |
player = deck.shift(2) | |
puts "プレイヤーの二枚は #{show_card.(player[0])} と #{show_card.(player[1])} です" | |
#ナチュラル21の判定 | |
p0 = is_natural21.("プレイヤー", player) | |
p1 = is_natural21.("ディーラー", dealer) | |
puts "ディーラーのもう一枚は #{show_card.(dealer[1])} です" if p1 | |
case | |
when p0 and p1 then return 0 | |
when p0 then return 2.5 | |
when p1 then return -1 | |
end | |
#プレイヤーの選択とディーラーの処理 | |
select_by_player = proc { | |
loop do | |
begin | |
print "Hit or Stand? (H or S): " | |
st = gets.chomp.downcase | |
end until st == "h" or st == "s" | |
if st == "h" | |
puts " Hitしました" | |
player << get_card.("プレイヤー") | |
if point.(player) > 21 | |
puts "プレイヤーはバーストです" | |
return -1 | |
end | |
else | |
break | |
end | |
end | |
} | |
select_by_player.() | |
puts "勝負です:" | |
puts "ディーラーのもう一枚は #{show_card.(dealer[1])} です" | |
point_of_player = point.(player) | |
point_of_dealer = point.(dealer) | |
while point_of_dealer < 17 | |
puts " ディーラーはもう一枚引きます" | |
sleep(2) | |
dealer << get_card.("ディーラー") | |
point_of_dealer = point.(dealer) | |
end | |
#勝ち負けの判定(正ならばプレイヤーの勝ち、負ならばディーラーの勝ち、0で引き分け) | |
puts "ディーラーの合計は #{point_of_dealer}、プレイヤーの合計は #{point_of_player} です" | |
case | |
when point_of_dealer > 21 then 2 | |
when point_of_dealer == point_of_player then 0 | |
when point_of_player > point_of_dealer then 2 | |
else -1 | |
end | |
end | |
main = lambda do | |
coin = 10000 | |
get_bet = ->{ | |
print "コイン: #{coin} 点 " | |
loop do | |
print "ベットは?(enter = 1000):" | |
st = gets | |
if st == "\n" and coin >= 1000 | |
puts " ベットは 1000 点です" | |
return 1000 | |
end | |
bet = st.chomp.to_i | |
if bet < 0 | |
puts "\nプレイヤーの点数が #{coin} 点で終了します" | |
exit | |
end | |
return bet if 0 < bet and bet <= coin | |
end | |
} | |
shuffle.() | |
# メインループ | |
while coin > 0 | |
shuffle.() if deck.size < 15 | |
bet = get_bet.() | |
coin -= bet | |
result = game.() | |
case | |
when result.zero? | |
puts "引き分けです" | |
coin += bet | |
when result > 0 | |
puts "プレイヤーの勝ちです" | |
coin += (bet * result).to_i | |
else | |
puts "ディーラーの勝ちです" | |
end | |
print "** コインは #{coin} 点です\n\n" | |
end | |
puts "コインがなくなりました" | |
end | |
main.() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment