fiftytwo 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.github/workflows/gem-push.yml +31 -0
- data/.github/workflows/ruby.yml +35 -0
- data/.gitignore +7 -0
- data/.rspec +2 -0
- data/.yardopts +1 -0
- data/CODE_OF_CONDUCT.md +76 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +151 -0
- data/Rakefile +7 -0
- data/fiftytwo.gemspec +34 -0
- data/lib/fiftytwo.rb +11 -0
- data/lib/fiftytwo/card.rb +60 -0
- data/lib/fiftytwo/deck.rb +33 -0
- data/lib/fiftytwo/hand.rb +9 -0
- data/lib/fiftytwo/has_cards.rb +52 -0
- data/lib/fiftytwo/rank.rb +57 -0
- data/lib/fiftytwo/suit.rb +45 -0
- data/lib/fiftytwo/suit/color.rb +23 -0
- data/lib/fiftytwo/version.rb +5 -0
- data/spec/lib/fiftytwo/card_spec.rb +95 -0
- data/spec/lib/fiftytwo/deck_spec.rb +280 -0
- data/spec/lib/fiftytwo/hand_spec.rb +7 -0
- data/spec/lib/fiftytwo/rank_spec.rb +128 -0
- data/spec/lib/fiftytwo/suit_spec.rb +107 -0
- data/spec/spec_helper.rb +16 -0
- metadata +229 -0
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "./has_cards"
|
4
|
+
|
5
|
+
module FiftyTwo
|
6
|
+
class Deck
|
7
|
+
include HasCards
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def standard
|
11
|
+
build(FiftyTwo::Rank::ALL.product(FiftyTwo::Suit::ALL))
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def build(items)
|
17
|
+
new.tap do |deck|
|
18
|
+
items.each do |rank, suit|
|
19
|
+
deck << FiftyTwo::Card.new(deck, rank, suit).freeze
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def deal(hands, hand_size: 1)
|
26
|
+
hand_size.times.each do |card_idx|
|
27
|
+
hands.each { |h| h << draw }
|
28
|
+
end
|
29
|
+
|
30
|
+
hands
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module FiftyTwo
|
4
|
+
module HasCards
|
5
|
+
extend Enumerable
|
6
|
+
attr_reader :cards
|
7
|
+
delegate :shuffle!, :sort!, :<<, :[], :each, :map, :count, :first, :last, to: :cards
|
8
|
+
|
9
|
+
CardUnavailableError = Class.new(StandardError)
|
10
|
+
|
11
|
+
def initialize(cards = [])
|
12
|
+
@cards = cards
|
13
|
+
end
|
14
|
+
|
15
|
+
def draw
|
16
|
+
cards.shift
|
17
|
+
end
|
18
|
+
|
19
|
+
def render
|
20
|
+
map(&:render).join(" ")
|
21
|
+
end
|
22
|
+
|
23
|
+
def locate(identifier)
|
24
|
+
cards.find { |c| c.identifier == identifier.upcase }
|
25
|
+
end
|
26
|
+
|
27
|
+
def transfer(card, destination = nil)
|
28
|
+
card = locate(card) unless card.is_a?(FiftyTwo::Card)
|
29
|
+
raise CardUnavailableError if card.nil?
|
30
|
+
raise CardUnavailableError unless cards.include?(card)
|
31
|
+
(destination || card.deck) << cards.delete(card)
|
32
|
+
end
|
33
|
+
|
34
|
+
FiftyTwo::Suit::ALL.each do |suit|
|
35
|
+
define_method(suit.name) { select(suit.name) }
|
36
|
+
end
|
37
|
+
|
38
|
+
FiftyTwo::Suit::Color::ALL.each do |color|
|
39
|
+
define_method(color.name.pluralize) { select(color.name) }
|
40
|
+
end
|
41
|
+
|
42
|
+
[*FiftyTwo::Rank::CATEGORIES, :jack, :king, :queen, :ace].each do |category|
|
43
|
+
define_method(category.to_s.pluralize) { select(category) }
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def select(identifier)
|
49
|
+
self.class.new(cards.select { |c| c.send("#{identifier}?") })
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module FiftyTwo
|
4
|
+
class Rank
|
5
|
+
include Comparable
|
6
|
+
CATEGORIES = %i[pip face]
|
7
|
+
|
8
|
+
attr_reader :value, :name, :category
|
9
|
+
|
10
|
+
def initialize(value, name = nil, category = :pip)
|
11
|
+
@value = value
|
12
|
+
@name = name || value.to_s
|
13
|
+
@category = category
|
14
|
+
end
|
15
|
+
|
16
|
+
ALL = [
|
17
|
+
TWO = Rank.new(2).freeze,
|
18
|
+
THREE = Rank.new(3).freeze,
|
19
|
+
FOUR = Rank.new(4).freeze,
|
20
|
+
FIVE = Rank.new(5).freeze,
|
21
|
+
SIX = Rank.new(6).freeze,
|
22
|
+
SEVEN = Rank.new(7).freeze,
|
23
|
+
EIGHT = Rank.new(8).freeze,
|
24
|
+
NINE = Rank.new(9).freeze,
|
25
|
+
TEN = Rank.new(10).freeze,
|
26
|
+
JACK = Rank.new(11, "jack", :face).freeze,
|
27
|
+
QUEEN = Rank.new(12, "queen", :face).freeze,
|
28
|
+
KING = Rank.new(13, "king", :face).freeze,
|
29
|
+
ACE = Rank.new(14, "ace").freeze
|
30
|
+
]
|
31
|
+
|
32
|
+
CATEGORIES.each do |category|
|
33
|
+
define_method("#{category}?") { self.category == category }
|
34
|
+
end
|
35
|
+
|
36
|
+
ALL.select(&:face?).each do |rank|
|
37
|
+
define_method("#{rank.name}?") { self == rank }
|
38
|
+
end
|
39
|
+
|
40
|
+
def ace?
|
41
|
+
name == "ace"
|
42
|
+
end
|
43
|
+
|
44
|
+
def <=>(other)
|
45
|
+
value <=> other.value
|
46
|
+
end
|
47
|
+
|
48
|
+
def to_s
|
49
|
+
name.titleize
|
50
|
+
end
|
51
|
+
|
52
|
+
def identifier
|
53
|
+
name.to_i > 0 ? name : name[0].upcase
|
54
|
+
end
|
55
|
+
alias_method :code, :identifier
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "./suit/color"
|
4
|
+
|
5
|
+
module FiftyTwo
|
6
|
+
class Suit
|
7
|
+
include Comparable
|
8
|
+
|
9
|
+
attr_reader :name, :color, :symbol
|
10
|
+
alias_method :code, :symbol
|
11
|
+
|
12
|
+
def initialize(name, color, symbol = nil)
|
13
|
+
@name = name
|
14
|
+
@color = color
|
15
|
+
@symbol = symbol
|
16
|
+
end
|
17
|
+
|
18
|
+
ALL = [
|
19
|
+
CLUBS = Suit.new("clubs", Color::BLACK, "♣").freeze,
|
20
|
+
DIAMONDS = Suit.new("diamonds", Color::RED, "♦").freeze,
|
21
|
+
HEARTS = Suit.new("hearts", Color::RED, "♥").freeze,
|
22
|
+
SPADES = Suit.new("spades", Color::BLACK, "♠").freeze
|
23
|
+
]
|
24
|
+
|
25
|
+
Color::ALL.each do |color|
|
26
|
+
define_method("#{color.name}?") { self.color == color }
|
27
|
+
end
|
28
|
+
|
29
|
+
ALL.each do |suit|
|
30
|
+
define_method("#{suit.name.downcase}?") { self == suit }
|
31
|
+
end
|
32
|
+
|
33
|
+
def <=>(other)
|
34
|
+
name <=> other.name
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_s
|
38
|
+
name.titleize
|
39
|
+
end
|
40
|
+
|
41
|
+
def identifier
|
42
|
+
name[0].upcase
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module FiftyTwo
|
4
|
+
class Suit
|
5
|
+
class Color
|
6
|
+
attr_reader :name, :rgb
|
7
|
+
|
8
|
+
def initialize(name, rgb)
|
9
|
+
@name = name
|
10
|
+
@rgb = rgb
|
11
|
+
end
|
12
|
+
|
13
|
+
ALL = [
|
14
|
+
RED = new("red", "ff0000"),
|
15
|
+
BLACK = new("black", "000000")
|
16
|
+
]
|
17
|
+
|
18
|
+
def ==(other)
|
19
|
+
name == other.name
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module FiftyTwo
|
4
|
+
describe Card do
|
5
|
+
let(:deck) { instance_double(FiftyTwo::Deck) }
|
6
|
+
let(:rank) { instance_double(FiftyTwo::Rank, code: "RC", identifier: "RI", to_s: "92") }
|
7
|
+
let(:suit) { instance_double(FiftyTwo::Suit, code: "SC", identifier: "SI", to_s: "Mittens") }
|
8
|
+
let(:subject) { described_class.new(deck, rank, suit) }
|
9
|
+
|
10
|
+
it "exposes its basics" do
|
11
|
+
expect(subject.deck).to eq deck
|
12
|
+
expect(subject.rank).to eq rank
|
13
|
+
expect(subject.suit).to eq suit
|
14
|
+
end
|
15
|
+
|
16
|
+
it "has a variety of serializations" do
|
17
|
+
expect(subject.code).to eq "RCSC"
|
18
|
+
expect(subject.identifier).to eq "RISI"
|
19
|
+
expect(subject.to_s).to eq "92 of Mittens"
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#render" do
|
23
|
+
let(:color) { instance_double(FiftyTwo::Suit::Color, name: "blue") }
|
24
|
+
before(:each) { allow(suit).to receive(:color).and_return color }
|
25
|
+
|
26
|
+
it "builds a proper rendering from 2 characters" do
|
27
|
+
allow(subject).to receive(:code).and_return "XY"
|
28
|
+
expect(subject.render).to eq "\e[0;34;49m XY\e[0m"
|
29
|
+
end
|
30
|
+
|
31
|
+
it "builds a proper rendering from 3 characters" do
|
32
|
+
allow(subject).to receive(:code).and_return "XYZ"
|
33
|
+
expect(subject.render).to eq "\e[0;34;49mXYZ\e[0m"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context "questions" do
|
38
|
+
before(:each) do
|
39
|
+
allow(rank).to receive(:face?).and_return "grumpy"
|
40
|
+
allow(rank).to receive(:pip?).and_return "pip hooray"
|
41
|
+
allow(suit).to receive(:red?).and_return "roses"
|
42
|
+
allow(suit).to receive(:diamonds?).and_return "drip"
|
43
|
+
end
|
44
|
+
|
45
|
+
it "can answer questions only its rank knows" do
|
46
|
+
expect(subject.face?).to eq "grumpy"
|
47
|
+
expect(subject.pip?).to eq "pip hooray"
|
48
|
+
end
|
49
|
+
|
50
|
+
it "can answer questions only its suit knows" do
|
51
|
+
expect(subject.red?).to eq "roses"
|
52
|
+
expect(subject.diamonds?).to eq "drip"
|
53
|
+
end
|
54
|
+
|
55
|
+
it "will not answer silly questions" do
|
56
|
+
subject.hungry?
|
57
|
+
rescue NoMethodError
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context "comparable" do
|
62
|
+
context "different rank, different suit" do
|
63
|
+
it "orders by rank first" do
|
64
|
+
card1 = described_class.new(deck, FiftyTwo::Rank::FOUR, FiftyTwo::Suit::CLUBS)
|
65
|
+
card2 = described_class.new(deck, FiftyTwo::Rank::TWO, FiftyTwo::Suit::DIAMONDS)
|
66
|
+
expect(card2).to be < card1
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context "different rank, same suit" do
|
71
|
+
it "orders by rank first" do
|
72
|
+
card1 = described_class.new(deck, FiftyTwo::Rank::FOUR, FiftyTwo::Suit::SPADES)
|
73
|
+
card2 = described_class.new(deck, FiftyTwo::Rank::SEVEN, FiftyTwo::Suit::SPADES)
|
74
|
+
expect(card2).to be > card1
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context "same rank, different suit" do
|
79
|
+
it "orders by suit" do
|
80
|
+
card1 = described_class.new(deck, FiftyTwo::Rank::KING, FiftyTwo::Suit::SPADES)
|
81
|
+
card2 = described_class.new(deck, FiftyTwo::Rank::KING, FiftyTwo::Suit::HEARTS)
|
82
|
+
expect(card2).to be < card1
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context "same rank, same suit" do
|
87
|
+
it "calls it a tie" do
|
88
|
+
card1 = described_class.new(deck, FiftyTwo::Rank::TEN, FiftyTwo::Suit::DIAMONDS)
|
89
|
+
card2 = described_class.new(deck, FiftyTwo::Rank::TEN, FiftyTwo::Suit::DIAMONDS)
|
90
|
+
expect(card2).to eq card1
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,280 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module FiftyTwo
|
4
|
+
describe Deck do
|
5
|
+
let(:subject) { described_class.standard }
|
6
|
+
let(:minideck) { described_class.new }
|
7
|
+
before(:each) do
|
8
|
+
minideck << FiftyTwo::Card.new(minideck, FiftyTwo::Rank::THREE, FiftyTwo::Suit::CLUBS)
|
9
|
+
minideck << FiftyTwo::Card.new(minideck, FiftyTwo::Rank::NINE, FiftyTwo::Suit::DIAMONDS)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "is a deck, made up of cards" do
|
13
|
+
expect(subject).to be_a described_class
|
14
|
+
expect(subject.count).to eq 52
|
15
|
+
subject.each do |card|
|
16
|
+
expect(card).to be_a FiftyTwo::Card
|
17
|
+
expect(card.deck).to eq subject
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
it "has 13 distinct ranks" do
|
22
|
+
expect(subject.map(&:rank).uniq.count).to eq 13
|
23
|
+
end
|
24
|
+
|
25
|
+
it "has 4 distinct suits" do
|
26
|
+
expect(subject.map(&:suit).uniq.count).to eq 4
|
27
|
+
end
|
28
|
+
|
29
|
+
it "has 2 distinct colors" do
|
30
|
+
expect(subject.map(&:color).uniq.count).to eq 2
|
31
|
+
end
|
32
|
+
|
33
|
+
context "shuffling/sorting" do
|
34
|
+
def sorted?(deck)
|
35
|
+
is_sorted = true
|
36
|
+
deck[1..].each_with_index do |card, i|
|
37
|
+
is_sorted = false unless deck[i] < card
|
38
|
+
end
|
39
|
+
is_sorted
|
40
|
+
end
|
41
|
+
|
42
|
+
it "starts with cards ordered properly" do
|
43
|
+
expect(sorted?(subject)).to be true
|
44
|
+
end
|
45
|
+
|
46
|
+
it "can shuffle the cards" do
|
47
|
+
subject.shuffle!
|
48
|
+
expect(sorted?(subject)).to be false
|
49
|
+
end
|
50
|
+
|
51
|
+
it "can resort the cards" do
|
52
|
+
subject.shuffle!
|
53
|
+
subject.sort!
|
54
|
+
expect(sorted?(subject)).to be true
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context "filtering" do
|
59
|
+
require "pry"
|
60
|
+
it "can find diamonds" do
|
61
|
+
cards = subject.diamonds
|
62
|
+
expect(cards.count).to eq 13
|
63
|
+
end
|
64
|
+
|
65
|
+
it "can find blacks" do
|
66
|
+
cards = subject.blacks
|
67
|
+
expect(cards.count).to eq 26
|
68
|
+
end
|
69
|
+
|
70
|
+
it "can find pips" do
|
71
|
+
cards = subject.pips
|
72
|
+
expect(cards.count).to eq 40
|
73
|
+
end
|
74
|
+
|
75
|
+
it "can find faces" do
|
76
|
+
cards = subject.faces
|
77
|
+
expect(cards.count).to eq 12
|
78
|
+
end
|
79
|
+
|
80
|
+
it "can find jacks" do
|
81
|
+
cards = subject.jacks
|
82
|
+
expect(cards.count).to eq 4
|
83
|
+
end
|
84
|
+
|
85
|
+
it "can find queens" do
|
86
|
+
cards = subject.queens
|
87
|
+
expect(cards.count).to eq 4
|
88
|
+
end
|
89
|
+
|
90
|
+
it "can find kings" do
|
91
|
+
cards = subject.kings
|
92
|
+
expect(cards.count).to eq 4
|
93
|
+
end
|
94
|
+
|
95
|
+
it "can find aces" do
|
96
|
+
cards = subject.aces
|
97
|
+
expect(cards.count).to eq 4
|
98
|
+
end
|
99
|
+
|
100
|
+
it "can find red faces" do
|
101
|
+
cards = subject.reds.faces
|
102
|
+
expect(cards.count).to eq 6
|
103
|
+
end
|
104
|
+
|
105
|
+
it "can find black jacks" do
|
106
|
+
cards = subject.jacks.blacks
|
107
|
+
expect(cards.count).to eq 2
|
108
|
+
end
|
109
|
+
|
110
|
+
it "can find pip spades" do
|
111
|
+
cards = subject.pips.spades
|
112
|
+
expect(cards.count).to eq 10
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe "#draw" do
|
117
|
+
let(:subject) { minideck }
|
118
|
+
|
119
|
+
it "takes cards in order from the deck" do
|
120
|
+
expect(subject.count).to eq 2
|
121
|
+
|
122
|
+
card = subject.draw
|
123
|
+
expect(subject.count).to eq 1
|
124
|
+
expect(card).to be_a FiftyTwo::Card
|
125
|
+
expect(card.identifier).to eq "3C"
|
126
|
+
|
127
|
+
card = subject.draw
|
128
|
+
expect(subject.count).to eq 0
|
129
|
+
expect(card).to be_a FiftyTwo::Card
|
130
|
+
expect(card.identifier).to eq "9D"
|
131
|
+
|
132
|
+
card = subject.draw
|
133
|
+
expect(subject.count).to eq 0
|
134
|
+
expect(card).to be nil
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
describe "#locate" do
|
139
|
+
it "can find the 3 of diamonds via 3D" do
|
140
|
+
card = subject.locate("3D")
|
141
|
+
expect(card.rank).to eq FiftyTwo::Rank::THREE
|
142
|
+
expect(card.suit).to eq FiftyTwo::Suit::DIAMONDS
|
143
|
+
end
|
144
|
+
|
145
|
+
it "can find the ace of spades via as" do
|
146
|
+
card = subject.locate("as")
|
147
|
+
expect(card.rank).to eq FiftyTwo::Rank::ACE
|
148
|
+
expect(card.suit).to eq FiftyTwo::Suit::SPADES
|
149
|
+
end
|
150
|
+
|
151
|
+
it "can find the 10 of clubs via 10C" do
|
152
|
+
card = subject.locate("10C")
|
153
|
+
expect(card.rank).to eq FiftyTwo::Rank::TEN
|
154
|
+
expect(card.suit).to eq FiftyTwo::Suit::CLUBS
|
155
|
+
end
|
156
|
+
|
157
|
+
it "returns nil on a nonsense code" do
|
158
|
+
card = subject.locate("MITTENS")
|
159
|
+
expect(card).to be nil
|
160
|
+
end
|
161
|
+
|
162
|
+
context "removed card" do
|
163
|
+
let(:subject) { minideck }
|
164
|
+
|
165
|
+
it "returns nil if the card is not currently in the deck" do
|
166
|
+
card = minideck.locate("10C")
|
167
|
+
expect(card).to be nil
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
describe "#transfer" do
|
173
|
+
let(:subject) { minideck }
|
174
|
+
let(:hand) { FiftyTwo::Hand.new }
|
175
|
+
|
176
|
+
it "has a deck with 2 cards, and a hand with none" do
|
177
|
+
expect(subject.count).to eq 2
|
178
|
+
expect(hand.count).to eq 0
|
179
|
+
end
|
180
|
+
|
181
|
+
it "can transfer a card by object" do
|
182
|
+
subject.transfer(subject[1], hand)
|
183
|
+
expect(subject.count).to eq 1
|
184
|
+
expect(hand.count).to eq 1
|
185
|
+
end
|
186
|
+
|
187
|
+
it "can transfer a card by identifier" do
|
188
|
+
subject.transfer("3C", hand)
|
189
|
+
expect(subject.count).to eq 1
|
190
|
+
expect(hand.count).to eq 1
|
191
|
+
end
|
192
|
+
|
193
|
+
context "missing card" do
|
194
|
+
let(:missing_card) { FiftyTwo::Card.new(subject, FiftyTwo::Rank::THREE, FiftyTwo::Suit::HEARTS) }
|
195
|
+
|
196
|
+
it "raises an error on a card not in the deck" do
|
197
|
+
expect { subject.transfer(missing_card, hand) }.to raise_error FiftyTwo::HasCards::CardUnavailableError
|
198
|
+
end
|
199
|
+
|
200
|
+
it "raises an error on an identifier not in the deck" do
|
201
|
+
expect { subject.transfer(missing_card.identifier, hand) }.to raise_error FiftyTwo::HasCards::CardUnavailableError
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
context "back to originating deck" do
|
206
|
+
let(:card) { subject[1] }
|
207
|
+
before(:each) { subject.transfer(card, hand) }
|
208
|
+
|
209
|
+
it "starts with a card in the hand and a card in the deck" do
|
210
|
+
expect(subject.count).to eq 1
|
211
|
+
expect(hand.count).to eq 1
|
212
|
+
end
|
213
|
+
|
214
|
+
it "can transfer a card from a hand back to the bottom of its originating deck" do
|
215
|
+
hand.transfer(card)
|
216
|
+
expect(subject.count).to eq 2
|
217
|
+
expect(hand.count).to eq 0
|
218
|
+
expect(subject.last).to eq card
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
describe "#render" do
|
224
|
+
let(:subject) { minideck }
|
225
|
+
|
226
|
+
before(:each) do
|
227
|
+
minideck.cards.each_with_index do |card, i|
|
228
|
+
allow(card).to receive(:render).and_return "CARD#{i}"
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
it "renders the set of cards in this deck" do
|
233
|
+
expect(subject.render).to eq "CARD0 CARD1"
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
describe "#deal" do
|
238
|
+
let(:hand1) { FiftyTwo::Hand.new }
|
239
|
+
let(:hand2) { FiftyTwo::Hand.new }
|
240
|
+
let(:hand3) { FiftyTwo::Hand.new }
|
241
|
+
let(:hands) { [hand1, hand2, hand3] }
|
242
|
+
before(:each) { subject.shuffle! }
|
243
|
+
|
244
|
+
it "starts out as expected" do
|
245
|
+
expect(subject.count).to eq 52
|
246
|
+
hands.each { |h| expect(h.count).to eq 0 }
|
247
|
+
end
|
248
|
+
|
249
|
+
it "can deal a single card to variety of hands" do
|
250
|
+
card1 = subject[0]
|
251
|
+
card2 = subject[1]
|
252
|
+
card3 = subject[2]
|
253
|
+
|
254
|
+
subject.deal(hands)
|
255
|
+
expect(subject.count).to eq 49
|
256
|
+
expect(hand1.cards).to match_array [card1]
|
257
|
+
expect(hand2.cards).to match_array [card2]
|
258
|
+
expect(hand3.cards).to match_array [card3]
|
259
|
+
end
|
260
|
+
|
261
|
+
it "can deal multiple cards to a variety of hands" do
|
262
|
+
card1 = subject[0]
|
263
|
+
card2 = subject[1]
|
264
|
+
card3 = subject[2]
|
265
|
+
card4 = subject[3]
|
266
|
+
card5 = subject[4]
|
267
|
+
card6 = subject[5]
|
268
|
+
card7 = subject[6]
|
269
|
+
card8 = subject[7]
|
270
|
+
card9 = subject[8]
|
271
|
+
|
272
|
+
subject.deal(hands, hand_size: 3)
|
273
|
+
expect(subject.count).to eq 43
|
274
|
+
expect(hand1.cards).to match_array [card1, card4, card7]
|
275
|
+
expect(hand2.cards).to match_array [card2, card5, card8]
|
276
|
+
expect(hand3.cards).to match_array [card3, card6, card9]
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|