hands 0.0.1 → 0.0.2
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/Gemfile +1 -0
- data/lib/hands.rb +2 -2
- data/lib/hands/card.rb +1 -1
- data/lib/hands/hand.rb +41 -13
- data/lib/hands/version.rb +1 -1
- data/spec/models/card_spec.rb +25 -11
- data/spec/models/hand_spec.rb +56 -22
- data/spec/spec_helper.rb +3 -0
- metadata +1 -1
data/Gemfile
CHANGED
data/lib/hands.rb
CHANGED
@@ -3,10 +3,10 @@ require 'hands/card'
|
|
3
3
|
require 'hands/hand'
|
4
4
|
|
5
5
|
module Hands
|
6
|
-
SUITES = %w{ clubs diamonds hearts spades }
|
7
6
|
VALUES = %w{ 2 3 4 5 6 7 8 9 10 j q k a }
|
8
7
|
VALUE_DESCRIPTIONS = %w{ two three four five six seven eight nine ten jack queen king ace }
|
9
8
|
|
10
|
-
#
|
9
|
+
# Reference: http://www.pagat.com/poker/rules/ranking.html
|
10
|
+
SUITES = %w{ clubs diamonds hearts spades } # Reverse alphabetical
|
11
11
|
HAND_ORDER = %w{ high_card pair two_pair three_of_a_kind straight flush full_house four_of_a_kind straight_flush }
|
12
12
|
end
|
data/lib/hands/card.rb
CHANGED
data/lib/hands/hand.rb
CHANGED
@@ -7,7 +7,7 @@ module Hands
|
|
7
7
|
def cards
|
8
8
|
@cards ||= []
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
def <=>(other_hand)
|
12
12
|
response = (self.hand_index <=> other_hand.hand_index)
|
13
13
|
|
@@ -52,7 +52,7 @@ module Hands
|
|
52
52
|
end
|
53
53
|
|
54
54
|
def three_of_a_kind
|
55
|
-
|
55
|
+
self.kinds(3)
|
56
56
|
end
|
57
57
|
|
58
58
|
def straight
|
@@ -85,28 +85,41 @@ module Hands
|
|
85
85
|
end
|
86
86
|
cs
|
87
87
|
end
|
88
|
-
|
88
|
+
|
89
89
|
def flush
|
90
90
|
# If all of the cards are the same suite, we have a flush
|
91
91
|
return nil unless self.suites.length == 1
|
92
92
|
self.cards.sort.reverse
|
93
93
|
end
|
94
|
-
|
94
|
+
|
95
95
|
def full_house
|
96
|
-
|
97
|
-
nil
|
96
|
+
dupes = self.duplicates
|
97
|
+
return nil unless dupes.length == 2
|
98
|
+
|
99
|
+
a = []
|
100
|
+
b = []
|
101
|
+
|
102
|
+
hand = self.cards.select do |card|
|
103
|
+
if dupes.first == card.value
|
104
|
+
a << card
|
105
|
+
elsif dupes.last == card.value
|
106
|
+
b << card
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
return nil unless a.length + b.length == 5
|
111
|
+
self.cards.sort.reverse
|
98
112
|
end
|
99
|
-
|
113
|
+
|
100
114
|
def four_of_a_kind
|
101
|
-
|
102
|
-
nil
|
115
|
+
self.kinds(4)
|
103
116
|
end
|
104
|
-
|
117
|
+
|
105
118
|
def straight_flush
|
106
|
-
|
107
|
-
|
119
|
+
return nil unless self.flush
|
120
|
+
self.straight
|
108
121
|
end
|
109
|
-
|
122
|
+
|
110
123
|
protected
|
111
124
|
|
112
125
|
def hand_index
|
@@ -132,5 +145,20 @@ module Hands
|
|
132
145
|
hand << (self.cards - hand).sort.reverse
|
133
146
|
hand.flatten
|
134
147
|
end
|
148
|
+
|
149
|
+
def kinds(num)
|
150
|
+
dupes = self.duplicates
|
151
|
+
return nil unless dupes.length == 1
|
152
|
+
|
153
|
+
hand = self.cards.select do |card|
|
154
|
+
dupes.include?(card.value)
|
155
|
+
end
|
156
|
+
|
157
|
+
return nil unless hand.length == num
|
158
|
+
|
159
|
+
hand = hand.sort.reverse
|
160
|
+
hand << (self.cards - hand).sort.reverse
|
161
|
+
hand.flatten
|
162
|
+
end
|
135
163
|
end
|
136
164
|
end
|
data/lib/hands/version.rb
CHANGED
data/spec/models/card_spec.rb
CHANGED
@@ -5,40 +5,45 @@ describe Hands::Card do
|
|
5
5
|
card = Hands::Card.new
|
6
6
|
card.is_valid?.should eq(false)
|
7
7
|
card.is_invalid?.should eq(true)
|
8
|
-
|
8
|
+
|
9
9
|
card.suite = :hearts
|
10
10
|
card.is_valid?.should eq(false)
|
11
|
-
|
11
|
+
|
12
12
|
card.value = 9
|
13
13
|
card.is_valid?.should eq(true)
|
14
|
-
|
14
|
+
|
15
15
|
card.suite = 17
|
16
16
|
card.is_valid?.should eq(false)
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
it 'should allow for integers instead of characters for high cards' do
|
20
20
|
card1 = Hands::Card.new(:value => 11, :suite => :clubs)
|
21
|
-
|
22
21
|
card1.is_valid?.should eq(true)
|
23
22
|
card1.value.should eq('j')
|
24
|
-
|
23
|
+
|
25
24
|
card2 = Hands::Card.new(:value => 'j', :suite => :clubs)
|
26
25
|
card2.should eq(card1)
|
27
26
|
end
|
28
|
-
|
27
|
+
|
28
|
+
it 'should not allow invalid values' do
|
29
|
+
card = Hands::Card.new
|
30
|
+
card.value = 'p'
|
31
|
+
card.value.should eql(nil)
|
32
|
+
end
|
33
|
+
|
29
34
|
it 'should be comparable' do
|
30
35
|
card1 = Hands::Card.new(:value => 2, :suite => :hearts)
|
31
36
|
card2 = Hands::Card.new(:value => 3, :suite => :clubs)
|
32
|
-
|
37
|
+
|
33
38
|
(card2 > card1).should eq(true)
|
34
39
|
(card1 < card2).should eq(true)
|
35
|
-
|
40
|
+
|
36
41
|
card1.value = 3
|
37
42
|
(card1 == card2).should eq(true)
|
38
43
|
(card1.<=>(card2, true)).should eq(1)
|
39
44
|
(card2.<=>(card1, true)).should eq(-1)
|
40
45
|
end
|
41
|
-
|
46
|
+
|
42
47
|
it 'should be sortable' do
|
43
48
|
c2 = Hands::Card.new(:value => 2, :suite => :hearts)
|
44
49
|
c3 = Hands::Card.new(:value => 3, :suite => :hearts)
|
@@ -53,8 +58,17 @@ describe Hands::Card do
|
|
53
58
|
cQ = Hands::Card.new(:value => 'q', :suite => :hearts)
|
54
59
|
cK = Hands::Card.new(:value => 'k', :suite => :hearts)
|
55
60
|
cA = Hands::Card.new(:value => 'a', :suite => :hearts)
|
56
|
-
|
61
|
+
|
57
62
|
cards = [c2, c3, c4, c5, c6, c7, c8, c9, c10, cJ, cQ, cK, cA]
|
58
63
|
cards.sort.should eq(cards)
|
59
64
|
end
|
65
|
+
|
66
|
+
it 'should include description in inspect' do
|
67
|
+
card = Hands::Card[2, :hearts]
|
68
|
+
card.inspect.include?('Two of Hearts').should eql(true)
|
69
|
+
|
70
|
+
card = Hands::Card.new
|
71
|
+
card.description.should eql('invalid')
|
72
|
+
card.inspect.include?('invalid').should eql(false)
|
73
|
+
end
|
60
74
|
end
|
data/spec/models/hand_spec.rb
CHANGED
@@ -5,7 +5,7 @@ describe Hands::Hand do
|
|
5
5
|
pair = Hands::Hand.new
|
6
6
|
pair << Hands::Card[2, :hearts]
|
7
7
|
pair << Hands::Card[2, :clubs]
|
8
|
-
|
8
|
+
|
9
9
|
flush = Hands::Hand.new
|
10
10
|
flush << Hands::Card[6, :hearts]
|
11
11
|
flush << Hands::Card[7, :hearts]
|
@@ -14,24 +14,24 @@ describe Hands::Hand do
|
|
14
14
|
flush << Hands::Card[4, :hearts]
|
15
15
|
(flush > pair).should eq(true)
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
it 'should order same types of hands' do
|
19
19
|
small_pair = Hands::Hand.new
|
20
20
|
small_pair << Hands::Card[2, :hearts]
|
21
21
|
small_pair << Hands::Card[2, :clubs]
|
22
|
-
|
22
|
+
|
23
23
|
large_pair = Hands::Hand.new
|
24
24
|
large_pair << Hands::Card['A', :hearts]
|
25
25
|
large_pair << Hands::Card['A', :clubs]
|
26
26
|
(large_pair > small_pair).should eq(true)
|
27
|
-
|
27
|
+
|
28
28
|
small_kicker = Hands::Hand.new
|
29
29
|
small_kicker << Hands::Card['A', :spades]
|
30
30
|
small_kicker << Hands::Card['A', :diamonds]
|
31
31
|
small_kicker << Hands::Card[2, :diamonds]
|
32
32
|
small_kicker << Hands::Card[3, :diamonds]
|
33
33
|
small_kicker << Hands::Card[4, :diamonds]
|
34
|
-
|
34
|
+
|
35
35
|
big_kicker = Hands::Hand.new
|
36
36
|
big_kicker << Hands::Card['A', :hearts]
|
37
37
|
big_kicker << Hands::Card['A', :clubs]
|
@@ -40,17 +40,17 @@ describe Hands::Hand do
|
|
40
40
|
big_kicker << Hands::Card[7, :diamonds]
|
41
41
|
(big_kicker > small_kicker).should eq(true)
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
44
|
it 'should collect suites' do
|
45
45
|
hand = Hands::Hand.new
|
46
46
|
hand << Hands::Card[2, :hearts]
|
47
47
|
hand << Hands::Card[2, :clubs]
|
48
48
|
hand.suites.should eq([:hearts, :clubs])
|
49
|
-
|
49
|
+
|
50
50
|
hand << Hands::Card[3, :clubs]
|
51
51
|
hand.suites.should eq([:hearts, :clubs])
|
52
52
|
end
|
53
|
-
|
53
|
+
|
54
54
|
it 'should recognize high card' do
|
55
55
|
hand = Hands::Hand.new
|
56
56
|
hand << Hands::Card[2, :hearts]
|
@@ -62,7 +62,7 @@ describe Hands::Hand do
|
|
62
62
|
hand.pair.should eql(nil)
|
63
63
|
hand.two_pair.should eql(nil)
|
64
64
|
end
|
65
|
-
|
65
|
+
|
66
66
|
it 'should recognize a pair' do
|
67
67
|
hand = Hands::Hand.new
|
68
68
|
hand << Hands::Card[9, :hearts]
|
@@ -73,7 +73,7 @@ describe Hands::Hand do
|
|
73
73
|
hand.pair.collect(&:value).should eq([9, 9, 7, 4, 2])
|
74
74
|
hand.two_pair.should eql(nil)
|
75
75
|
end
|
76
|
-
|
76
|
+
|
77
77
|
it 'should recognize two pair' do
|
78
78
|
hand = Hands::Hand.new
|
79
79
|
hand << Hands::Card[7, :hearts]
|
@@ -84,9 +84,17 @@ describe Hands::Hand do
|
|
84
84
|
hand.two_pair.collect(&:value).should eq([9, 9, 7, 7, 4])
|
85
85
|
hand.two_pair.should eql(hand.pair)
|
86
86
|
end
|
87
|
-
|
88
|
-
it 'should recognize three of a kind'
|
89
|
-
|
87
|
+
|
88
|
+
it 'should recognize three of a kind' do
|
89
|
+
hand = Hands::Hand.new
|
90
|
+
hand << Hands::Card[7, :hearts]
|
91
|
+
hand << Hands::Card[7, :spades]
|
92
|
+
hand << Hands::Card[7, :diamonds]
|
93
|
+
hand << Hands::Card[3, :hearts]
|
94
|
+
hand << Hands::Card[9, :clubs]
|
95
|
+
hand.best_hand[:type].should eq('three_of_a_kind')
|
96
|
+
end
|
97
|
+
|
90
98
|
it 'should recognize a straight' do
|
91
99
|
hand1 = Hands::Hand.new
|
92
100
|
hand1 << Hands::Card[2, :hearts]
|
@@ -95,7 +103,7 @@ describe Hands::Hand do
|
|
95
103
|
hand1 << Hands::Card[5, :hearts]
|
96
104
|
hand1 << Hands::Card[6, :clubs]
|
97
105
|
hand1.best_hand[:type].should eq('straight')
|
98
|
-
|
106
|
+
|
99
107
|
hand2 = Hands::Hand.new
|
100
108
|
hand2 << Hands::Card['A', :hearts]
|
101
109
|
hand2 << Hands::Card[2, :spades]
|
@@ -103,7 +111,7 @@ describe Hands::Hand do
|
|
103
111
|
hand2 << Hands::Card[4, :hearts]
|
104
112
|
hand2 << Hands::Card[5, :clubs]
|
105
113
|
hand2.best_hand[:type].should eq('straight')
|
106
|
-
|
114
|
+
|
107
115
|
hand3 = Hands::Hand.new
|
108
116
|
hand3 << Hands::Card[10, :hearts]
|
109
117
|
hand3 << Hands::Card['J', :spades]
|
@@ -111,7 +119,7 @@ describe Hands::Hand do
|
|
111
119
|
hand3 << Hands::Card['K', :hearts]
|
112
120
|
hand3 << Hands::Card['A', :clubs]
|
113
121
|
hand3.best_hand[:type].should eq('straight')
|
114
|
-
|
122
|
+
|
115
123
|
hand4 = Hands::Hand.new
|
116
124
|
hand4 << Hands::Card['J', :spades]
|
117
125
|
hand4 << Hands::Card['Q', :diamonds]
|
@@ -120,7 +128,7 @@ describe Hands::Hand do
|
|
120
128
|
hand4 << Hands::Card[2, :hearts]
|
121
129
|
hand4.best_hand[:type].should eq('high_card')
|
122
130
|
end
|
123
|
-
|
131
|
+
|
124
132
|
it 'should recognize a flush' do
|
125
133
|
hand = Hands::Hand.new
|
126
134
|
hand << Hands::Card[6, :hearts]
|
@@ -130,11 +138,37 @@ describe Hands::Hand do
|
|
130
138
|
hand << Hands::Card[4, :hearts]
|
131
139
|
hand.best_hand[:type].should eq('flush')
|
132
140
|
end
|
133
|
-
|
134
|
-
it 'should recognize a full house'
|
135
|
-
|
136
|
-
|
137
|
-
|
141
|
+
|
142
|
+
it 'should recognize a full house' do
|
143
|
+
hand = Hands::Hand.new
|
144
|
+
hand << Hands::Card[7, :hearts]
|
145
|
+
hand << Hands::Card[7, :spades]
|
146
|
+
hand << Hands::Card[7, :diamonds]
|
147
|
+
hand << Hands::Card[9, :spades]
|
148
|
+
hand << Hands::Card[9, :clubs]
|
149
|
+
hand.best_hand[:type].should eq('full_house')
|
150
|
+
end
|
151
|
+
|
152
|
+
it 'should recognize four of a kind' do
|
153
|
+
hand = Hands::Hand.new
|
154
|
+
hand << Hands::Card[7, :hearts]
|
155
|
+
hand << Hands::Card[7, :spades]
|
156
|
+
hand << Hands::Card[7, :diamonds]
|
157
|
+
hand << Hands::Card[7, :clubs]
|
158
|
+
hand << Hands::Card[9, :clubs]
|
159
|
+
hand.best_hand[:type].should eq('four_of_a_kind')
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'should recognize a straight flush' do
|
163
|
+
hand = Hands::Hand.new
|
164
|
+
hand << Hands::Card[2, :hearts]
|
165
|
+
hand << Hands::Card[3, :hearts]
|
166
|
+
hand << Hands::Card[4, :hearts]
|
167
|
+
hand << Hands::Card[5, :hearts]
|
168
|
+
hand << Hands::Card[6, :hearts]
|
169
|
+
hand.best_hand[:type].should eq('straight_flush')
|
170
|
+
end
|
171
|
+
|
138
172
|
it 'should recognize the best hand' do
|
139
173
|
hand = Hands::Hand.new
|
140
174
|
hand << Hands::Card[7, :hearts]
|
data/spec/spec_helper.rb
CHANGED