Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 115 additions & 28 deletions blackjack.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,13 @@ def value
end

def to_s
"#{@value}-#{suit}"
"#{@value}#{suit.to_s.chr.capitalize}"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

chr works (I tried it :) ) but its a tad confusing. maybe

"#{@value}#{suit.to_s[0].capitalize}" makes more sense

And, this also works, but I'm not sure if its easier or harder to understand

`"#{@value}#{suit[0].capitalize}"

end

# def inspect
# "#{@value}#{suit.to_s.chr.capitalize}"
# end

end


Expand Down Expand Up @@ -47,6 +51,7 @@ class Hand
def initialize
@cards = []
end

def hit!(deck)
@cards << deck.cards.shift
end
Expand All @@ -55,16 +60,16 @@ def value
cards.inject(0) {|sum, card| sum += card.value }
end

def play_as_dealer(deck)
if value < 16
def play_as_dealer(deck,player_value)
if value < 16 || value < player_value
hit!(deck)
play_as_dealer(deck)
play_as_dealer(deck,player_value)
end
end
end

class Game
attr_reader :player_hand, :dealer_hand
attr_reader :player_hand, :dealer_hand, :deck
def initialize
@deck = Deck.new
@player_hand = Hand.new
Expand All @@ -73,13 +78,28 @@ def initialize
2.times { @dealer_hand.hit!(@deck) }
end

def show(hand,all)
str_cards = ""
if all == true
hand.cards.each { |card| str_cards += "#{card.to_s} " }
else
str_cards += "XX #{hand.cards[1].to_s}"
end
str_cards
end

def hit
@player_hand.hit!(@deck)
@player_hand.value > 21 ? stand : "Player: #{show(@player_hand,true)} value: #{@player_hand.value}"
end

def stand
@dealer_hand.play_as_dealer(@deck)
@winner = determine_winner(@player_hand.value, @dealer_hand.value)
if @player_hand.value > 21
@winner = determine_winner(@player_hand.value, @dealer_hand.value)
else
@dealer_hand.play_as_dealer(@deck,@player_hand.value)
@winner = determine_winner(@player_hand.value, @dealer_hand.value)
end
end

def status
Expand All @@ -91,19 +111,19 @@ def status
end

def determine_winner(player_value, dealer_value)
return :dealer if player_value > 21
return :player if dealer_value > 21
return "Dealer Won! Player: #{show(@player_hand,true)} value: #{@player_hand.value}, Dealer: #{show(@dealer_hand,true)} value: #{@dealer_hand.value}" if player_value > 21
return "Player Won! Player: #{show(@player_hand,true)} value: #{@player_hand.value}, Dealer: #{show(@dealer_hand,true)} value: #{@dealer_hand.value}" if dealer_value > 21
if player_value == dealer_value
:push
"Push Player: #{show(@player_hand,true)} value: #{@player_hand.value}, Dealer: #{show(@dealer_hand,true)} value: #{@dealer_hand.value}"
elsif player_value > dealer_value
:player
"Player Won! Player: #{show(@player_hand,true)} value: #{@player_hand.value}, Dealer: #{show(@dealer_hand,true)} value: #{@dealer_hand.value}"
else
:dealer
"Dealer Won! Player: #{show(@player_hand,true)} value: #{@player_hand.value}, Dealer: #{show(@dealer_hand,true)} value: #{@dealer_hand.value}"
end
end

def inspect
status
"Player: #{show(@player_hand,true)} value: #{@player_hand.value}, Dealer: #{show(@dealer_hand,false)} value: #{@dealer_hand.cards[1].value}"
end
end

Expand Down Expand Up @@ -135,7 +155,7 @@ def inspect

it "should be formatted nicely" do
card = Card.new(:diamonds, "A")
card.to_s.should eq("A-diamonds")
card.to_s.should eq("AD")
end
end

Expand All @@ -156,7 +176,7 @@ def inspect
describe Hand do

it "should calculate the value correctly" do
deck = mock(:deck, :cards => [Card.new(:clubs, 4), Card.new(:diamonds, 10)])
deck = double(:deck, :cards => [Card.new(:clubs, 4), Card.new(:diamonds, 10)])
hand = Hand.new
2.times { hand.hit!(deck) }
hand.value.should eq(14)
Expand All @@ -167,37 +187,53 @@ def inspect
diamond7 = Card.new(:diamonds, 7)
clubK = Card.new(:clubs, "K")

deck = mock(:deck, :cards => [club4, diamond7, clubK])
deck = double(:deck, :cards => [club4, diamond7, clubK])
hand = Hand.new
2.times { hand.hit!(deck) }
hand.cards.should eq([club4, diamond7])

end

describe "#play_as_dealer" do
it "should hit blow 16" do
deck = mock(:deck, :cards => [Card.new(:clubs, 4), Card.new(:diamonds, 4), Card.new(:clubs, 2), Card.new(:hearts, 6)])
it "should hit below 16" do
deck = double(:deck, :cards => [Card.new(:clubs, 4), Card.new(:diamonds, 4), Card.new(:clubs, 2), Card.new(:hearts, 6)])
hand = Hand.new
player_value = 16
2.times { hand.hit!(deck) }
hand.play_as_dealer(deck)
hand.play_as_dealer(deck,player_value)
hand.value.should eq(16)
end
it "should not hit above" do
deck = mock(:deck, :cards => [Card.new(:clubs, 8), Card.new(:diamonds, 9)])
it "should not hit above player value" do
deck = double(:deck, :cards => [Card.new(:clubs, 8),
Card.new(:diamonds, 9),
Card.new(:hearts, 2)])
hand = Hand.new
player_value = 17
2.times { hand.hit!(deck) }
hand.play_as_dealer(deck)
hand.play_as_dealer(deck,player_value)
hand.value.should eq(17)
end
it "should stop on 21" do
deck = mock(:deck, :cards => [Card.new(:clubs, 4),
deck = double(:deck, :cards => [Card.new(:clubs, 4),
Card.new(:diamonds, 7),
Card.new(:clubs, "K")])
hand = Hand.new
2.times { hand.hit!(deck) }
hand.play_as_dealer(deck)
player_value = 20
hand.play_as_dealer(deck,player_value)
hand.value.should eq(21)
end
it "should hit below player value" do
deck = double(:deck, :cards => [Card.new(:clubs, 8),
Card.new(:diamonds, 8),
Card.new(:spades, 2),
Card.new(:hearts, 4)])
hand = Hand.new
player_value = 17
2.times { hand.hit!(deck) }
hand.play_as_dealer(deck,player_value)
hand.value.should eq(18)
end
end
end

Expand Down Expand Up @@ -225,18 +261,69 @@ def inspect
game.status[:winner].should_not be_nil
end

it "should stand if player value is greater than 21" do
game = Game.new
next_player_value = game.player_hand.value + game.deck.cards[0].value
while next_player_value <=21
game.hit
next_player_value = game.player_hand.value + game.deck.cards[0].value
end
expect(game.hit[0...6]).to eq("Dealer")
end

describe "#show" do

it "should show the players hand" do
game = Game.new
player_cards = game.player_hand.cards
str_cards = ""
player_cards.each {|card| str_cards += "#{card.to_s} " }
expect(game.show(game.player_hand,true)).to eq(str_cards)
end

it "should show the dealers first card until stand" do
game = Game.new
dealer_cards = game.dealer_hand.cards
expect(game.show(game.dealer_hand,false)).to eq("XX #{dealer_cards[1].to_s}")
end

it "should show the players cards and dealers cards on stand" do
game = Game.new
result = game.stand
if game.dealer_hand.value > 21
expect(result).to eq("Player Won! Player: #{game.show(game.player_hand,true)} value: #{game.player_hand.value}, Dealer: #{game.show(game.dealer_hand,true)} value: #{game.dealer_hand.value}")
elsif game.player_hand.value > game.dealer_hand.value
expect(result).to eq("Player Won! Player: #{game.show(game.player_hand,true)} value: #{game.player_hand.value}, Dealer: #{game.show(game.dealer_hand,true)} value: #{game.dealer_hand.value}")
elsif game.player_hand.value == game.dealer_hand.value
expect(result).to eq("Push Player: #{game.show(game.player_hand,true)} value: #{game.player_hand.value}, Dealer: #{game.show(game.dealer_hand,true)} value: #{game.dealer_hand.value}")
else
expect(result).to eq("Dealer Won! Player: #{game.show(game.player_hand,true)} value: #{game.player_hand.value}, Dealer: #{game.show(game.dealer_hand,true)} value: #{game.dealer_hand.value}")
end
end

it "should show the players cards on hit" do
game = Game.new
result = game.hit
if game.player_hand.value > 21
expect(result).to eq("Dealer Won! Player: #{game.show(game.player_hand,true)} value: #{game.player_hand.value}, Dealer: #{game.show(game.dealer_hand,true)} value: #{game.dealer_hand.value}")
else
expect(result).to eq("Player: #{game.show(game.player_hand,true)} value: #{game.player_hand.value}")
end
end
end

describe "#determine_winner" do
it "should have dealer win when player busts" do
Game.new.determine_winner(22, 15).should eq(:dealer)
Game.new.determine_winner(22, 15)[0...6].should eq("Dealer")
end
it "should player win if dealer busts" do
Game.new.determine_winner(18, 22).should eq(:player)
Game.new.determine_winner(18, 22)[0...6].should eq("Player")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, so here you are determining if a string begins with 'Player'

In Ruby, it's normal to use regular expressions for these selections.. So to see if something starts with player

"Player: #"[/^Player/]

it's string[regex] ... and the regex is /^Player/

Here's an example of using it for control flow (if/else): http://rubyfiddle.com/riddles/06413
Here's the best thing ever for regex: http://rubular.com/r/gL40Y9l2sW

Final form:

Game.new.determine_winner(18, 22)[/^Player/].should eq("Player") 

And also with rspec magic

Game.new.determine_winner(18, 22).should match(/^Player/) 

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome, that is a lot better

end
it "should have player win if player > dealer" do
Game.new.determine_winner(18, 16).should eq(:player)
Game.new.determine_winner(18, 16)[0...6].should eq("Player")
end
it "should have push if tie" do
Game.new.determine_winner(16, 16).should eq(:push)
Game.new.determine_winner(16, 16)[0...4].should eq("Push")
end
end
end