fiftytwo 0.0.1 → 0.0.5
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 +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
|