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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6c00da0e98ce49dd9546e2936caf0f8b19dea1353ff953e35edf0fa4e8856e97
4
- data.tar.gz: bd0ec3c7c3b7bb0305c3b9b8ed534865eee21dd47a9b0e61e69655d9a7d3c8ff
3
+ metadata.gz: bf4943f0c945d56876c500510e5b3d484aad7a10b3957372d34ce5802e1cb712
4
+ data.tar.gz: dd70bde751e33a47750c1b80174a89cc70dd3a6d94aeee084ccf8f8cec2bf9fd
5
5
  SHA512:
6
- metadata.gz: c2dbb21639b82fe689c8de2ef7033783e9a5ade2fd35372f7e763b09464cec1bc46bac943cd9274499621143922fe7eb7c0d34426b9430f698ea8dcc120b3216
7
- data.tar.gz: cebde92a30ff69c21a3244e29588eef325431c0d684cddbb2b7a66c4bf34846a397b8529edc87397862512fbde75bd9a0960ff61c0f83d86e569211aecef6d83
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], hand_size: 5)
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, hand_size: 1)
26
- hand_size.times.each do |card_idx|
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
@@ -5,5 +5,9 @@ require_relative "./has_cards"
5
5
  module FiftyTwo
6
6
  class Hand
7
7
  include HasCards
8
+
9
+ def release
10
+ cards.reverse_each { |c| transfer(c) }
11
+ end
8
12
  end
9
13
  end
@@ -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(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)
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FiftyTwo
4
- VERSION = "0.0.1"
4
+ VERSION = "0.0.5"
5
5
  end
@@ -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 "3C"
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 "9D"
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 2
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.count).to eq 1
184
- expect(hand.count).to eq 1
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.count).to eq 1
190
- expect(hand.count).to eq 1
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 a card in the deck" do
210
- expect(subject.count).to eq 1
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 2
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, hand_size: 3)
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.1
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-30 00:00:00.000000000 Z
11
+ date: 2021-07-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport