the_gambler 0.1.0 → 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.
- data/README.md +6 -8
- data/VERSION +1 -1
- data/lib/the_gambler/poker.rb +42 -12
- data/spec/decks/deck_spec.rb +23 -4
- data/spec/hands/{hand_flush_spec.rb → poker/hand_flush_spec.rb} +0 -0
- data/spec/hands/{hand_four_of_a_kind_spec.rb → poker/hand_four_of_a_kind_spec.rb} +0 -0
- data/spec/hands/{hand_full_house_spec.rb → poker/hand_full_house_spec.rb} +0 -0
- data/spec/hands/{hand_high_card_spec.rb → poker/hand_high_card_spec.rb} +0 -0
- data/spec/hands/{hand_one_pair_spec.rb → poker/hand_one_pair_spec.rb} +0 -0
- data/spec/hands/{hand_royal_flush_spec.rb → poker/hand_royal_flush_spec.rb} +0 -0
- data/spec/hands/{hand_straight_flush_spec.rb → poker/hand_straight_flush_spec.rb} +0 -0
- data/spec/hands/{hand_straight_spec.rb → poker/hand_straight_spec.rb} +0 -0
- data/spec/hands/{hand_three_of_a_kind_spec.rb → poker/hand_three_of_a_kind_spec.rb} +0 -0
- data/spec/hands/{hand_two_pair_spec.rb → poker/hand_two_pair_spec.rb} +0 -0
- data/spec/hands/poker/kicker_cards_spec.rb +90 -0
- data/the_gambler.gemspec +13 -12
- metadata +14 -13
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Yet another poker hand evaluator. I'm writing it because poker hand evaluators
|
4
4
|
are useful to me in some of my side projects. If it's useful to you, too, all
|
5
|
-
the better.
|
5
|
+
the better. If it's not, then don't use it. Easy.
|
6
6
|
|
7
7
|
## Usage
|
8
8
|
|
@@ -18,19 +18,17 @@ Start rockin':
|
|
18
18
|
You can initialize `Card`s using a (case-insensitive) String (_e.g._ `"JC"`),
|
19
19
|
an Array (_e.g._ `['9', 'S']`), or a Hash (_e.g._ `{rank: 'Q', suit: :diamonds}`).
|
20
20
|
|
21
|
+
Hands are just arrays of cards. You can use the `#blackjack_value` and `#poker_value` methods to use
|
22
|
+
them in games.
|
23
|
+
|
21
24
|
## Beta progress
|
22
25
|
|
23
26
|
Right now, the following stuff works. Assume anything not mentioned in this list doesn't work properly.
|
24
27
|
|
25
28
|
* Blackjack hand evaluation
|
26
|
-
*
|
27
|
-
* Exact poker hand evaluation of all types of hands (!!!).
|
28
|
-
|
29
|
-
### Known issues
|
30
|
-
|
31
|
-
* Hands with the same ranking but different high cards are valued equally.
|
29
|
+
* Poker hand evaluation
|
32
30
|
|
33
|
-
## Contributing to the_gambler
|
31
|
+
## Contributing to `the_gambler`
|
34
32
|
|
35
33
|
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
36
34
|
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
1.0.0
|
data/lib/the_gambler/poker.rb
CHANGED
@@ -8,41 +8,71 @@ module TheGambler
|
|
8
8
|
|
9
9
|
def poker_value
|
10
10
|
if royal_flush? then
|
11
|
-
|
11
|
+
|
12
|
+
10000e10
|
13
|
+
|
12
14
|
elsif straight_flush? then
|
15
|
+
|
13
16
|
if contents.map(&:numerical_value).sort == [2, 3, 4, 5, 14] then
|
14
|
-
|
17
|
+
10000e9 + 1
|
15
18
|
else
|
16
|
-
|
19
|
+
10000e9 + contents.max_by(&:numerical_value).numerical_value
|
17
20
|
end
|
21
|
+
|
18
22
|
elsif four_of_a_kind? then
|
23
|
+
|
19
24
|
c = contents.group_by(&:numerical_value)
|
20
|
-
|
25
|
+
10000e8 + 13 * c.keys.max_by{|k| c[k].count} + c.keys.min_by{|k| c[k].count}
|
26
|
+
|
21
27
|
elsif full_house? then
|
28
|
+
|
22
29
|
c = contents.group_by(&:numerical_value)
|
23
|
-
|
30
|
+
10000e7 + c.keys.detect{|k| c[k].count == 3} * 13 + c.keys.detect{|k| c[k].count == 2}
|
31
|
+
|
24
32
|
elsif flush? then
|
25
|
-
|
33
|
+
|
34
|
+
10000e6 + contents.max_by(&:numerical_value).numerical_value
|
35
|
+
|
26
36
|
elsif straight? then
|
37
|
+
|
27
38
|
if contents.map(&:numerical_value).sort == [2, 3, 4, 5, 14] then
|
28
|
-
|
39
|
+
10000e5 + 1
|
29
40
|
else
|
30
|
-
|
41
|
+
10000e5 + contents.max_by(&:numerical_value).numerical_value
|
31
42
|
end
|
43
|
+
|
32
44
|
elsif three_of_a_kind? then
|
45
|
+
|
33
46
|
c = contents.group_by(&:numerical_value)
|
34
|
-
|
47
|
+
a, b = c.keys.select{|k| c[k].count == 1}.minmax
|
48
|
+
10000e4 + 13 * 13 * c.keys.detect{|k| c[k].count == 3} + 13 * b + a
|
49
|
+
|
35
50
|
elsif two_pair? then
|
51
|
+
|
36
52
|
c = contents.group_by(&:numerical_value)
|
37
53
|
|
38
54
|
pair_one, pair_two = c.keys.select{|k| c[k].count == 2}.minmax
|
55
|
+
kicker = c.keys.detect{|k| c[k].count == 1}
|
56
|
+
|
57
|
+
10000e3 + 13 * 13 * pair_two + 13 * pair_one + kicker
|
39
58
|
|
40
|
-
10e3 + 13 * pair_two + pair_one
|
41
59
|
elsif one_pair? then
|
60
|
+
|
42
61
|
c = contents.group_by(&:numerical_value)
|
43
|
-
|
62
|
+
kicker_value = 0
|
63
|
+
c.keys.select{|k| c[k].count == 1}.each do |n|
|
64
|
+
kicker_value = kicker_value * 13 + n
|
65
|
+
end
|
66
|
+
10000e2 + (13 ** 4) * c.keys.detect{|k| c[k].count == 2} + kicker_value
|
67
|
+
|
44
68
|
elsif high_card? then
|
45
|
-
|
69
|
+
|
70
|
+
value = 0
|
71
|
+
contents.map(&:numerical_value).sort.each_with_index do |n, i|
|
72
|
+
value += 13 ** i * n
|
73
|
+
end
|
74
|
+
value
|
75
|
+
|
46
76
|
end
|
47
77
|
end
|
48
78
|
|
data/spec/decks/deck_spec.rb
CHANGED
@@ -4,11 +4,30 @@ module TheGambler
|
|
4
4
|
|
5
5
|
describe Deck do
|
6
6
|
let(:deck) { Deck.new }
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
|
8
|
+
describe '#initialize' do
|
9
|
+
it 'should accept cards as arguments' do
|
10
|
+
pending
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should accept an array of cards as arguments' do
|
14
|
+
pending
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#deal' do
|
20
|
+
it 'should deal the first card in the deck' do
|
21
|
+
pending
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#shuffle' do
|
26
|
+
it 'should change the ordering of the deck in a random manner' do
|
27
|
+
pending
|
28
|
+
end
|
10
29
|
end
|
11
30
|
|
12
31
|
end
|
13
32
|
|
14
|
-
end
|
33
|
+
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module TheGambler
|
4
|
+
describe Hand do
|
5
|
+
describe '#poker_value' do
|
6
|
+
context 'with kicker cards' do
|
7
|
+
|
8
|
+
context 'four of a kind' do
|
9
|
+
def four_of_a_kind(primary, kicker)
|
10
|
+
Hand.new "#{primary}S", "#{primary}C", "#{primary}H", "#{primary}D", "#{kicker}D"
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should value four aces and a jack higher than four aces and a 3' do
|
14
|
+
four_of_a_kind('A', 'J').poker_value.should > four_of_a_kind('A', '3').poker_value
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should value four 2s and an ace higher than four 2s and a 10' do
|
18
|
+
four_of_a_kind('2', 'A').poker_value.should > four_of_a_kind('2', '10').poker_value
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'three of a kind' do
|
23
|
+
def three_of_a_kind(primary, kicker1, kicker2)
|
24
|
+
Hand.new "#{primary}S", "#{primary}C", "#{primary}H", "#{kicker1}D", "#{kicker2}D"
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should value three aces, a jack, and a 2 higher than three aces, a 10, and a 2' do
|
28
|
+
three_of_a_kind('A', 'J', '2').poker_value.should > three_of_a_kind('A', '10', '2').poker_value
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should value three kings, a jack, and a 10 higher than three kings, a jack, and a 2' do
|
32
|
+
three_of_a_kind('K', 'J', '10').poker_value.should > three_of_a_kind('K', 'J', '2').poker_value
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'two pair' do
|
37
|
+
def two_pair(primary, secondary, kicker)
|
38
|
+
Hand.new "#{primary}S", "#{primary}C", "#{secondary}H", "#{secondary}D", "#{kicker}D"
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should value two pairs with an ace kicker higher than two pairs with a 10 kicker' do
|
42
|
+
two_pair('J', '2', 'A').poker_value.should > two_pair('J', '2', '10').poker_value
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should value two pairs with a 10 kicker higher than two pairs with an 8 kicker' do
|
46
|
+
two_pair('J', '2', '10').poker_value.should > two_pair('J', '2', '8').poker_value
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'one pair' do
|
52
|
+
def one_pair(pair, a, b, c)
|
53
|
+
Hand.new "#{pair}H", "#{pair}C", "#{a}D", "#{b}D", "#{c}D"
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should value a pair with J, 7, 2 higher than a pair with 10, 7, 2' do
|
57
|
+
one_pair('A', 'J', '7', '2').poker_value.should > one_pair('A', '10', '7', '2').poker_value
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should value a pair with J, 7, 5 higher than a pair with J, 6, 5' do
|
61
|
+
one_pair('A', 'J', '7', '5').poker_value.should > one_pair('A', 'J', '6', '5').poker_value
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'should value a pair with J, 7, 5 higher than a pair with J, 7, 2' do
|
65
|
+
one_pair('A', 'J', '7', '5').poker_value.should > one_pair('A', 'J', '7', '2').poker_value
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context 'high card' do
|
70
|
+
it 'should value high card hand AQJ72 higher than ATJ72' do
|
71
|
+
Hand.new(*%w{AD QC JS 7H 2D}).poker_value.should > Hand.new(*%w{AD 10C JS 7H 2D}).poker_value
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'should value high card hand AQJ72 higher than AQT72' do
|
75
|
+
Hand.new(*%w{AD QC JS 7H 2D}).poker_value.should > Hand.new(*%w{AD QC 10S 7H 2D}).poker_value
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should value high card hand AQJ72 higher than AQJ62' do
|
79
|
+
Hand.new(*%w{AD QC JS 7H 2D}).poker_value.should > Hand.new(*%w{AD QC JS 6H 2D}).poker_value
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'should value high card hand AQJ76 higher than AQJ72' do
|
83
|
+
Hand.new(*%w{AD QC JS 7H 6D}).poker_value.should > Hand.new(*%w{AD QC JS 7H 2D}).poker_value
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
data/the_gambler.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "the_gambler"
|
8
|
-
s.version = "
|
8
|
+
s.version = "1.0.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["max thom stahl"]
|
12
|
-
s.date = "2012-11-
|
12
|
+
s.date = "2012-11-20"
|
13
13
|
s.description = "\n Really common tasks in programs that use playing cards are a pain to implement. This is my\n implementation. Use it. Or don't.\n "
|
14
14
|
s.email = "max@villainousindustries.com"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -33,17 +33,18 @@ Gem::Specification.new do |s|
|
|
33
33
|
"lib/the_gambler/poker.rb",
|
34
34
|
"spec/cards/initialization_spec.rb",
|
35
35
|
"spec/decks/deck_spec.rb",
|
36
|
-
"spec/hands/hand_flush_spec.rb",
|
37
|
-
"spec/hands/hand_four_of_a_kind_spec.rb",
|
38
|
-
"spec/hands/hand_full_house_spec.rb",
|
39
|
-
"spec/hands/hand_high_card_spec.rb",
|
40
|
-
"spec/hands/hand_one_pair_spec.rb",
|
41
|
-
"spec/hands/hand_royal_flush_spec.rb",
|
42
|
-
"spec/hands/hand_straight_flush_spec.rb",
|
43
|
-
"spec/hands/hand_straight_spec.rb",
|
44
|
-
"spec/hands/hand_three_of_a_kind_spec.rb",
|
45
|
-
"spec/hands/hand_two_pair_spec.rb",
|
46
36
|
"spec/hands/hands_spec.rb",
|
37
|
+
"spec/hands/poker/hand_flush_spec.rb",
|
38
|
+
"spec/hands/poker/hand_four_of_a_kind_spec.rb",
|
39
|
+
"spec/hands/poker/hand_full_house_spec.rb",
|
40
|
+
"spec/hands/poker/hand_high_card_spec.rb",
|
41
|
+
"spec/hands/poker/hand_one_pair_spec.rb",
|
42
|
+
"spec/hands/poker/hand_royal_flush_spec.rb",
|
43
|
+
"spec/hands/poker/hand_straight_flush_spec.rb",
|
44
|
+
"spec/hands/poker/hand_straight_spec.rb",
|
45
|
+
"spec/hands/poker/hand_three_of_a_kind_spec.rb",
|
46
|
+
"spec/hands/poker/hand_two_pair_spec.rb",
|
47
|
+
"spec/hands/poker/kicker_cards_spec.rb",
|
47
48
|
"spec/players/player_spec.rb",
|
48
49
|
"spec/spec_helper.rb",
|
49
50
|
"spec/support/shared_examples/shared_poker_hands.rb",
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: the_gambler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-11-
|
12
|
+
date: 2012-11-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
@@ -132,17 +132,18 @@ files:
|
|
132
132
|
- lib/the_gambler/poker.rb
|
133
133
|
- spec/cards/initialization_spec.rb
|
134
134
|
- spec/decks/deck_spec.rb
|
135
|
-
- spec/hands/hand_flush_spec.rb
|
136
|
-
- spec/hands/hand_four_of_a_kind_spec.rb
|
137
|
-
- spec/hands/hand_full_house_spec.rb
|
138
|
-
- spec/hands/hand_high_card_spec.rb
|
139
|
-
- spec/hands/hand_one_pair_spec.rb
|
140
|
-
- spec/hands/hand_royal_flush_spec.rb
|
141
|
-
- spec/hands/hand_straight_flush_spec.rb
|
142
|
-
- spec/hands/hand_straight_spec.rb
|
143
|
-
- spec/hands/hand_three_of_a_kind_spec.rb
|
144
|
-
- spec/hands/hand_two_pair_spec.rb
|
145
135
|
- spec/hands/hands_spec.rb
|
136
|
+
- spec/hands/poker/hand_flush_spec.rb
|
137
|
+
- spec/hands/poker/hand_four_of_a_kind_spec.rb
|
138
|
+
- spec/hands/poker/hand_full_house_spec.rb
|
139
|
+
- spec/hands/poker/hand_high_card_spec.rb
|
140
|
+
- spec/hands/poker/hand_one_pair_spec.rb
|
141
|
+
- spec/hands/poker/hand_royal_flush_spec.rb
|
142
|
+
- spec/hands/poker/hand_straight_flush_spec.rb
|
143
|
+
- spec/hands/poker/hand_straight_spec.rb
|
144
|
+
- spec/hands/poker/hand_three_of_a_kind_spec.rb
|
145
|
+
- spec/hands/poker/hand_two_pair_spec.rb
|
146
|
+
- spec/hands/poker/kicker_cards_spec.rb
|
146
147
|
- spec/players/player_spec.rb
|
147
148
|
- spec/spec_helper.rb
|
148
149
|
- spec/support/shared_examples/shared_poker_hands.rb
|
@@ -163,7 +164,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
163
164
|
version: '0'
|
164
165
|
segments:
|
165
166
|
- 0
|
166
|
-
hash:
|
167
|
+
hash: 3691939105348010071
|
167
168
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
168
169
|
none: false
|
169
170
|
requirements:
|