ruby-poker 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|