Intro to Ruby & Web Dev: Blackjack OO Game
25 Sep 2014
Object Oriented Blackjack Game
- Abstraction - the interaction of objects (keeping track of state and behaviors
- Encapsulation - encapsulates certain behaviors
Steps
- Look at the Requirements
- Pick nouns
- Think off all actions you want the object to perform and write down method calls (i.e. player.deal) as though the methods already exists.
- Do this for each class.
class Card
attr_accessor :suit, :face_value
def initialize(s,fv)
@suit = s
@face_value = fv
end
def pretty_output
"The #{face_value} of #{find_suit}"
end
def to_s
pretty_output
end
def find_suit
ret_val = case suit
when 'H' then 'Hearts'
when 'D' then 'Diamonds'
when 'S' then 'Spades'
when 'C' then 'Clubs'
end
ret_val
end
end
class Deck
attr_accessor :cards
def initialize
@cards = []
['H', 'D', 'S', 'C'].each do |suit|
['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A'].each do |face_value|
@cards << Card.new(suit, face_value)
end
end
scramble!
end
def scramble!
cards.shuffle!
end
def deal_one
cards.pop
end
def size
cards.size
end
end
module Hand
def show_hand
puts "---- #{name}'s Hand ----"
cards.each do|card|
puts "=> #{card}"
end
puts "=> Total: #{total}"
end
def total
face_values = cards.map{|card| card.face_value }
total = 0
face_values.each do |val|
if val == "A"
total += 11
else
total += (val.to_i == 0 ? 10 : val.to_i)
end
end
#correct for Aces
face_values.select{|val| val == "A"}.count.times do
break if total <= 21
total -= 10
end
total
end
def add_card(new_card)
cards << new_card
end
def is_busted?
total > Blackjack::BLACKJACK_AMOUNT
end
end
class Player
include Hand
attr_accessor :name, :cards
def initialize(n)
@name = n
@cards = []
end
def show_flop
show_hand
end
end
class Dealer
include Hand
attr_accessor :name, :cards
def initialize
@name = "Dealer"
@cards = []
end
def show_flop
puts "---- Dealer's Hand ----"
puts "=> First card is hidden"
puts "=> Second card is #{cards[1]}"
end
end
class Blackjack
attr_accessor :deck, :player, :dealer
BLACKJACK_AMOUNT = 21
DEALER_HIT_MIN = 17
def initialize
@deck = Deck.new
@player = Player.new("Player1")
@dealer = Dealer.new
end
def set_player_name
puts "What's your name?"
player.name = gets.chomp
end
def deal_cards
player.add_card(deck.deal_one)
dealer.add_card(deck.deal_one)
player.add_card(deck.deal_one)
dealer.add_card(deck.deal_one)
end
def show_flop
player.show_flop
dealer.show_flop
end
def blackjack_or_bust?(player_or_dealer)
if player_or_dealer.total == BLACKJACK_AMOUNT
if player_or_dealer.is_a?(Dealer)
puts "Sorry, dealer hit blackjack. #{player.name} loses."
else
puts "Congratulations, you hit blackjack! #{player.name} win!"
end
play_again?
elsif player_or_dealer.is_busted?
if player_or_dealer.is_a?(Dealer)
puts "Congratulations, dealer busted. #{player.name} win!"
else
puts "Sorry, #{player.name} busted. #{player.name} loses."
end
play_again?
end
end
def player_turn
puts "#{player.name}'s turn."
blackjack_or_bust?(player)
while !player.is_busted?
puts "What would you like to do? 1) hit 2) stay"
response = gets.chomp
if !['1', '2'].include?(response)
puts "Error: you must enter 1 or 2"
next
end
if response == '2'
puts "#{player.name} chose to stay."
break
end
#hit
new_card = deck.deal_one
puts "Dealing card to #{player.name}: #{new_card}"
player.add_card(new_card)
puts "#{player.name}'s total is now: #{player.total}"
blackjack_or_bust?(player)
end
puts "#{player.name} stays at #{player.total}."
end
def dealer_turn
puts "Dealer's turn."
blackjack_or_bust?(dealer)
while dealer.total < DEALER_HIT_MIN
new_card = deck.deal_one
puts "Dealing card to dealer: #{new_card}"
dealer.add_card(new_card)
puts "Dealer total is now: #{dealer.total}"
blackjack_or_bust?(dealer)
end
puts "Dealer stays at #{dealer.total}."
end
def who_won?
if player.total > dealer.total
puts "Congratulations, #{player.name} wins!"
elsif player.total < dealer.total
puts "Sorry, #{player.name} loses."
else
puts "It's a tie!"
end
play_again?
end
def play_again?
puts ""
puts "Would you like to play again? 1) yes 2) no, exit"
if gets.chomp == '1'
puts "Starting new game..."
puts ""
deck = Deck.new
player.cards = []
dealer.cards = []
start
else
puts "Goodbye!"
exit
end
end
def start
set_player_name
deal_cards
show_flop
player_turn
dealer_turn
who_won?
end
end
game = Blackjack.new
game.start