Skip to content

Instantly share code, notes, and snippets.

@nfriend21
Created November 23, 2012 17:15
Show Gist options
  • Save nfriend21/4136527 to your computer and use it in GitHub Desktop.
Save nfriend21/4136527 to your computer and use it in GitHub Desktop.
21
#start a new game by calling Game.new with player names as params, i.e. g = Game.new("Nick", "Mike")
#the Game object will contain the deck & the players.
#A new Deck will be automatically reloaded as soon as all cards are gone.
#As a result, you can play endless hands of blackjack.
SUITS = %w{clubs hearts spades diamonds}
VALUES = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"]
AMOUNTS = [2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 11]
Card = Struct.new(:value, :suit, :amount)
def prompt
print "> "
end
class Deck < Array
attr_accessor :deck
def initialize
SUITS.each do |suit|
VALUES.each_with_index do |value, index|
self << Card.new(value, suit, AMOUNTS[index])
end
end
self.shuffle_cards
end
def shuffle_cards
self.shuffle!
end
end
class Game
attr_accessor :deck, :game
def initialize(names)
@deck = Deck.new
@game = {}
add_players(names)
end
def add_players(names)
names.each do |name|
@game["player_#{name}"] = Player.new("#{name}")
end
end
def load_new_deck
@deck = Deck.new
end
def initial_deal
@game.each_key do |player|
2.times do
if @deck.empty? == true
load_new_deck
@game[player].hand << @deck.pop
else
@game[player].hand << @deck.pop
end
end
end
return @game
end
def card_count(player)
card_count = 0
@game[player].hand.each do |card|
card_count += card.amount
end
card_count
end
def play_hand
deal_new_hand
player_actions
determine_winning_hand
scoreboard
play_more_or_exit
end
def player_actions
@game.each_key do |player|
hand_count = card_count(player)
puts "----- #{@game[player].name}'s turn ------"
puts "#{@game[player].name} has blackjack!" if hand_count == 21
while hand_count < 21
puts "hit or stand?"
action = gets.chomp
if action == "hit"
puts "#{@game[player].name} hits."
hit(player)
hand_count = card_count(player)
elsif action == "stand"
break stand(player)
else
puts "sorry. please type hit or stand:"
end
end
if hand_count > 21
puts "#{@game[player].name} busts!"
end
@game[player].final_hand_count = hand_count
@game[player].final_hand_count = 0 if hand_count > 21
end
end
def dealer_actions
@game.each_key do |player|
hand_count = card_count(player)
puts "\n\n----- #{@game[player].name}'s turn ------"
until hand_count > 16
puts "#{@game[player].name} hits."
hit(player)
hand_count = card_count(player)
end
if hand_count > 21
puts "#{@game[player].name} busts!"
elsif hand_count == 21
puts "#{@game[player].name} has blackjack!"
elsif hand_count < 21
stand(player)
end
@game[player].final_hand_count = hand_count
@game[player].final_hand_count = 0 if hand_count > 21
end
end
def deal_new_hand
@game.each_key do |player|
@game[player].hand.clear
end
initial_deal
puts "---- Initial Deal ----"
@game.each_key do |player|
puts "#{@game[player].name} was dealt #{card_count(player)}"
end
end
def determine_winning_hand
highest_hand = 0
winner = "TBD"
@game.each_key do |player|
puts "#{@game[player].name}'s final hand is #{@game[player].final_hand_count}"
if @game[player].final_hand_count > highest_hand
highest_hand = @game[player].final_hand_count
winner = @game[player]
end
end
if highest_hand == 0
puts "\n==== Both hands busted! No winner! ===="
else
puts "\n==== the winner is #{winner.name}. ===="
winner.total_score += 1
end
end
def scoreboard
puts "\n************ SCOREBOARD"
@game.each_key do |player|
puts "#{@game[player].name}'s total score is #{@game[player].total_score}"
end
end
def play_more_or_exit
puts "play another hand?"
prompt
response = gets.chomp
if response == "y" || response == "yes"
play_hand
else
Process.exit
end
end
def hit(player)
if @deck.empty? == true
load_new_deck
puts "Loading a new deck."
end
new_card = @deck.pop
@game[player].hand << new_card
puts "#{@game[player].name} receives a new card: #{new_card.value} of #{new_card.suit}"
end
def stand(player)
puts "#{@game[player].name} stands."
end
end
class Player
attr_accessor :name, :hand, :final_hand_count, :total_score
def initialize(name)
@name = name
@hand = []
@final_hand_count = 0
@total_score = 0
end
def hand_count
hand_count = 0
@hand.each do |card|
hand_count += card.amount
end
return hand_count
end
end
print "Name each player, separated by a comma"
prompt
names = gets.chomp.split(',').collect(&:strip)
g = Game.new(names)
g.play_hand
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment