ruby-poker 0.2.0 → 0.2.1
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.
- data/CHANGELOG +4 -1
- data/README +6 -6
- data/lib/card.rb +23 -3
- data/lib/ruby-poker.rb +85 -11
- data/test/test_card.rb +6 -0
- data/test/test_poker_hand.rb +24 -3
- metadata +2 -2
data/CHANGELOG
CHANGED
|
@@ -13,4 +13,7 @@
|
|
|
13
13
|
* Added support for hands with >5 cards
|
|
14
14
|
* Straights with a low Ace count now
|
|
15
15
|
* to_s on a PokerHand now includes the rank after the card list
|
|
16
|
-
* Finally wrote the Unit Tests suite
|
|
16
|
+
* Finally wrote the Unit Tests suite
|
|
17
|
+
2008-02-08 (0.2.1)
|
|
18
|
+
* Cards can be added to a hand after it is created by using (<<) on a PokerHand
|
|
19
|
+
* Cards can be deleted from a hand with PokerHand.delete()
|
data/README
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
== Author
|
|
4
4
|
|
|
5
|
-
Robert Olson
|
|
5
|
+
Robert Olson (rko618 [at] gmail [dot] com)
|
|
6
6
|
|
|
7
7
|
== License
|
|
8
8
|
|
|
@@ -21,7 +21,8 @@ The homepage of this project is located at
|
|
|
21
21
|
|
|
22
22
|
== Description
|
|
23
23
|
|
|
24
|
-
Ruby-Poker handles the logic for poker
|
|
24
|
+
Ruby-Poker handles the logic for getting the rank of a poker hand. It can also be used
|
|
25
|
+
to compare two or more hands to determine which hand has the highest poker value.
|
|
25
26
|
|
|
26
27
|
Card representations can be passed to the PokerHand constructor as a string or an array.
|
|
27
28
|
Face cards (cards ten, jack, queen, king, and ace) are created using their
|
|
@@ -42,7 +43,6 @@ In this section some examples show what can be done with this class.
|
|
|
42
43
|
|
|
43
44
|
== Background
|
|
44
45
|
|
|
45
|
-
I (Robert Olson) wrote all of the code in the original version of ruby-poker which
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
ruby-poker 0.2.0.
|
|
46
|
+
I (Robert Olson) wrote all of the code in the original version of ruby-poker which limited
|
|
47
|
+
hands to only 5 cards. As of the 0.2.0 release ruby-poker is based on Patrick Hurley's
|
|
48
|
+
Texas Holdem code from http://rubyquiz.com/quiz24.html which I merged into ruby-poker.
|
data/lib/card.rb
CHANGED
|
@@ -58,12 +58,20 @@ class Card
|
|
|
58
58
|
build_from_value((face - 1) + (suit * FACES.size()))
|
|
59
59
|
end
|
|
60
60
|
|
|
61
|
+
# Constructs this card object from another card object
|
|
62
|
+
def build_from_card(card)
|
|
63
|
+
@value = card.value
|
|
64
|
+
@suit = card.suit
|
|
65
|
+
@face = card.face
|
|
66
|
+
end
|
|
67
|
+
|
|
61
68
|
public
|
|
62
69
|
|
|
63
|
-
# got a little carried away with this constructor ;-)
|
|
64
70
|
def initialize(*value)
|
|
65
71
|
if (value.size == 1)
|
|
66
|
-
if (value[0].respond_to?(:
|
|
72
|
+
if (value[0].respond_to?(:to_card))
|
|
73
|
+
build_from_card(value[0])
|
|
74
|
+
elsif (value[0].respond_to?(:to_str))
|
|
67
75
|
build_from_string(value[0])
|
|
68
76
|
elsif (value[0].respond_to?(:to_int))
|
|
69
77
|
build_from_value(value[0])
|
|
@@ -82,10 +90,22 @@ class Card
|
|
|
82
90
|
attr_reader :suit, :face, :value
|
|
83
91
|
include Comparable
|
|
84
92
|
|
|
93
|
+
# Returns a string containing the representation of Card
|
|
94
|
+
#
|
|
95
|
+
# Card.new("7c").to_s # => "7c"
|
|
85
96
|
def to_s
|
|
86
97
|
FACES[@face].chr + SUITS[@suit].chr
|
|
87
98
|
end
|
|
88
|
-
|
|
99
|
+
|
|
100
|
+
# If to_card is called on a `Card` it should return itself
|
|
101
|
+
def to_card
|
|
102
|
+
self
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Compare the face value of this card with another card. Returns:
|
|
106
|
+
# -1 if self is less than card2
|
|
107
|
+
# 0 if self is the same face value of card2
|
|
108
|
+
# 1 if self is greater than card2
|
|
89
109
|
def <=> card2
|
|
90
110
|
@face <=> card2.face
|
|
91
111
|
end
|
data/lib/ruby-poker.rb
CHANGED
|
@@ -4,9 +4,20 @@ class PokerHand
|
|
|
4
4
|
include Comparable
|
|
5
5
|
attr_reader :hand
|
|
6
6
|
|
|
7
|
+
# Returns a new PokerHand object. Accepts the cards represented
|
|
8
|
+
# in a string or an array
|
|
9
|
+
#
|
|
10
|
+
# PokerHand.new("3d 5c 8h Ks") # => #<PokerHand:0x5c673c ...
|
|
11
|
+
# PokerHand.new(["3d", "5c", "8h", "Ks"]) # => #<PokerHand:0x5c2d6c ...
|
|
7
12
|
def initialize(cards = [])
|
|
8
13
|
if cards.is_a? Array
|
|
9
|
-
@hand = cards.map
|
|
14
|
+
@hand = cards.map do |card|
|
|
15
|
+
if card.is_a? Card
|
|
16
|
+
card
|
|
17
|
+
else
|
|
18
|
+
Card.new(card.to_s)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
10
21
|
elsif cards.respond_to?(:to_str)
|
|
11
22
|
@hand = cards.scan(/\S{2,3}/).map { |str| Card.new(str) }
|
|
12
23
|
else
|
|
@@ -14,20 +25,40 @@ class PokerHand
|
|
|
14
25
|
end
|
|
15
26
|
end
|
|
16
27
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
28
|
+
# Returns a new PokerHand object with the cards sorted by suit
|
|
29
|
+
# The suit order is spades, hearts, diamonds, clubs
|
|
30
|
+
#
|
|
31
|
+
# PokerHand.new("3d 5c 8h Ks").by_suit.just_cards # => "Ks 8h 3d 5c"
|
|
21
32
|
def by_suit
|
|
22
33
|
PokerHand.new(@hand.sort_by { |c| [c.suit, c.face] }.reverse)
|
|
23
34
|
end
|
|
24
35
|
|
|
36
|
+
# Returns a new PokerHand object with the cards sorted by value
|
|
37
|
+
# with the highest value first.
|
|
38
|
+
#
|
|
39
|
+
# PokerHand.new("3d 5c 8h Ks").by_face.just_cards # => "Ks 8h 5c 3d"
|
|
25
40
|
def by_face
|
|
26
41
|
PokerHand.new(@hand.sort_by { |c| [c.face, c.suit] }.reverse)
|
|
27
42
|
end
|
|
43
|
+
|
|
44
|
+
# Returns string representation of the hand without the rank
|
|
45
|
+
#
|
|
46
|
+
# PokerHand.new(["3c", "Kh"]).just_cards # => "3c Kh"
|
|
47
|
+
def just_cards
|
|
48
|
+
@hand.join(" ")
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Returns an array of the card values in the hand.
|
|
52
|
+
# The values returned are 1 less than the value on the card.
|
|
53
|
+
# For example: 2's will be shown as 1.
|
|
54
|
+
#
|
|
55
|
+
# PokerHand.new(["3c", "Kh"]).face_values # => [2, 12]
|
|
56
|
+
def face_values
|
|
57
|
+
@hand.map { |c| c.face }
|
|
58
|
+
end
|
|
28
59
|
|
|
29
60
|
def =~ (re)
|
|
30
|
-
re.match(
|
|
61
|
+
re.match(just_cards)
|
|
31
62
|
end
|
|
32
63
|
|
|
33
64
|
def royal_flush?
|
|
@@ -192,6 +223,9 @@ class PokerHand
|
|
|
192
223
|
['Highest Card', :highest_card? ],
|
|
193
224
|
]
|
|
194
225
|
|
|
226
|
+
# Returns the verbose hand rating
|
|
227
|
+
#
|
|
228
|
+
# PokerHand.new("4s 5h 6c 7d 8s").hand_rating # => "Straight"
|
|
195
229
|
def hand_rating
|
|
196
230
|
OPS.map { |op|
|
|
197
231
|
(method(op[1]).call()) ? op[0] : false
|
|
@@ -199,7 +233,7 @@ class PokerHand
|
|
|
199
233
|
end
|
|
200
234
|
|
|
201
235
|
alias :rank :hand_rating
|
|
202
|
-
|
|
236
|
+
|
|
203
237
|
def score
|
|
204
238
|
OPS.map { |op|
|
|
205
239
|
method(op[1]).call()
|
|
@@ -209,19 +243,59 @@ class PokerHand
|
|
|
209
243
|
def arranged_hand
|
|
210
244
|
score[1] + " (#{hand_rating})"
|
|
211
245
|
end
|
|
212
|
-
|
|
213
|
-
def just_cards
|
|
214
|
-
@hand.join(" ")
|
|
215
|
-
end
|
|
216
246
|
|
|
247
|
+
# Returns string with a listing of the cards in the hand followed by the hand's rank.
|
|
248
|
+
#
|
|
249
|
+
# h = PokerHand.new("8c 8s")
|
|
250
|
+
# h.to_s # => "8c 8s (Pair)"
|
|
217
251
|
def to_s
|
|
218
252
|
just_cards + " (" + hand_rating + ")"
|
|
219
253
|
end
|
|
220
254
|
|
|
255
|
+
# Returns an array of `Card` objects that make up the `PokerHand`.
|
|
256
|
+
def to_a
|
|
257
|
+
@hand
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
alias :to_ary :to_a
|
|
261
|
+
|
|
221
262
|
def <=> other_hand
|
|
222
263
|
self.score <=> other_hand.score
|
|
223
264
|
end
|
|
224
265
|
|
|
266
|
+
# Add a card to the hand
|
|
267
|
+
#
|
|
268
|
+
# hand = PokerHand.new("5d")
|
|
269
|
+
# hand << "6s" # => Add a six of spades to the hand by passing a string
|
|
270
|
+
# hand << ["7h", "8d"] # => Add multiple cards to the hand using an array
|
|
271
|
+
def << new_cards
|
|
272
|
+
# If they only passed one card we need to place it in an array for processing
|
|
273
|
+
new_cards = [new_cards] if new_cards.is_a?(Card)
|
|
274
|
+
|
|
275
|
+
# luckily .each behaves nicely regardless of whether new_cards is a string or array
|
|
276
|
+
new_cards.each do |nc|
|
|
277
|
+
@hand << Card.new(nc)
|
|
278
|
+
end
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
# Remove a card from the hand.
|
|
282
|
+
#
|
|
283
|
+
# hand = PokerHand.new("5d Jd")
|
|
284
|
+
# hand.delete("Jd") # => #<Card:0x5d0674 @value=23, @face=10, @suit=1>
|
|
285
|
+
# hand.just_cards # => "5d"
|
|
286
|
+
def delete card
|
|
287
|
+
@hand.delete(Card.new(card))
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
RESOLVING_METHODS = ['size', '+', '-']
|
|
291
|
+
RESOLVING_METHODS.each do |method|
|
|
292
|
+
class_eval %{
|
|
293
|
+
def #{method}(*args, &block)
|
|
294
|
+
@hand.#{method}(*args, &block)
|
|
295
|
+
end
|
|
296
|
+
}
|
|
297
|
+
end
|
|
298
|
+
|
|
225
299
|
protected
|
|
226
300
|
|
|
227
301
|
def arrange_hand(md)
|
data/test/test_card.rb
CHANGED
|
@@ -14,6 +14,12 @@ class TestCard < Test::Unit::TestCase
|
|
|
14
14
|
@c4 = Card.new("qS")
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
+
def test_build_from_card
|
|
18
|
+
c1 = Card.new("2c")
|
|
19
|
+
c2 = Card.new(c1)
|
|
20
|
+
assert_equal("2c", c2.to_s)
|
|
21
|
+
end
|
|
22
|
+
|
|
17
23
|
def test_class_face_value
|
|
18
24
|
assert_equal(0, Card.face_value('L'))
|
|
19
25
|
assert_equal(13, Card.face_value('A'))
|
data/test/test_poker_hand.rb
CHANGED
|
@@ -102,11 +102,32 @@ class TestPokerHand < Test::Unit::TestCase
|
|
|
102
102
|
assert !PokerHand.new("6D 7C 5D 5H 3S").two_pair?
|
|
103
103
|
end
|
|
104
104
|
|
|
105
|
+
def test_matching
|
|
106
|
+
assert_match(/9c/, @trips)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def test_size
|
|
110
|
+
assert_equal(2, PokerHand.new("2c 3d").size)
|
|
111
|
+
end
|
|
112
|
+
|
|
105
113
|
def test_comparisons
|
|
106
114
|
assert_equal(0, @trips <=> @trips)
|
|
107
|
-
|
|
108
|
-
|
|
115
|
+
hand1 = PokerHand.new("5C JC 2H 5S 3D")
|
|
116
|
+
hand2 = PokerHand.new("6D 7C 5D 5H 3S")
|
|
117
|
+
assert_equal(1, hand1 <=> hand2)
|
|
118
|
+
assert_equal(-1, hand2 <=> hand1)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def test_appending
|
|
122
|
+
ph = PokerHand.new()
|
|
123
|
+
ph << "Qd"
|
|
124
|
+
assert_equal("Qd", ph.just_cards)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def test_delete
|
|
128
|
+
ph = PokerHand.new("Ac")
|
|
129
|
+
ph.delete("Ac")
|
|
130
|
+
assert_equal(Array.new, ph.hand)
|
|
109
131
|
end
|
|
110
132
|
end
|
|
111
133
|
|
|
112
|
-
# Number of errors detected: 20
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ruby-poker
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Robert Olson
|
|
@@ -9,7 +9,7 @@ autorequire:
|
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
11
|
|
|
12
|
-
date: 2008-
|
|
12
|
+
date: 2008-02-08 00:00:00 -08:00
|
|
13
13
|
default_executable:
|
|
14
14
|
dependencies: []
|
|
15
15
|
|