ruby-poker 0.3.2 → 1.0.0
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/CHANGELOG +14 -9
- data/README.rdoc +11 -7
- data/Rakefile +6 -67
- data/examples/deck.rb +3 -3
- data/lib/ruby-poker.rb +0 -1
- data/lib/ruby-poker/card.rb +56 -56
- data/lib/ruby-poker/poker_hand.rb +191 -90
- data/ruby-poker.gemspec +20 -22
- data/test/test_card.rb +53 -20
- data/test/test_helper.rb +3 -4
- data/test/test_poker_hand.rb +344 -34
- metadata +44 -44
data/ruby-poker.gemspec
CHANGED
@@ -1,32 +1,30 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "ruby-poker"
|
3
|
-
s.version = "0.
|
4
|
-
s.date = "2009-01-24"
|
5
|
-
s.rubyforge_project = "rubypoker"
|
3
|
+
s.version = "1.0.0"
|
6
4
|
s.platform = Gem::Platform::RUBY
|
7
|
-
s.summary
|
5
|
+
s.summary = "Poker library in Ruby"
|
8
6
|
s.description = "Ruby library for comparing poker hands and determining the winner."
|
9
|
-
s.author
|
10
|
-
s.email = "
|
11
|
-
s.homepage = "
|
12
|
-
s.
|
7
|
+
s.author = "Rob Olson"
|
8
|
+
s.email = "rob@thinkingdigitally.com"
|
9
|
+
s.homepage = "https://github.com/robolson/ruby-poker"
|
10
|
+
s.license = 'BSD'
|
13
11
|
s.files = ["CHANGELOG",
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
12
|
+
"examples/deck.rb",
|
13
|
+
"examples/quick_example.rb",
|
14
|
+
"lib/ruby-poker.rb",
|
15
|
+
"lib/ruby-poker/card.rb",
|
16
|
+
"lib/ruby-poker/poker_hand.rb",
|
17
|
+
"LICENSE",
|
18
|
+
"Rakefile",
|
19
|
+
"README.rdoc",
|
20
|
+
"ruby-poker.gemspec"]
|
21
|
+
s.test_files = ["test/test_helper.rb", "test/test_card.rb", "test/test_poker_hand.rb"]
|
24
22
|
s.require_paths << 'lib'
|
25
|
-
|
26
|
-
s.extra_rdoc_files = ["README", "CHANGELOG", "LICENSE"]
|
23
|
+
|
24
|
+
s.extra_rdoc_files = ["README.rdoc", "CHANGELOG", "LICENSE"]
|
27
25
|
s.rdoc_options << '--title' << 'Ruby Poker Documentation' <<
|
28
26
|
'--main' << 'README.rdoc' <<
|
29
27
|
'--inline-source' << '-q'
|
30
|
-
|
31
|
-
|
28
|
+
|
29
|
+
s.add_development_dependency('shoulda-context', '~> 1.1')
|
32
30
|
end
|
data/test/test_card.rb
CHANGED
@@ -7,29 +7,65 @@ class TestCard < Test::Unit::TestCase
|
|
7
7
|
@c2 = Card.new("TD")
|
8
8
|
@c3 = Card.new("jh")
|
9
9
|
@c4 = Card.new("qS")
|
10
|
+
@c5 = Card.new("AC")
|
10
11
|
end
|
11
|
-
|
12
|
-
def test_build_from_card
|
13
|
-
assert_equal("9c", Card.new(@c1).to_s)
|
14
|
-
end
|
15
|
-
|
12
|
+
|
16
13
|
def test_class_face_value
|
17
|
-
|
14
|
+
assert_equal(0, Card.face_value('L'))
|
18
15
|
assert_equal(13, Card.face_value('A'))
|
19
16
|
end
|
20
17
|
|
18
|
+
def test_build_from_card
|
19
|
+
assert_equal("9c", Card.new(@c1).to_s)
|
20
|
+
end
|
21
|
+
|
21
22
|
def test_build_from_value
|
22
|
-
assert_equal(@c1, Card.new(
|
23
|
+
assert_equal(@c1, Card.new(8))
|
23
24
|
assert_equal(@c2, Card.new(22))
|
24
|
-
assert_equal(@c3, Card.new(
|
25
|
-
assert_equal(@c4, Card.new(
|
25
|
+
assert_equal(@c3, Card.new(36))
|
26
|
+
assert_equal(@c4, Card.new(50))
|
27
|
+
assert_equal(@c5, Card.new(13))
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_build_from_face_suit
|
31
|
+
assert_equal(8, Card.new('9', 'c').value)
|
32
|
+
assert_equal(22, Card.new('T', 'd').value)
|
33
|
+
assert_equal(36, Card.new('J', 'h').value)
|
34
|
+
assert_equal(50, Card.new('Q', 's').value)
|
35
|
+
assert_equal(13, Card.new('A', 'c').value)
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_build_from_value_and_from_face_suit_match
|
39
|
+
ticker = 0
|
40
|
+
Card::SUITS.each_char do |suit|
|
41
|
+
"23456789TJQKA".each_char do |face|
|
42
|
+
ticker += 1
|
43
|
+
from_value = Card.new(ticker)
|
44
|
+
from_face_suit = Card.new(face, suit)
|
45
|
+
assert_equal(from_face_suit, from_value,
|
46
|
+
"Face and suit #{face + suit} did not match card from value #{ticker}")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_build_from_value_and_from_face_suit_values_match
|
52
|
+
ticker = 0
|
53
|
+
0.upto(3) do |suit|
|
54
|
+
1.upto(13) do |face|
|
55
|
+
ticker += 1
|
56
|
+
from_value = Card.new(ticker)
|
57
|
+
from_face_suit_values = Card.new(face, suit)
|
58
|
+
assert_equal(from_face_suit_values, from_value,
|
59
|
+
"Face=#{face} and suit=#{suit} did not match card from value #{ticker}")
|
60
|
+
end
|
61
|
+
end
|
26
62
|
end
|
27
63
|
|
28
64
|
def test_face
|
29
65
|
assert_equal(8, @c1.face)
|
30
66
|
assert_equal(9, @c2.face)
|
31
67
|
assert_equal(10, @c3.face)
|
32
|
-
assert_equal(11, @c4.face)
|
68
|
+
assert_equal(11, @c4.face)
|
33
69
|
end
|
34
70
|
|
35
71
|
def test_suit
|
@@ -40,12 +76,13 @@ class TestCard < Test::Unit::TestCase
|
|
40
76
|
end
|
41
77
|
|
42
78
|
def test_value
|
43
|
-
assert_equal(
|
79
|
+
assert_equal(8, @c1.value)
|
44
80
|
assert_equal(22, @c2.value)
|
45
|
-
assert_equal(
|
46
|
-
assert_equal(
|
81
|
+
assert_equal(36, @c3.value)
|
82
|
+
assert_equal(50, @c4.value)
|
83
|
+
assert_equal(13, @c5.value)
|
47
84
|
end
|
48
|
-
|
85
|
+
|
49
86
|
def test_natural_value
|
50
87
|
assert_equal(1, Card.new("AC").natural_value)
|
51
88
|
assert_equal(15, Card.new("2D").natural_value)
|
@@ -56,14 +93,10 @@ class TestCard < Test::Unit::TestCase
|
|
56
93
|
assert(@c1 < @c2)
|
57
94
|
assert(@c3 > @c2)
|
58
95
|
end
|
59
|
-
|
96
|
+
|
60
97
|
def test_equals
|
61
98
|
c = Card.new("9h")
|
62
99
|
assert_not_equal(@c1, c)
|
63
100
|
assert_equal(@c1, @c1)
|
64
101
|
end
|
65
|
-
|
66
|
-
def test_hash
|
67
|
-
assert_equal(15, @c1.hash)
|
68
|
-
end
|
69
|
-
end
|
102
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
2
3
|
require 'test/unit'
|
3
|
-
require 'shoulda'
|
4
|
+
require 'shoulda-context'
|
4
5
|
|
5
|
-
|
6
|
-
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
7
|
-
require 'ruby-poker'
|
6
|
+
require 'ruby-poker'
|
data/test/test_poker_hand.rb
CHANGED
@@ -2,22 +2,62 @@ require File.expand_path(File.dirname(__FILE__) + '/test_helper')
|
|
2
2
|
|
3
3
|
class TestPokerHand < Test::Unit::TestCase
|
4
4
|
context "A PokerHand instance" do
|
5
|
-
|
5
|
+
|
6
6
|
setup do
|
7
|
-
@
|
7
|
+
@quads = PokerHand.new('Kc Kh Kd Ks Qs')
|
8
8
|
@full_boat = PokerHand.new(["2H", "2D", "4C", "4D", "4S"])
|
9
9
|
@flush = PokerHand.new("3D 6D 7D TD QD 5H 2S")
|
10
10
|
@straight = PokerHand.new("8H 9D TS JH QC AS")
|
11
|
+
@trips = PokerHand.new("2D 9C AS AH AC")
|
12
|
+
@two_pair = PokerHand.new("As Ac Kc Kd 2s")
|
13
|
+
@pair = PokerHand.new("As Ac Kc Qd 2s")
|
14
|
+
@ace_high = PokerHand.new("As Jh 9c 7d 5s")
|
15
|
+
end
|
16
|
+
|
17
|
+
should "handle empty hands" do
|
18
|
+
assert_equal(PokerHand.new.rank, "Empty Hand")
|
19
|
+
end
|
20
|
+
|
21
|
+
should "handle single card hands" do
|
22
|
+
assert_equal(PokerHand.new('As').rank, @ace_high.rank)
|
23
|
+
end
|
24
|
+
|
25
|
+
should "handle two card hands" do
|
26
|
+
assert_equal(PokerHand.new('As Ac').rank, @pair.rank)
|
27
|
+
end
|
28
|
+
|
29
|
+
should "handle three card hands" do
|
30
|
+
assert_equal(PokerHand.new('As Ac Ah').rank, @trips.rank)
|
31
|
+
end
|
32
|
+
|
33
|
+
should "handle four card hands" do
|
34
|
+
assert_equal(PokerHand.new('As Ac Kd Kh').rank, @two_pair.rank)
|
35
|
+
assert_equal(PokerHand.new('As Ac Ad Ah').rank, @quads.rank)
|
36
|
+
end
|
37
|
+
|
38
|
+
should "handle lower case face card names" do
|
39
|
+
assert_equal(0, PokerHand.new('kc kd') <=> PokerHand.new('Kc Kd'))
|
40
|
+
assert_equal(0, PokerHand.new('kc kd') <=> PokerHand.new('Kc KD'))
|
41
|
+
end
|
42
|
+
|
43
|
+
should "handle hands without space" do
|
44
|
+
assert_equal(0, PokerHand.new('KcKd') <=> PokerHand.new('Kc Kd'))
|
45
|
+
assert_equal(0, PokerHand.new('KcKd9d') <=> PokerHand.new('Kc Kd 9d'))
|
46
|
+
end
|
47
|
+
|
48
|
+
should "raise a clear error with invalid cards" do
|
49
|
+
e = assert_raises(ArgumentError) { PokerHand.new('Fc') }
|
50
|
+
assert_match(/"Fc"/, e.message)
|
51
|
+
e = assert_raises(ArgumentError) { PokerHand.new('Tp') }
|
52
|
+
assert_match(/"Tp"/, e.message)
|
11
53
|
end
|
12
|
-
|
13
|
-
# there are a lot of combinations that should be tested here. I will add more
|
14
|
-
# troublesome cases as I think of them.
|
54
|
+
|
15
55
|
should "sort using rank" do
|
16
56
|
assert_equal("As Ah Ac 9c 2d", @trips.sort_using_rank)
|
17
57
|
assert_equal("4s 4d 4c 2h 2d", @full_boat.sort_using_rank)
|
18
58
|
assert_equal("Qd Td 7d 6d 3d 2s 5h", @flush.sort_using_rank)
|
19
59
|
assert_equal("Qc Jh Ts 9d 8h As", @straight.sort_using_rank)
|
20
|
-
|
60
|
+
|
21
61
|
assert_equal("As Ah 3d 3c Kd", PokerHand.new("AS AH KD 3D 3C").sort_using_rank)
|
22
62
|
assert_equal("As Ah 3d 3c 2d", PokerHand.new("2D AS AH 3D 3C").sort_using_rank)
|
23
63
|
end
|
@@ -33,13 +73,13 @@ class TestPokerHand < Test::Unit::TestCase
|
|
33
73
|
should "return just the face values of the cards" do
|
34
74
|
assert_equal([1, 8, 13, 13, 13], @trips.face_values)
|
35
75
|
end
|
36
|
-
|
76
|
+
|
37
77
|
should "recognize a straight flush" do
|
38
78
|
assert !@flush.straight_flush?
|
39
79
|
assert !@straight.straight_flush?
|
40
80
|
assert PokerHand.new("8H 9H TH JH QH AS").straight_flush?
|
41
81
|
end
|
42
|
-
|
82
|
+
|
43
83
|
should "recognize a royal flush" do
|
44
84
|
assert !@flush.royal_flush?
|
45
85
|
assert PokerHand.new("AD KD QD JD TD").royal_flush?
|
@@ -59,10 +99,13 @@ class TestPokerHand < Test::Unit::TestCase
|
|
59
99
|
assert !@trips.full_house?
|
60
100
|
assert @full_boat.full_house?
|
61
101
|
end
|
62
|
-
|
102
|
+
|
63
103
|
should "recognize a straight" do
|
64
104
|
assert @straight.straight?
|
105
|
+
# ace low straight
|
65
106
|
assert PokerHand.new("AH 2S 3D 4H 5D").straight?
|
107
|
+
# ace high straight
|
108
|
+
assert PokerHand.new("AH KS QD JH TD").straight?
|
66
109
|
end
|
67
110
|
|
68
111
|
should "recognize a three of a kind" do
|
@@ -73,12 +116,12 @@ class TestPokerHand < Test::Unit::TestCase
|
|
73
116
|
assert PokerHand.new("2S 2D TH TD 4S").two_pair?
|
74
117
|
assert !PokerHand.new("6D 7C 5D 5H 3S").two_pair?
|
75
118
|
end
|
76
|
-
|
119
|
+
|
77
120
|
should "recognize a pair" do
|
78
121
|
assert !PokerHand.new("5C JC 2H 7S 3D").pair?
|
79
122
|
assert PokerHand.new("6D 7C 5D 5H 3S").pair?
|
80
123
|
end
|
81
|
-
|
124
|
+
|
82
125
|
should "recognize a hand with the rank highest_card" do
|
83
126
|
# hard to test, make sure it does not return null
|
84
127
|
assert PokerHand.new("2D 4S 6C 8C TH").highest_card?
|
@@ -110,42 +153,42 @@ class TestPokerHand < Test::Unit::TestCase
|
|
110
153
|
assert_match(/9c/, @trips.to_s)
|
111
154
|
assert_no_match(/AD/, @trips.to_s)
|
112
155
|
end
|
113
|
-
|
156
|
+
|
114
157
|
should "return the correct number of cards in the hand" do
|
115
158
|
assert_equal(0, PokerHand.new.size)
|
116
159
|
assert_equal(1, PokerHand.new("2c").size)
|
117
160
|
assert_equal(2, PokerHand.new("2c 3d").size)
|
118
161
|
end
|
119
|
-
|
162
|
+
|
120
163
|
should "be comparable to other PokerHands" do
|
121
164
|
hand1 = PokerHand.new("5C JC 2H 5S 3D")
|
122
165
|
hand2 = PokerHand.new("6D 7C 5D 5H 3S")
|
123
166
|
assert_equal(1, hand1 <=> hand2)
|
124
167
|
assert_equal(-1, hand2 <=> hand1)
|
125
168
|
end
|
126
|
-
|
169
|
+
|
127
170
|
should "be considered equal to other poker hands that contain the same cards" do
|
128
171
|
assert_equal(0, @trips <=> @trips)
|
129
|
-
|
172
|
+
|
130
173
|
hand1 = PokerHand.new("Ac Qc Ks Kd 9d 3c")
|
131
174
|
hand2 = PokerHand.new("Ah Qs 9h Kh Kc 3s")
|
132
175
|
assert_equal(0, hand1 <=> hand2)
|
133
176
|
end
|
134
|
-
|
135
|
-
should "be able to
|
177
|
+
|
178
|
+
should "be able to insert new cards into the hand" do
|
136
179
|
ph = PokerHand.new()
|
137
180
|
ph << "Qd"
|
138
181
|
ph << Card.new("2D")
|
139
182
|
ph << ["3d", "4d"]
|
140
183
|
assert_equal("Qd 2d 3d 4d", ph.just_cards)
|
141
184
|
end
|
142
|
-
|
185
|
+
|
143
186
|
should "be able to delete a card" do
|
144
187
|
ph = PokerHand.new("Ac")
|
145
188
|
ph.delete("Ac")
|
146
189
|
assert_equal(Array.new, ph.hand)
|
147
190
|
end
|
148
|
-
|
191
|
+
|
149
192
|
should "detect the two highest pairs when there are more than two" do
|
150
193
|
ph = PokerHand.new("7d 7s 4d 4c 2h 2d")
|
151
194
|
assert_equal([3, 6, 3, 1], ph.two_pair?[0])
|
@@ -155,66 +198,333 @@ class TestPokerHand < Test::Unit::TestCase
|
|
155
198
|
# 3: second highest pair is two 4's
|
156
199
|
# 1: kicker is a 2
|
157
200
|
end
|
158
|
-
|
201
|
+
|
159
202
|
context "when duplicates are allowed" do
|
160
203
|
setup do
|
161
204
|
PokerHand.allow_duplicates = true
|
162
205
|
end
|
163
|
-
|
206
|
+
|
164
207
|
should "create a PokerHand of unique cards" do
|
165
208
|
uniq_ph = PokerHand.new("3s 4s 3s").uniq
|
166
209
|
assert_instance_of(PokerHand, uniq_ph) # want to be sure uniq hands back a PokerHand
|
167
210
|
assert_contains(uniq_ph.hand, Card.new('3s'))
|
168
211
|
assert_contains(uniq_ph.hand, Card.new('4s'))
|
169
212
|
end
|
170
|
-
|
213
|
+
|
171
214
|
should "allow five of a kind" do
|
172
215
|
# there is no five of a kind. This just tests to make sure
|
173
216
|
# that ruby-poker doesn't crash if given 5 of the same card
|
174
217
|
ph = PokerHand.new("KS KS KS KS KS")
|
175
218
|
assert_equal("Four of a kind", ph.rank)
|
176
219
|
end
|
177
|
-
|
220
|
+
|
178
221
|
should "allow duplicates on initialize" do
|
179
222
|
assert_nothing_raised RuntimeError do
|
180
223
|
PokerHand.new("3s 3s")
|
181
224
|
end
|
182
225
|
end
|
183
|
-
|
226
|
+
|
184
227
|
should "allow duplicate card to be added after initialize" do
|
185
228
|
ph = PokerHand.new("2d")
|
186
229
|
ph << "2d"
|
187
230
|
assert_equal("2d 2d", ph.just_cards)
|
188
231
|
end
|
189
232
|
end
|
190
|
-
|
233
|
+
|
191
234
|
context "when duplicates are not allowed" do
|
192
235
|
setup do
|
193
236
|
PokerHand.allow_duplicates = false
|
194
237
|
end
|
195
|
-
|
238
|
+
|
196
239
|
should "not allow duplicates on initialize" do
|
197
240
|
PokerHand.allow_duplicates = false
|
198
|
-
|
241
|
+
|
199
242
|
assert_raise RuntimeError do
|
200
243
|
PokerHand.new("3s 3s")
|
201
244
|
end
|
202
|
-
|
245
|
+
|
203
246
|
PokerHand.allow_duplicates = true
|
204
247
|
end
|
205
|
-
|
248
|
+
|
206
249
|
should "not allow duplicates after initialize" do
|
207
250
|
PokerHand.allow_duplicates = false
|
208
|
-
|
209
|
-
ph = PokerHand.new("2d")
|
251
|
+
|
252
|
+
ph = PokerHand.new("2d")
|
210
253
|
assert_raise RuntimeError do
|
211
254
|
ph << "2d"
|
212
255
|
end
|
213
|
-
|
256
|
+
|
214
257
|
PokerHand.allow_duplicates = true
|
215
258
|
end
|
216
259
|
end
|
217
|
-
|
260
|
+
|
261
|
+
should "have an each method" do
|
262
|
+
cards = []
|
263
|
+
@straight.each do |card|
|
264
|
+
cards << card
|
265
|
+
end
|
266
|
+
assert_equal @straight.to_a, cards
|
267
|
+
end
|
268
|
+
|
269
|
+
should "be Enumerable" do
|
270
|
+
assert PokerHand.include?(Enumerable)
|
271
|
+
end
|
218
272
|
end
|
219
|
-
end
|
220
273
|
|
274
|
+
context "addition" do
|
275
|
+
setup do
|
276
|
+
@base = PokerHand.new('Ac Kc')
|
277
|
+
end
|
278
|
+
|
279
|
+
should "work with a string" do
|
280
|
+
assert_equal PokerHand.new('Ac Kc Qc'), @base + 'Qc'
|
281
|
+
end
|
282
|
+
|
283
|
+
should "work with a card" do
|
284
|
+
assert_equal PokerHand.new('Ac Kc Qc'), @base + Card.new('Qc')
|
285
|
+
end
|
286
|
+
|
287
|
+
should "work with a hand" do
|
288
|
+
assert_equal PokerHand.new('Ac Kc Qc'), @base + PokerHand.new('Qc')
|
289
|
+
end
|
290
|
+
|
291
|
+
should "not modify the receiver hand" do
|
292
|
+
result = @base + 'Qc'
|
293
|
+
assert_not_equal result, @base
|
294
|
+
end
|
295
|
+
|
296
|
+
should "not affect receiver cards" do
|
297
|
+
result = @base + 'Qc'
|
298
|
+
result.to_a.first.instance_eval { @face = Card.face_value('2') }
|
299
|
+
assert_equal PokerHand.new('Ac Kc'), @base
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
context "PokerHand#pair?" do
|
304
|
+
|
305
|
+
should "return false with one card" do
|
306
|
+
assert !PokerHand.new("2h").pair?
|
307
|
+
end
|
308
|
+
|
309
|
+
context "with a pair" do
|
310
|
+
|
311
|
+
should "return 2, followed by the pair value" do
|
312
|
+
assert_equal [2, 5-1], PokerHand.new("5h 5s").pair?[0]
|
313
|
+
end
|
314
|
+
|
315
|
+
context "with a two card hand" do
|
316
|
+
setup do
|
317
|
+
@ph = PokerHand.new("5h 5s")
|
318
|
+
@scoring = @ph.pair?[0]
|
319
|
+
end
|
320
|
+
|
321
|
+
should "return scoring with 2 entries" do
|
322
|
+
assert_equal 2, @scoring.size
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
context "with a three card hand" do
|
327
|
+
setup do
|
328
|
+
@ph = PokerHand.new("5h 5s 8s")
|
329
|
+
@scoring = @ph.pair?[0]
|
330
|
+
end
|
331
|
+
|
332
|
+
should "return scoring with 3 entries" do
|
333
|
+
assert_equal 3, @scoring.size
|
334
|
+
end
|
335
|
+
|
336
|
+
should "return the value of the kicker" do
|
337
|
+
assert_equal 8-1, @scoring[2]
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
341
|
+
context "with a four card hand" do
|
342
|
+
setup do
|
343
|
+
@ph = PokerHand.new("5h 5s 8s 7s")
|
344
|
+
@scoring = @ph.pair?[0]
|
345
|
+
end
|
346
|
+
|
347
|
+
should "return scoring with 4 entries" do
|
348
|
+
assert_equal 4, @scoring.size
|
349
|
+
end
|
350
|
+
|
351
|
+
should "return the values of the kickers" do
|
352
|
+
assert_equal 8-1, @scoring[2]
|
353
|
+
assert_equal 7-1, @scoring[3]
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
357
|
+
context "with a five (or more) card hand" do
|
358
|
+
setup do
|
359
|
+
@ph = PokerHand.new("5h 5s 8s 7s 6s 2h")
|
360
|
+
@scoring = @ph.pair?[0]
|
361
|
+
end
|
362
|
+
|
363
|
+
should "return scoring with 5 entries" do
|
364
|
+
assert_equal 5, @scoring.size
|
365
|
+
end
|
366
|
+
|
367
|
+
should "return the values of the kickers" do
|
368
|
+
assert_equal 8-1, @scoring[2]
|
369
|
+
assert_equal 7-1, @scoring[3]
|
370
|
+
assert_equal 6-1, @scoring[4]
|
371
|
+
end
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
context "without a pair" do
|
376
|
+
should "return false" do
|
377
|
+
assert !PokerHand.new("2h 3h").pair?
|
378
|
+
end
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
382
|
+
|
383
|
+
def assert_hand_match(expression, cards)
|
384
|
+
hand = PokerHand.new(cards)
|
385
|
+
assert hand.match?(expression), "#{cards} didn't match #{expression}"
|
386
|
+
end
|
387
|
+
|
388
|
+
def assert_hand_not_match(expression, cards)
|
389
|
+
hand = PokerHand.new(cards)
|
390
|
+
assert !hand.match?(expression), "#{cards} did match #{expression}"
|
391
|
+
end
|
392
|
+
|
393
|
+
context "matching expression" do
|
394
|
+
should "match two faces" do
|
395
|
+
assert_hand_match 'AA', 'Ah Ad'
|
396
|
+
assert_hand_match 'Q8', 'Qc 8d'
|
397
|
+
end
|
398
|
+
|
399
|
+
should "not match two faces" do
|
400
|
+
assert_hand_not_match 'T9', 'Tc 8s'
|
401
|
+
assert_hand_not_match 'QQ', 'Tc 8s'
|
402
|
+
end
|
403
|
+
|
404
|
+
should "match unordered faces" do
|
405
|
+
assert_hand_match 'K7', '7c Ks'
|
406
|
+
end
|
407
|
+
|
408
|
+
should "match suited when suited" do
|
409
|
+
assert_hand_match 'Q8s', 'Qc 8c'
|
410
|
+
assert_hand_match '56s', '5h 6h'
|
411
|
+
end
|
412
|
+
|
413
|
+
should "not match suited when offsuit" do
|
414
|
+
assert_hand_not_match 'Q8s', 'Qc 8d'
|
415
|
+
assert_hand_not_match '56s', '5h 6c'
|
416
|
+
end
|
417
|
+
|
418
|
+
should "match offsuit when offsuited" do
|
419
|
+
assert_hand_match 'Q8o', 'Qc 8h'
|
420
|
+
assert_hand_match '56o', '5h 6s'
|
421
|
+
end
|
422
|
+
|
423
|
+
should "not match offsuit when suited" do
|
424
|
+
assert_hand_not_match 'Q8o', 'Qc 8c'
|
425
|
+
assert_hand_not_match '56o', '5h 6h'
|
426
|
+
end
|
427
|
+
|
428
|
+
should "match pair min" do
|
429
|
+
assert_hand_match 'JJ+', 'Jc Js'
|
430
|
+
assert_hand_match '66+', 'Qc Qh'
|
431
|
+
assert_hand_match 'JJ+', 'Ad Ac'
|
432
|
+
end
|
433
|
+
|
434
|
+
should "not match pair min" do
|
435
|
+
assert_hand_not_match 'JJ+', 'Tc Ts'
|
436
|
+
assert_hand_not_match '66+', 'Qc Kh'
|
437
|
+
assert_hand_not_match 'AA+', '2d 2c'
|
438
|
+
end
|
439
|
+
|
440
|
+
should "match face min" do
|
441
|
+
assert_hand_match 'AJ+', 'Ac Js'
|
442
|
+
assert_hand_match 'AQ+', 'Ac Kc'
|
443
|
+
assert_hand_match 'AJ+', 'Ac As'
|
444
|
+
assert_hand_match 'QT+', 'Qc Ts'
|
445
|
+
assert_hand_match 'QT+', 'Qc Qs'
|
446
|
+
assert_hand_not_match 'QT+', 'Qc Ks' # sure? should be matched with KQ+?
|
447
|
+
assert_hand_not_match 'AJ+', 'Ac Ts'
|
448
|
+
assert_hand_not_match 'AJ+', 'Tc Ts'
|
449
|
+
end
|
450
|
+
|
451
|
+
should "match suited face min" do
|
452
|
+
assert_hand_match 'AJs+', 'Ac Jc'
|
453
|
+
assert_hand_match 'AQs+', 'Ac Kc'
|
454
|
+
assert_hand_not_match 'AJs+', 'Ac As'
|
455
|
+
assert_hand_match 'QTs+', 'Qc Tc'
|
456
|
+
assert_hand_not_match 'QTs+', 'Qc Ts'
|
457
|
+
assert_hand_not_match 'AJs+', 'Ac Qs'
|
458
|
+
end
|
459
|
+
|
460
|
+
should "match offsuit face min" do
|
461
|
+
assert_hand_match 'AJo+', 'Ac Jd'
|
462
|
+
assert_hand_match 'AQo+', 'Ac Kh'
|
463
|
+
assert_hand_match 'AJo+', 'Ac As'
|
464
|
+
assert_hand_match 'QTo+', 'Qc Td'
|
465
|
+
assert_hand_not_match 'QTo+', 'Qc Tc'
|
466
|
+
assert_hand_not_match 'AJo+', 'Ac Qc'
|
467
|
+
end
|
468
|
+
|
469
|
+
should "match face with 1 gap" do
|
470
|
+
assert_hand_match '89+', '8c 9d'
|
471
|
+
assert_hand_match '89+', '9c Td'
|
472
|
+
assert_hand_match '89+', 'Tc Jd'
|
473
|
+
assert_hand_match '89+', 'Ac Kd'
|
474
|
+
assert_hand_not_match '89+', '8c Td'
|
475
|
+
assert_hand_not_match '89+', 'Tc Td'
|
476
|
+
assert_hand_not_match '89+', '7c 8d'
|
477
|
+
end
|
478
|
+
|
479
|
+
should "match face with 2 gaps" do
|
480
|
+
assert_hand_match '8T+', '8c Td'
|
481
|
+
assert_hand_match '8T+', 'Tc 8d'
|
482
|
+
assert_hand_match '24+', '9c Jd'
|
483
|
+
assert_hand_match '79+', 'Ac Qd'
|
484
|
+
assert_hand_not_match '8T+', '8c 9d'
|
485
|
+
assert_hand_not_match '8T+', 'Tc Td'
|
486
|
+
assert_hand_not_match '8T+', 'Jc Ad'
|
487
|
+
assert_hand_not_match '8T+', '7c 9d'
|
488
|
+
end
|
489
|
+
|
490
|
+
should "match face with many gaps" do
|
491
|
+
assert_hand_match '8J+', '9c Qd'
|
492
|
+
assert_hand_match '8Q+', '9c Kd'
|
493
|
+
assert_hand_match '8K+', 'Ac 9d'
|
494
|
+
assert_hand_not_match '8J+', '7c Td'
|
495
|
+
end
|
496
|
+
|
497
|
+
should "match face gap with suit" do
|
498
|
+
assert_hand_match '89s+', '9c Tc'
|
499
|
+
assert_hand_not_match '89s+', '9c Td'
|
500
|
+
assert_hand_match '89o+', '9c Th'
|
501
|
+
assert_hand_not_match '89o+', '9d Td'
|
502
|
+
end
|
503
|
+
|
504
|
+
[
|
505
|
+
%w(),
|
506
|
+
%w(Ac),
|
507
|
+
%w(Ac Kc Qc),
|
508
|
+
%w(Ac Kc Qc Jc Tc),
|
509
|
+
].each do |cards|
|
510
|
+
should "raise an error if the number of cards is #{cards.size}" do
|
511
|
+
hand = PokerHand.new(cards)
|
512
|
+
assert_raises RuntimeError do
|
513
|
+
hand.match?('AA')
|
514
|
+
end
|
515
|
+
end
|
516
|
+
end
|
517
|
+
|
518
|
+
should "raise an error with invalid expression" do
|
519
|
+
hand = PokerHand.new("Ac Kc")
|
520
|
+
assert_raises ArgumentError do
|
521
|
+
hand.match? "foo"
|
522
|
+
end
|
523
|
+
|
524
|
+
assert_raises ArgumentError do
|
525
|
+
hand.match? ""
|
526
|
+
end
|
527
|
+
end
|
528
|
+
end
|
529
|
+
|
530
|
+
end
|