Last active
August 27, 2018 18:25
-
-
Save W-Mills/8e86f9940fbabeff1d3d93fc328bca49 to your computer and use it in GitHub Desktop.
Version 1.0.0 of text-based card game twenty one written in Ruby
This file contains 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
SUITS = %w[C H D S] | |
SUITS_HASH = { 'C' => 'Clubs', | |
'H' => 'Hearts', | |
'D' => 'Diamonds', | |
'S' => 'Spades' } | |
DEALER_STOPS_AT = 17 | |
BUST_IF_OVER = 21 | |
def prompt(msg) | |
puts "==> #{msg}" | |
end | |
def init_deck(dck, suit) | |
dck = %w[Ace 2 3 4 5 6 7 8 9 10 Jack Queen King] | |
fresh_deck = suit.map do |suits| | |
dck.map do |value| | |
[suits, value] | |
end | |
end | |
fresh_deck.flatten(1) | |
end | |
def deal_card(dck) | |
card = dck.sample | |
dck.delete_if { |element| element == card } | |
card | |
end | |
def hit_or_stay_validation(hand, player, answer) | |
loop do | |
show_hand(hand, player) | |
prompt "Enter 'h' to hit, 's' to stay." | |
answer = gets.chomp.downcase | |
break if answer =~ /[sh]/ && answer.length == 1 | |
prompt "INVALID INPUT. Enter 'h' to hit, 's' to stay." | |
end | |
answer | |
end | |
def hit_or_stay?(hand, deck, player) | |
answer = '' | |
loop do | |
answer = hit_or_stay_validation(hand, player, answer) | |
system('clear') || system('cls') | |
hand << deal_card(deck) if answer[0] == 'h' | |
if answer[0] == 's' | |
answer = 'stay' | |
system('clear') || system('cls') | |
break | |
elsif busted?(hand) | |
answer = 'busted' | |
break | |
end | |
end | |
answer | |
end | |
def cmp_hit_or_stay(hand) | |
vlu = calculate_hand_value(hand) | |
if busted?(hand) | |
return 'busted' | |
elsif vlu < DEALER_STOPS_AT | |
return 'hit' | |
else | |
return 'stay' | |
end | |
end | |
def busted?(hand) | |
calculate_hand_value(hand) > BUST_IF_OVER | |
end | |
def translate_cards(cards) | |
translated = cards.map { |suit, num| [num, SUITS_HASH[suit]] } | |
translated = translated.map { |card| "a #{card[0]} of #{card[1]}" } | |
joinand(translated, ', ') | |
end | |
def joinand(arr, delimiter=', ', word='and') | |
case arr.size | |
when 0 then '' | |
when 1 then arr.first | |
when 2 then arr.join(" #{word} ") | |
else | |
arr[-1] = "#{word} #{arr.last}" | |
arr.join(delimiter) | |
end | |
end | |
def show_hand(hand, player) | |
puts | |
if player == 'You' | |
prompt "#{player} have: #{translate_cards(hand)}." | |
prompt "(#{calculate_hand_value(hand)})" | |
elsif player == 'Dealer' | |
prompt "#{player} has: #{translate_cards(hand)}." | |
end | |
puts | |
end | |
def calculate_hand_value(hand) | |
values = hand.map { |card| card[1] } | |
sum = 0 | |
values.each do |value| | |
sum += if value == "Ace" | |
11 | |
elsif value.to_i == 0 | |
10 | |
else | |
value.to_i | |
end | |
end | |
sum += correct_for_aces(values, sum) | |
sum | |
end | |
def correct_for_aces(values, sum) | |
correction = 0 | |
values.select { |value| value == "Ace" }.count.times do | |
correction -= 10 if sum > BUST_IF_OVER | |
end | |
correction | |
end | |
def tie_game?(player_hand, computer_hand) | |
return true if busted?(player_hand) && busted?(computer_hand) || | |
player_hand == computer_hand | |
end | |
def who_wins(player, player_hand, computer, computer_hand) | |
plyr_value = calculate_hand_value(player_hand) | |
comp_value = calculate_hand_value(computer_hand) | |
return "tie game" if tie_game?(player_hand, computer_hand) | |
if busted?(player_hand) | |
computer | |
elsif busted?(computer_hand) | |
player | |
elsif plyr_value > comp_value | |
player | |
elsif plyr_value < comp_value | |
computer | |
end | |
end | |
def display_winner(winner) | |
if winner == 'You' | |
prompt "#{winner} win the round!" | |
elsif winner == 'Dealer' | |
prompt "#{winner} wins the round!" | |
else | |
prompt "It was a tie game." | |
end | |
end | |
def press_enter | |
prompt 'Press enter to continue...' | |
gets.chomp | |
system('clear') || system('cls') | |
end | |
def display_score(score) | |
prompt "SCORE: | |
Player: #{score[:player]} | |
Dealer: #{score[:dealer]} | |
" | |
end | |
def increment_score(winner, scoreboard) | |
if winner == 'You' | |
scoreboard[:player] += 1 | |
elsif winner == 'Dealer' | |
scoreboard[:dealer] += 1 | |
end | |
end | |
def print_staying_hand(player, hand) | |
if player == 'Dealer' | |
# rubocop:disable LineLength | |
prompt "#{player} stays with a hand value of: #{calculate_hand_value(hand)}." | |
elsif player == 'You' | |
prompt "#{player} decided to stay with a hand value of: #{calculate_hand_value(hand)}." | |
# rubocop:enable LineLength | |
end | |
puts | |
press_enter | |
end | |
current_deck = [] | |
player_name = 'You' | |
computer_name = 'Dealer' | |
score_count = { player: 0, dealer: 0 } | |
loop do | |
system('clear') || system('cls') | |
player_hand = [] | |
computer_hand = [] | |
current_deck = init_deck(current_deck, SUITS) | |
puts | |
2.times { player_hand << deal_card(current_deck) } | |
computer_hand << deal_card(current_deck) | |
prompt "Dealer hand: #{translate_cards(computer_hand)} and an unknown card." | |
computer_hand << deal_card(current_deck) | |
loop do | |
player_result = hit_or_stay?(player_hand, current_deck, player_name) | |
case player_result | |
when 'busted' | |
show_hand(player_hand, player_name) | |
prompt 'YOU BUSTED.' | |
press_enter | |
break | |
when 'stay' | |
print_staying_hand(player_name, player_hand) | |
break | |
end | |
end | |
loop do | |
cmp_play = cmp_hit_or_stay(computer_hand) | |
case cmp_play | |
when 'hit' | |
computer_hand << deal_card(current_deck) | |
when 'stay' | |
print_staying_hand(computer_name, computer_hand) | |
break | |
when 'busted' | |
prompt "Dealer BUSTED." | |
press_enter | |
break | |
end | |
end | |
winner = who_wins(player_name, player_hand, computer_name, computer_hand) | |
display_winner(winner) | |
increment_score(winner, score_count) | |
display_score(score_count) | |
press_enter | |
break if score_count.values.include?(5) | |
end | |
prompt "#{score_count.key(5).capitalize} is the grand winner!" | |
prompt "Thank you for playing 21!" | |
puts |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment