Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Panda, Tiger, and Eagle level #1

Open
wants to merge 3 commits into from

2 participants

@HerbCSO

I've now done all three levels. However, I don't think the implementation of the Eagle level is really ideal, so I'm hoping to get some better ideas from you or the other commits. ;]

@jwo
Owner
jwo commented

Nice job on these.. The eagle is a big tough -- but I'd start with having a DealerHand and a PlayerHand --- and depending on if the player has finished, the DealerHand shows all cards, or a DownCard and Card.

blackjack.rb
@@ -225,6 +228,14 @@ def inspect
game.status[:winner].should_not be_nil
end
+ it "should #stand for the player if they bust" do
+ game = Game.new
+ while game.status[:player_value] < 21
+ game.hit
+ end
+ game.status[:winner].should_not be_nil
@jwo Owner
jwo added a note

This works --- and we didn't cover should_receive and should_not_receive, but I think that could make sense here. Just thoughts for later -- you could assert that the dealer does not receive a message to hit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@HerbCSO HerbCSO Eagle level completed
I added the Eagle level assignment. Not sure if this is really the most effective
way to do this, so more than happy for better ideas on how to implement, but this
should work.

Also replaced the test for stand for player if they bust with the should_receive
method from rspec  - very cool, thx for pointing that out jwo!
85aece4
@HerbCSO

@jwo, not sure if you saw the update to the Eagle level yet.

@jwo jwo commented on the diff
blackjack.rb
@@ -63,18 +93,35 @@ def play_as_dealer(deck)
end
end
+class PlayerHand < Hand
+end
+
+class DealerHand < Hand
+ def hit!(deck)
+ if @cards.length == 0
+ downcard = deck.cards.shift
+ @cards << DownCard.new(downcard.suit, downcard.value)
+ else
+ @cards << deck.cards.shift
+ end
+ end
+end
+
class Game
attr_reader :player_hand, :dealer_hand
def initialize
@deck = Deck.new
@player_hand = Hand.new
@jwo Owner
jwo added a note

You probably want to use a PlayerHand here (or not have a PlayerHand class)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
blackjack.rb
@@ -56,6 +85,7 @@ def value
end
def play_as_dealer(deck)
+ @cards.each { |card| card.game_done }
@jwo Owner
jwo added a note

Since game_done is a "destructive" method, you probably want to signify that with game_done! .. the bang at the end of a method indicates (by convention) that this is unsafe.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@jwo
Owner
jwo commented

Great job! Looks good -- I added some comments, but your code got the job done and looks good to maintain.

@HerbCSO

Thanks @jwo - I decided to remove PlayerHand since it wasn't really needed anymore and I changed #game_done to #game_done! - forgot the convention there, thanks!

I'm looking forward to seeing more elegant solutions than mine. ;]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Aug 5, 2012
  1. @HerbCSO
Commits on Aug 7, 2012
  1. @HerbCSO

    Eagle level completed

    HerbCSO authored
    I added the Eagle level assignment. Not sure if this is really the most effective
    way to do this, so more than happy for better ideas on how to implement, but this
    should work.
    
    Also replaced the test for stand for player if they bust with the should_receive
    method from rspec  - very cool, thx for pointing that out jwo!
Commits on Aug 8, 2012
  1. @HerbCSO
This page is out of date. Refresh to see the latest.
Showing with 102 additions and 3 deletions.
  1. +102 −3 blackjack.rb
View
105 blackjack.rb
@@ -5,6 +5,7 @@ class Card
def initialize(suit, value)
@suit = suit
@value = value
+ @game_done = false
end
def value
@@ -14,7 +15,35 @@ def value
end
def to_s
- "#{@value}-#{suit}"
+ "#{suit.to_s[0].capitalize}#{@value}"
+ end
+
+ def game_done!
+ @game_done = true
+ end
+
+end
+
+
+class DownCard < Card
+ def initialize(suit, value)
+ super(suit, value)
+ end
+
+ def value
+ if @game_done
+ super
+ else
+ 0
+ end
+ end
+
+ def to_s
+ if @game_done
+ super
+ else
+ "XX"
+ end
end
end
@@ -56,6 +85,7 @@ def value
end
def play_as_dealer(deck)
+ @cards.each { |card| card.game_done! }
if value < 16
hit!(deck)
play_as_dealer(deck)
@@ -63,18 +93,32 @@ def play_as_dealer(deck)
end
end
+class DealerHand < Hand
+ def hit!(deck)
+ if @cards.length == 0
+ downcard = deck.cards.shift
+ @cards << DownCard.new(downcard.suit, downcard.value)
+ else
+ @cards << deck.cards.shift
+ end
+ end
+end
+
class Game
attr_reader :player_hand, :dealer_hand
def initialize
@deck = Deck.new
@player_hand = Hand.new
@jwo Owner
jwo added a note

You probably want to use a PlayerHand here (or not have a PlayerHand class)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
- @dealer_hand = Hand.new
+ @dealer_hand = DealerHand.new
2.times { @player_hand.hit!(@deck) }
2.times { @dealer_hand.hit!(@deck) }
end
def hit
@player_hand.hit!(@deck)
+ if status[:player_value] > 21 then
+ stand
+ end
end
def stand
@@ -135,7 +179,32 @@ 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("DA")
+ end
+end
+
+
+describe DownCard do
+ it "should show XX before the game is done" do
+ downcard = DownCard.new(:diamonds, "K")
+ downcard.to_s.should eq("XX")
+ end
+
+ it "should show the actual card after the game is done" do
+ downcard = DownCard.new(:diamonds, "K")
+ downcard.game_done!
+ downcard.to_s.should eq("DK")
+ end
+
+ it "should return a value of 0 before the game is done" do
+ downcard = DownCard.new(:hearts, 9)
+ downcard.value.should eq(0)
+ end
+
+ it "should return the actual value after the game is done" do
+ downcard = DownCard.new(:hearts, 9)
+ downcard.game_done!
+ downcard.value.should eq(9)
end
end
@@ -202,6 +271,17 @@ def inspect
end
+describe DealerHand do
+ describe "#hit!" do
+ it "should have a downcard on the first hit" do
+ deck = Deck.new
+ dealer_hand = DealerHand.new.hit!(deck)
+ dealer_hand[0].to_s.should eq("XX")
+ end
+ end
+end
+
+
describe Game do
it "should have a players hand" do
@@ -225,6 +305,25 @@ def inspect
game.status[:winner].should_not be_nil
end
+ it "should not show the full dealer hand before the game is done" do
+ game = Game.new
+ game.status[:dealer_cards].to_s.should include("XX")
+ end
+
+ it "should show the full dealer hand after the game is done" do
+ game = Game.new
+ game.stand
+ game.status[:dealer_cards].to_s.should_not include("XX")
+ end
+
+ it "should #stand for the player if they bust" do
+ game = Game.new
+ game.should_receive(:stand)
+ while game.status[:player_value] <= 21
+ game.hit
+ end
+ end
+
describe "#determine_winner" do
it "should have dealer win when player busts" do
Game.new.determine_winner(22, 15).should eq(:dealer)
Something went wrong with that request. Please try again.