the_gambler 0.1.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|