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 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
- * (Very) Rough poker hand evaluation (i.e., flush > three of a kind, but not distinguishing between different instances of hands)
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
- 0.1.0
1
+ 1.0.0
@@ -8,41 +8,71 @@ module TheGambler
8
8
 
9
9
  def poker_value
10
10
  if royal_flush? then
11
- 10e10
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
- 10e9 + 1
17
+ 10000e9 + 1
15
18
  else
16
- 10e9 + contents.max_by(&:numerical_value).numerical_value
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
- 10e8 + c.keys.max_by{|k| c[k].count}
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
- 10e7 + c.keys.detect{|k| c[k].count == 3} * 13 + c.keys.detect{|k| c[k].count == 2}
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
- 10e6 + contents.max_by(&:numerical_value).numerical_value
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
- 10e5 + 1
39
+ 10000e5 + 1
29
40
  else
30
- 10e5 + contents.max_by(&:numerical_value).numerical_value
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
- 10e4 + c.keys.detect{|k| c[k].count == 3}
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
- 10e2 + c.keys.detect{|k| c[k].count == 2}
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
- contents.max_by(&:numerical_value).numerical_value
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
 
@@ -4,11 +4,30 @@ module TheGambler
4
4
 
5
5
  describe Deck do
6
6
  let(:deck) { Deck.new }
7
-
8
- it 'should default to sorted, not shuffled' do
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
@@ -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 = "0.1.0"
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-18"
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: 0.1.0
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-18 00:00:00.000000000 Z
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: 417615722838553205
167
+ hash: 3691939105348010071
167
168
  required_rubygems_version: !ruby/object:Gem::Requirement
168
169
  none: false
169
170
  requirements: