Permalink
Browse files

CardParser

  • Loading branch information...
camillebaldock committed Sep 7, 2014
1 parent 8068fac commit 2e4dc547bc9b7e40981baf719e2f418c468221a9
Showing with 110 additions and 39 deletions.
  1. +4 −0 README.md
  2. +26 −0 lib/card_parser.rb
  3. +4 −1 lib/hand.rb
  4. +6 −17 lib/hand_parser.rb
  5. +58 −0 spec/card_parser_spec.rb
  6. +10 −20 spec/hand_parser_spec.rb
  7. +2 −1 spec/hand_spec.rb
View
@@ -27,3 +27,7 @@ The consecutive_cards? methods is mainly checking whether an array is made of co
The HandParser now gets initialized with an array of card strings and fails if the array is the wrong size.
6) Address the ```#TODO: this is not a nice interface``` comment
+
+7) Open closed principle: move logic to CardParser
+New card parser and add pending tests:
+#TODO: fail loudly and with better errors with unexpected inputs
View
@@ -0,0 +1,26 @@
+class CardParser
+
+ SUITS = {
+ "h" => :hearts,
+ "d" => :diamonds,
+ "s" => :spades,
+ "c" => :clubs
+ }
+
+ PIPS_FOR_HEADS = {
+ "j" => 11,
+ "q" => 12,
+ "k" => 13,
+ "a" => 14
+ }
+
+ def parse(card_string)
+ end_of_card_number_index = (card_string.length)-2
+ pips_string = card_string[0..end_of_card_number_index]
+ number_of_pips = PIPS_FOR_HEADS.fetch(pips_string, pips_string.to_i)
+ {
+ :pips => number_of_pips,
+ :suit => SUITS.fetch(card_string[end_of_card_number_index+1])
+ }
+ end
+end
View
@@ -4,7 +4,10 @@ class Hand
attr_reader :cards
def initialize(card_input, hand_parser)
- @cards = hand_parser.parse(card_input)
+ card_hashes = hand_parser.parse(card_input)
+ @cards = card_hashes.map do |card_hash|
+ Card.new(card_hash.fetch(:pips), card_hash.fetch(:suit))
+ end
end
def better_than?(other_hand)
View
@@ -3,28 +3,17 @@
class HandParser
+ def initialize(card_parser)
+ @card_parser = card_parser
+ end
+
def parse(array_of_string_cards)
if array_of_string_cards.size != 5
raise WrongNumberOfCardsError.new(array_of_string_cards.size)
end
- cards = array_of_string_cards.map do |card_string|
- make_card(card_string)
+ array_of_string_cards.map do |card_string|
+ @card_parser.parse(card_string)
end
end
- private
-
- SUITS = { "h" => :hearts, "d" => :diamonds,
- "s" => :spades, "c" => :clubs}
- PIPS_FOR_HEADS = { "j" => 11, "q" => 12, "k" => 13, "a" => 14}
-
- #TODO: fail loudly and with better errors with unexpected inputs
- #assumes correct capitalisation, correct letters...
- def make_card(card_string)
- end_of_card_number_index = (card_string.length)-2
- pips_string = card_string[0..end_of_card_number_index]
- number_of_pips = PIPS_FOR_HEADS.fetch(pips_string, pips_string.to_i)
- Card.new(number_of_pips, SUITS.fetch(card_string[end_of_card_number_index+1]))
- end
-
end
View
@@ -0,0 +1,58 @@
+require "spec_helper"
+require "card_parser"
+
+describe CardParser do
+
+ let(:single_digit_card_string) { "5h" }
+ let(:two_digit_card_string) { "10d" }
+ let(:jack_card_string) { "jd" }
+ let(:queen_card_string) { "qc" }
+ let(:king_card_string) { "ks" }
+ let(:ace_card_string) { "ad" }
+ let(:ace_as_one_card_string) { "1h" }
+
+ it "parses a card string with a single digit number" do
+ parsed_card = described_class.new.parse(single_digit_card_string)
+ expect(parsed_card.fetch(:suit)).to eq :hearts
+ expect(parsed_card.fetch(:pips)).to eq 5
+ end
+
+ it "parses a card string with a two digit number" do
+ parsed_card = described_class.new.parse(two_digit_card_string)
+ expect(parsed_card.fetch(:suit)).to eq :diamonds
+ expect(parsed_card.fetch(:pips)).to eq 10
+ end
+
+ it "parses a jack card string" do
+ parsed_card = described_class.new.parse(jack_card_string)
+ expect(parsed_card.fetch(:suit)).to eq :diamonds
+ expect(parsed_card.fetch(:pips)).to eq 11
+ end
+
+ it "parses a queen card string" do
+ parsed_card = described_class.new.parse(queen_card_string)
+ expect(parsed_card.fetch(:suit)).to eq :clubs
+ expect(parsed_card.fetch(:pips)).to eq 12
+ end
+
+ it "parses a king card string" do
+ parsed_card = described_class.new.parse(king_card_string)
+ expect(parsed_card.fetch(:suit)).to eq :spades
+ expect(parsed_card.fetch(:pips)).to eq 13
+ end
+
+ it "parses an ace card string" do
+ parsed_card = described_class.new.parse(ace_card_string)
+ expect(parsed_card.fetch(:suit)).to eq :diamonds
+ expect(parsed_card.fetch(:pips)).to eq 14
+ end
+
+ it "parses an ace card string when it is written as a 1"
+
+ it "fails if the card string does not have a recognised suit"
+
+ it "fails if the card string is in the wrong format"
+
+ it "fails if the wrong capitalisation is used"
+
+end
View
@@ -4,41 +4,31 @@
describe HandParser do
+ let(:card_parser) { double(:card_parser, :parse => nil) }
let(:array_of_five_cards) { ["5h", "10d", "ks", "qc", "1h"] }
let(:array_of_four_cards) { ["5h", "10d", "ks", "qc"] }
describe "#initialize" do
it "succeeds with an array of five elements" do
- expect{described_class.new.parse(array_of_five_cards)}.not_to raise_error
+ expect{described_class.new(card_parser).parse(array_of_five_cards)}.not_to raise_error
end
it "fails with an array that does not have five elements" do
- expect{described_class.new.parse(array_of_four_cards)}.to raise_error(WrongNumberOfCardsError)
+ expect{described_class.new(card_parser).parse(array_of_four_cards)}.to raise_error(WrongNumberOfCardsError)
end
end
describe "#parse" do
- it "returns a hand of 5 cards" do
- parsed_cards = described_class.new.parse(array_of_five_cards)
+ it "returns an array of 5 elements" do
+ parsed_cards = described_class.new(card_parser).parse(array_of_five_cards)
expect(parsed_cards.count).to eq 5
end
- it "returns the right cards" do
- parsed_cards = described_class.new.parse(array_of_five_cards)
- expect(parsed_cards.first.suit).to eq :hearts
- expect(parsed_cards.first.pips).to eq 5
- end
-
- it "returns the right cards" do
- parsed_cards = described_class.new.parse(array_of_five_cards)
- expect(parsed_cards[1].suit).to eq :diamonds
- expect(parsed_cards[1].pips).to eq 10
- end
-
- it "returns the right cards" do
- parsed_cards = described_class.new.parse(array_of_five_cards)
- expect(parsed_cards[2].suit).to eq :spades
- expect(parsed_cards[2].pips).to eq 13
+ it "parses all the card strings" do
+ parsed_cards = described_class.new(card_parser).parse(array_of_five_cards)
+ array_of_five_cards.each do |card_string|
+ expect(card_parser).to have_received(:parse).with(card_string)
+ end
end
end
View
@@ -4,7 +4,8 @@
describe Hand do
- let(:hand_parser) { HandParser.new }
+ let(:card_parser) { CardParser.new }
+ let(:hand_parser) { HandParser.new(card_parser) }
let(:pair_hand_string_array) { ["5h", "5d", "6d", "7d", "8d"] }
let(:highest_hand_string_array) { ["4h", "5d", "6d", "7d", "9d"] }
let(:two_pair_hand_string_array) { ["4h", "4d", "6d", "6h", "9s"] }

0 comments on commit 2e4dc54

Please sign in to comment.