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 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