fiftytwo 0.0.1 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +62 -9
- data/lib/fiftytwo/deck.rb +3 -3
- data/lib/fiftytwo/hand.rb +4 -0
- data/lib/fiftytwo/has_cards.rb +16 -5
- data/lib/fiftytwo/version.rb +1 -1
- data/spec/lib/fiftytwo/deck_spec.rb +58 -13
- data/spec/lib/fiftytwo/hand_spec.rb +31 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bf4943f0c945d56876c500510e5b3d484aad7a10b3957372d34ce5802e1cb712
|
4
|
+
data.tar.gz: dd70bde751e33a47750c1b80174a89cc70dd3a6d94aeee084ccf8f8cec2bf9fd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1e5d0e2f89d862a920f3660915a713ea2750f4380777cb464bf200727c8e8077901ab418869c58d1f37eda99ce33fd0a4339190b2ee323a54be310d6bd958c83
|
7
|
+
data.tar.gz: cad05b3559ac84e6cf7bced0a9dcc97ba2b5126bc5bd8ecc9b631f399865f21e84b86ea9c1e11c39fbaf9663e563408e4f97ea93089cfeff9cba5f36ce1c557b
|
data/README.md
CHANGED
@@ -111,41 +111,94 @@ my_hand = FiftyTwo::Hand.new
|
|
111
111
|
your_hand = FiftyTwo::Hand.new
|
112
112
|
# => #<FiftyTwo::Hand:0x00007fb3d21c68c0 @cards=[]>
|
113
113
|
|
114
|
-
deck.deal([my_hand, your_hand],
|
114
|
+
deck.deal([my_hand, your_hand], 5)
|
115
115
|
"Deck has #{deck.count} cards, I have #{my_hand.count} cards, you have #{your_hand.count} cards"
|
116
116
|
# => "Deck has 42 cards, I have 5 cards, you have 5 cards"
|
117
117
|
|
118
118
|
puts my_hand.render, your_hand.render # by the way renderings are colored red/black in your terminal, just like the suit!
|
119
|
-
3♦ 4♠ 5♦ 7♥ 2♣
|
120
|
-
6♠ A♦ 5♠ 10♦ Q♣
|
119
|
+
# 3♦ 4♠ 5♦ 7♥ 2♣
|
120
|
+
# 6♠ A♦ 5♠ 10♦ Q♣
|
121
121
|
```
|
122
122
|
|
123
123
|
Hands, just like the deck, can be shuffled, sorted, searched, etc:
|
124
124
|
```ruby
|
125
125
|
your_hand.sort!
|
126
126
|
puts your_hand.render
|
127
|
-
5♠ 6♠ 10♦ Q♣ A♦
|
127
|
+
# 5♠ 6♠ 10♦ Q♣ A♦
|
128
128
|
|
129
129
|
your_hand.aces.count
|
130
130
|
# => 1
|
131
131
|
```
|
132
132
|
|
133
|
+
Examine the overall composition of a hand:
|
134
|
+
```ruby
|
135
|
+
your_hand.suits.map(&:name) # values are ordered ascending. try ranks too!
|
136
|
+
# => ["clubs", "diamonds", "spades"]
|
137
|
+
```
|
138
|
+
|
133
139
|
Pass your cards around:
|
134
140
|
```ruby
|
135
|
-
my_hand.transfer("4S", your_hand)
|
141
|
+
my_hand.transfer("4S", your_hand) # try an array of card identifiers and/or indexes, too!
|
136
142
|
puts my_hand.render, your_hand.render
|
137
|
-
3♦ 5♦ 7♥ 2♣
|
138
|
-
5♠ 6♠ 10♦ Q♣ A♦ 4♠
|
143
|
+
# 3♦ 5♦ 7♥ 2♣
|
144
|
+
# 5♠ 6♠ 10♦ Q♣ A♦ 4♠
|
139
145
|
|
140
146
|
your_hand.transfer("QC") # goes back to the deck
|
141
147
|
puts my_hand.render, your_hand.render
|
142
|
-
3♦ 5♦ 7♥ 2♣
|
143
|
-
5♠ 6♠ 10♦ A♦ 4♠
|
148
|
+
# 3♦ 5♦ 7♥ 2♣
|
149
|
+
# 5♠ 6♠ 10♦ A♦ 4♠
|
144
150
|
|
145
151
|
deck.count
|
146
152
|
# => 43
|
147
153
|
```
|
148
154
|
|
155
|
+
And finally, release your hand back to the dealer:
|
156
|
+
```ruby
|
157
|
+
my_hand.release
|
158
|
+
your_hand.release
|
159
|
+
|
160
|
+
"Deck has #{deck.count} cards, I have #{my_hand.count} cards, you have #{your_hand.count} cards"
|
161
|
+
# => "Deck has 52 cards, I have 0 cards, you have 0 cards"
|
162
|
+
```
|
163
|
+
|
164
|
+
## Example: 5 card draw poker
|
165
|
+
_Reminder, we are implementing a deck of cards, and the operations you can perform with that deck. Evaluation of hands is dependent upon some
|
166
|
+
particular game, and is outside the scope of this gem!_
|
167
|
+
|
168
|
+
```ruby
|
169
|
+
require "fiftytwo"
|
170
|
+
|
171
|
+
deck = FiftyTwo::Deck.standard
|
172
|
+
deck.shuffle!
|
173
|
+
|
174
|
+
my_hand = FiftyTwo::Hand.new
|
175
|
+
your_hand = FiftyTwo::Hand.new
|
176
|
+
discard = FiftyTwo::Hand.new
|
177
|
+
|
178
|
+
deck.deal([your_hand, my_hand], 5)
|
179
|
+
|
180
|
+
[my_hand, your_hand].each(&:sort!)
|
181
|
+
puts "you: #{your_hand.render}", "me: #{my_hand.render}"
|
182
|
+
# you: 6♦ 6♠ 7♠ K♣ A♦
|
183
|
+
# me: 2♦ 5♥ 8♠ 9♥ 10♦
|
184
|
+
|
185
|
+
your_hand.transfer(%w[7s kc], discard)
|
186
|
+
deck.deal(your_hand, 2)
|
187
|
+
|
188
|
+
my_hand.transfer(%w[2D 5H], discard)
|
189
|
+
deck.deal(my_hand, 2)
|
190
|
+
|
191
|
+
[my_hand, your_hand].each(&:sort!)
|
192
|
+
puts "you: #{your_hand.render}", "me: #{my_hand.render}"
|
193
|
+
# you: 4♠ 6♦ 6♠ K♦ A♦
|
194
|
+
# me: 2♣ 4♣ 8♠ 9♥ 10♦
|
195
|
+
|
196
|
+
puts "Congratulations, you win!"
|
197
|
+
|
198
|
+
[my_hand, your_hand, discard].each(&:release)
|
199
|
+
deck.shuffle!
|
200
|
+
```
|
201
|
+
|
149
202
|
# Problems?
|
150
203
|
Please submit an [issue](https://github.com/kevinstuffandthings/fiftytwo/issues).
|
151
204
|
We'll figure out how to get you up and running with FiftyTwo as smoothly as possible.
|
data/lib/fiftytwo/deck.rb
CHANGED
@@ -22,9 +22,9 @@ module FiftyTwo
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
def deal(hands,
|
26
|
-
|
27
|
-
hands.each { |h| h << draw }
|
25
|
+
def deal(hands, num_cards = 1)
|
26
|
+
num_cards.times.each do |card_idx|
|
27
|
+
Array(hands).each { |h| h << draw }
|
28
28
|
end
|
29
29
|
|
30
30
|
hands
|
data/lib/fiftytwo/hand.rb
CHANGED
data/lib/fiftytwo/has_cards.rb
CHANGED
@@ -21,14 +21,16 @@ module FiftyTwo
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def locate(identifier)
|
24
|
+
return cards[identifier] if identifier.is_a?(Integer)
|
24
25
|
cards.find { |c| c.identifier == identifier.upcase }
|
25
26
|
end
|
26
27
|
|
27
|
-
def transfer(
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
28
|
+
def transfer(cards, destination = nil)
|
29
|
+
gather(cards).map { |c| (destination || c.deck) << self.cards.delete(c) }
|
30
|
+
end
|
31
|
+
|
32
|
+
%i[rank suit].each do |attribute|
|
33
|
+
define_method(attribute.to_s.pluralize) { cards.map { |c| c.send(attribute) }.uniq.sort }
|
32
34
|
end
|
33
35
|
|
34
36
|
FiftyTwo::Suit::ALL.each do |suit|
|
@@ -48,5 +50,14 @@ module FiftyTwo
|
|
48
50
|
def select(identifier)
|
49
51
|
self.class.new(cards.select { |c| c.send("#{identifier}?") })
|
50
52
|
end
|
53
|
+
|
54
|
+
def gather(cards)
|
55
|
+
Array(cards).map do |card|
|
56
|
+
card = locate(card) unless card.is_a?(FiftyTwo::Card)
|
57
|
+
raise CardUnavailableError if card.nil?
|
58
|
+
raise CardUnavailableError unless self.cards.include?(card)
|
59
|
+
card
|
60
|
+
end
|
61
|
+
end
|
51
62
|
end
|
52
63
|
end
|
data/lib/fiftytwo/version.rb
CHANGED
@@ -7,6 +7,7 @@ module FiftyTwo
|
|
7
7
|
before(:each) do
|
8
8
|
minideck << FiftyTwo::Card.new(minideck, FiftyTwo::Rank::THREE, FiftyTwo::Suit::CLUBS)
|
9
9
|
minideck << FiftyTwo::Card.new(minideck, FiftyTwo::Rank::NINE, FiftyTwo::Suit::DIAMONDS)
|
10
|
+
minideck << FiftyTwo::Card.new(minideck, FiftyTwo::Rank::TEN, FiftyTwo::Suit::DIAMONDS)
|
10
11
|
end
|
11
12
|
|
12
13
|
it "is a deck, made up of cards" do
|
@@ -55,8 +56,23 @@ module FiftyTwo
|
|
55
56
|
end
|
56
57
|
end
|
57
58
|
|
59
|
+
context "ranks/suits" do
|
60
|
+
let(:subject) { minideck }
|
61
|
+
|
62
|
+
it "can pull the unique ranks from a deck" do
|
63
|
+
items = subject.ranks
|
64
|
+
items.each { |i| expect(i).to be_a FiftyTwo::Rank }
|
65
|
+
expect(items.map(&:value)).to eq [3, 9, 10]
|
66
|
+
end
|
67
|
+
|
68
|
+
it "can pull the unique suits from a deck" do
|
69
|
+
items = subject.suits
|
70
|
+
items.each { |i| expect(i).to be_a FiftyTwo::Suit }
|
71
|
+
expect(items.map(&:name)).to eq %w[clubs diamonds]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
58
75
|
context "filtering" do
|
59
|
-
require "pry"
|
60
76
|
it "can find diamonds" do
|
61
77
|
cards = subject.diamonds
|
62
78
|
expect(cards.count).to eq 13
|
@@ -117,17 +133,22 @@ module FiftyTwo
|
|
117
133
|
let(:subject) { minideck }
|
118
134
|
|
119
135
|
it "takes cards in order from the deck" do
|
136
|
+
expect(subject.count).to eq 3
|
137
|
+
|
138
|
+
card = subject.draw
|
120
139
|
expect(subject.count).to eq 2
|
140
|
+
expect(card).to be_a FiftyTwo::Card
|
141
|
+
expect(card.identifier).to eq "3C"
|
121
142
|
|
122
143
|
card = subject.draw
|
123
144
|
expect(subject.count).to eq 1
|
124
145
|
expect(card).to be_a FiftyTwo::Card
|
125
|
-
expect(card.identifier).to eq "
|
146
|
+
expect(card.identifier).to eq "9D"
|
126
147
|
|
127
148
|
card = subject.draw
|
128
149
|
expect(subject.count).to eq 0
|
129
150
|
expect(card).to be_a FiftyTwo::Card
|
130
|
-
expect(card.identifier).to eq "
|
151
|
+
expect(card.identifier).to eq "10D"
|
131
152
|
|
132
153
|
card = subject.draw
|
133
154
|
expect(subject.count).to eq 0
|
@@ -174,20 +195,44 @@ module FiftyTwo
|
|
174
195
|
let(:hand) { FiftyTwo::Hand.new }
|
175
196
|
|
176
197
|
it "has a deck with 2 cards, and a hand with none" do
|
177
|
-
expect(subject.count).to eq
|
198
|
+
expect(subject.count).to eq 3
|
178
199
|
expect(hand.count).to eq 0
|
179
200
|
end
|
180
201
|
|
181
202
|
it "can transfer a card by object" do
|
182
203
|
subject.transfer(subject[1], hand)
|
183
|
-
expect(subject.
|
184
|
-
expect(hand.
|
204
|
+
expect(subject.map(&:identifier)).to match_array ["3C", "10D"]
|
205
|
+
expect(hand.map(&:identifier)).to match_array ["9D"]
|
185
206
|
end
|
186
207
|
|
187
208
|
it "can transfer a card by identifier" do
|
188
209
|
subject.transfer("3C", hand)
|
189
|
-
expect(subject.
|
190
|
-
expect(hand.
|
210
|
+
expect(subject.map(&:identifier)).to match_array ["9D", "10D"]
|
211
|
+
expect(hand.map(&:identifier)).to match_array ["3C"]
|
212
|
+
end
|
213
|
+
|
214
|
+
it "can transfer a card by index" do
|
215
|
+
subject.transfer(0, hand)
|
216
|
+
expect(subject.map(&:identifier)).to match_array ["9D", "10D"]
|
217
|
+
expect(hand.map(&:identifier)).to match_array ["3C"]
|
218
|
+
end
|
219
|
+
|
220
|
+
it "can transfer multiple cards" do
|
221
|
+
subject.transfer(%w[3C 10D], hand)
|
222
|
+
expect(subject.map(&:identifier)).to match_array ["9D"]
|
223
|
+
expect(hand.map(&:identifier)).to match_array ["3C", "10D"]
|
224
|
+
end
|
225
|
+
|
226
|
+
it "can transfer multiple cards by a variety of identification methods" do
|
227
|
+
subject.transfer(["3C", 1], hand)
|
228
|
+
expect(subject.map(&:identifier)).to match_array ["10D"]
|
229
|
+
expect(hand.map(&:identifier)).to match_array ["3C", "9D"]
|
230
|
+
end
|
231
|
+
|
232
|
+
it "will not transfer any and raise an error if any one card reference is invalid" do
|
233
|
+
expect { subject.transfer(%w[3C 10K], hand) }.to raise_error FiftyTwo::HasCards::CardUnavailableError
|
234
|
+
expect(subject.count).to eq 3
|
235
|
+
expect(hand.count).to eq 0
|
191
236
|
end
|
192
237
|
|
193
238
|
context "missing card" do
|
@@ -206,14 +251,14 @@ module FiftyTwo
|
|
206
251
|
let(:card) { subject[1] }
|
207
252
|
before(:each) { subject.transfer(card, hand) }
|
208
253
|
|
209
|
-
it "starts with a card in the hand and
|
210
|
-
expect(subject.count).to eq
|
254
|
+
it "starts with a card in the hand and 2 in the deck" do
|
255
|
+
expect(subject.count).to eq 2
|
211
256
|
expect(hand.count).to eq 1
|
212
257
|
end
|
213
258
|
|
214
259
|
it "can transfer a card from a hand back to the bottom of its originating deck" do
|
215
260
|
hand.transfer(card)
|
216
|
-
expect(subject.count).to eq
|
261
|
+
expect(subject.count).to eq 3
|
217
262
|
expect(hand.count).to eq 0
|
218
263
|
expect(subject.last).to eq card
|
219
264
|
end
|
@@ -230,7 +275,7 @@ module FiftyTwo
|
|
230
275
|
end
|
231
276
|
|
232
277
|
it "renders the set of cards in this deck" do
|
233
|
-
expect(subject.render).to eq "CARD0 CARD1"
|
278
|
+
expect(subject.render).to eq "CARD0 CARD1 CARD2"
|
234
279
|
end
|
235
280
|
end
|
236
281
|
|
@@ -269,7 +314,7 @@ module FiftyTwo
|
|
269
314
|
card8 = subject[7]
|
270
315
|
card9 = subject[8]
|
271
316
|
|
272
|
-
subject.deal(hands,
|
317
|
+
subject.deal(hands, 3)
|
273
318
|
expect(subject.count).to eq 43
|
274
319
|
expect(hand1.cards).to match_array [card1, card4, card7]
|
275
320
|
expect(hand2.cards).to match_array [card2, card5, card8]
|
@@ -2,6 +2,36 @@
|
|
2
2
|
|
3
3
|
module FiftyTwo
|
4
4
|
describe Hand do
|
5
|
-
# covered by tests for FiftyTwo::Deck
|
5
|
+
# majority covered by tests for FiftyTwo::Deck
|
6
|
+
|
7
|
+
let(:deck) { FiftyTwo::Deck.standard }
|
8
|
+
let(:hand) { described_class.new }
|
9
|
+
before(:each) { deck.shuffle! }
|
10
|
+
|
11
|
+
describe "#release" do
|
12
|
+
it "does nothing with an empty hand" do
|
13
|
+
expect(deck.count).to eq 52
|
14
|
+
expect(hand.count).to eq 0
|
15
|
+
|
16
|
+
hand.release
|
17
|
+
|
18
|
+
expect(deck.count).to eq 52
|
19
|
+
expect(hand.count).to eq 0
|
20
|
+
end
|
21
|
+
|
22
|
+
context "with cards" do
|
23
|
+
before(:each) { deck.deal(hand, 5) }
|
24
|
+
|
25
|
+
it "can return the entirety of the hand back to the deck from whence it came" do
|
26
|
+
expect(deck.count).to eq 47
|
27
|
+
expect(hand.count).to eq 5
|
28
|
+
|
29
|
+
hand.release
|
30
|
+
|
31
|
+
expect(deck.count).to eq 52
|
32
|
+
expect(hand.count).to eq 0
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
6
36
|
end
|
7
37
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fiftytwo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin McDonald
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-07-
|
11
|
+
date: 2021-07-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|