hands 0.0.1
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/.gitignore +17 -0
- data/Gemfile +6 -0
- data/LICENSE +22 -0
- data/Rakefile +8 -0
- data/Readme.markdown +73 -0
- data/hands.gemspec +17 -0
- data/lib/hands/card.rb +90 -0
- data/lib/hands/hand.rb +136 -0
- data/lib/hands/version.rb +3 -0
- data/lib/hands.rb +12 -0
- data/spec/models/card_spec.rb +60 -0
- data/spec/models/hand_spec.rb +147 -0
- data/spec/spec_helper.rb +2 -0
- metadata +61 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2011 Sam Soffes
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
data/Readme.markdown
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
# Hands
|
2
|
+
|
3
|
+
Simple library for calculating poker hands.
|
4
|
+
|
5
|
+
Currently this gem is very limited. I plan on adding outs, odds, and other actually useful stuff. I started writing this on a plane as a personal challenge. It's current state is crude, although tested and works.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
``` ruby
|
12
|
+
gem 'hands'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install hands
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
``` ruby
|
26
|
+
# Best hand detection
|
27
|
+
straight = Hands::Hand.new
|
28
|
+
straight << Hands::Card['A', :hearts]
|
29
|
+
straight << Hands::Card[2, :spades]
|
30
|
+
straight << Hands::Card[3, :diamonds]
|
31
|
+
straight << Hands::Card[4, :hearts]
|
32
|
+
straight << Hands::Card[5, :clubs]
|
33
|
+
straight.best_hand[:type] # 'straight'
|
34
|
+
|
35
|
+
# Hand comparison
|
36
|
+
pair = Hands::Hand.new
|
37
|
+
pair << Hands::Card[2, :hearts]
|
38
|
+
pair << Hands::Card[2, :clubs]
|
39
|
+
pair << Hands::Card[3, :diamonds]
|
40
|
+
pair << Hands::Card[4, :hearts]
|
41
|
+
pair << Hands::Card[5, :clubs]
|
42
|
+
|
43
|
+
flush = Hands::Hand.new
|
44
|
+
flush << Hands::Card[6, :hearts]
|
45
|
+
flush << Hands::Card[7, :hearts]
|
46
|
+
flush << Hands::Card[8, :hearts]
|
47
|
+
flush << Hands::Card[2, :hearts]
|
48
|
+
flush << Hands::Card[4, :hearts]
|
49
|
+
flush > pair # true
|
50
|
+
|
51
|
+
# Card comparison
|
52
|
+
card1 = Hands::Card.new(:value => 2, :suite => :hearts)
|
53
|
+
card2 = Hands::Card.new(:value => 3, :suite => :clubs)
|
54
|
+
card2 > card1 # true
|
55
|
+
```
|
56
|
+
|
57
|
+
## Running Tests
|
58
|
+
|
59
|
+
Running and reading the tests is (for now) the best way to see the functionality of this gem.
|
60
|
+
|
61
|
+
```
|
62
|
+
$ bundle
|
63
|
+
$ bundle exec rake spec
|
64
|
+
```
|
65
|
+
|
66
|
+
## Contributing
|
67
|
+
|
68
|
+
1. Fork it
|
69
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
70
|
+
3. Write a passing spec
|
71
|
+
4. Commit your changes (`git commit -am 'Added some feature'`)
|
72
|
+
5. Push to the branch (`git push origin my-new-feature`)
|
73
|
+
6. Create new Pull Request
|
data/hands.gemspec
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/hands/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ['Sam Soffes']
|
6
|
+
gem.email = ['sam@samsoff.es']
|
7
|
+
gem.description = 'Simple library for various poker hands calculations.'
|
8
|
+
gem.summary = 'Simple library for various poker hands calculations.'
|
9
|
+
gem.homepage = 'http://github.com/samsoffes/hands'
|
10
|
+
|
11
|
+
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
12
|
+
gem.files = `git ls-files`.split("\n")
|
13
|
+
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
14
|
+
gem.name = 'hands'
|
15
|
+
gem.require_paths = ['lib']
|
16
|
+
gem.version = Hands::VERSION
|
17
|
+
end
|
data/lib/hands/card.rb
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
module Hands
|
2
|
+
class Card
|
3
|
+
include Comparable
|
4
|
+
|
5
|
+
attr_accessor :suite
|
6
|
+
attr_accessor :value
|
7
|
+
|
8
|
+
def self.[](first = nil, second = nil)
|
9
|
+
self.new(first, second)
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(first = nil, suite = nil)
|
13
|
+
# Value provided
|
14
|
+
if first.is_a?(Integer) or first.is_a?(String)
|
15
|
+
self.value = first
|
16
|
+
|
17
|
+
# Hash provided
|
18
|
+
elsif first.is_a?(Hash)
|
19
|
+
self.value = first[:value] if first[:value]
|
20
|
+
self.suite = first[:suite] if first[:suite]
|
21
|
+
end
|
22
|
+
|
23
|
+
# Set suite
|
24
|
+
self.suite = suite if suite
|
25
|
+
end
|
26
|
+
|
27
|
+
def value=(val)
|
28
|
+
# Integer
|
29
|
+
if val.is_a?(Integer)
|
30
|
+
# Number range
|
31
|
+
if val > 0 and val <= 10
|
32
|
+
@value = val
|
33
|
+
return
|
34
|
+
|
35
|
+
# Face card or ace range
|
36
|
+
elsif val > 10 and val < 15
|
37
|
+
@value = VALUES[val - 2]
|
38
|
+
return
|
39
|
+
end
|
40
|
+
|
41
|
+
# String
|
42
|
+
elsif val.is_a?(String) and VALUES.include?(val.downcase)
|
43
|
+
@value = val.downcase
|
44
|
+
return
|
45
|
+
end
|
46
|
+
|
47
|
+
# Invalid
|
48
|
+
@value = nil
|
49
|
+
end
|
50
|
+
|
51
|
+
def inspect
|
52
|
+
if self.is_valid?
|
53
|
+
"#{super} #{self.description}"
|
54
|
+
else
|
55
|
+
super
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def is_valid?
|
60
|
+
SUITES.include?(self.suite.to_s) and VALUES.include?(self.value.to_s.downcase)
|
61
|
+
end
|
62
|
+
|
63
|
+
def is_invalid?
|
64
|
+
!self.is_valid?
|
65
|
+
end
|
66
|
+
|
67
|
+
def description
|
68
|
+
if self.is_valid?
|
69
|
+
"#{VALUE_DESCRIPTIONS[self.value_index].capitalize} of #{self.suite.to_s.capitalize}"
|
70
|
+
else
|
71
|
+
'invalid'
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def <=>(other_card, check_suite = false)
|
76
|
+
# TODO: Handle invalid cards
|
77
|
+
result = self.value_index <=> other_card.value_index
|
78
|
+
return self.suite_index <=> other_card.suite_index if result == 0 and check_suite
|
79
|
+
result
|
80
|
+
end
|
81
|
+
|
82
|
+
def suite_index
|
83
|
+
SUITES.index(self.suite.to_s.downcase)
|
84
|
+
end
|
85
|
+
|
86
|
+
def value_index
|
87
|
+
VALUES.index(self.value.to_s.downcase)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
data/lib/hands/hand.rb
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
module Hands
|
2
|
+
class Hand
|
3
|
+
include Comparable
|
4
|
+
|
5
|
+
attr_accessor :cards
|
6
|
+
|
7
|
+
def cards
|
8
|
+
@cards ||= []
|
9
|
+
end
|
10
|
+
|
11
|
+
def <=>(other_hand)
|
12
|
+
response = (self.hand_index <=> other_hand.hand_index)
|
13
|
+
|
14
|
+
# If the hands tie, see which is higher (i.e. higher pair)
|
15
|
+
if response == 0
|
16
|
+
self.cards <=> other_hand.cards
|
17
|
+
else
|
18
|
+
response
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def <<(card)
|
23
|
+
self.cards << card
|
24
|
+
end
|
25
|
+
|
26
|
+
def suites
|
27
|
+
self.cards.collect(&:suite).uniq
|
28
|
+
end
|
29
|
+
|
30
|
+
def best_hand
|
31
|
+
response = {}
|
32
|
+
HAND_ORDER.reverse.each do |type|
|
33
|
+
cards = self.send(type.to_sym)
|
34
|
+
next unless cards
|
35
|
+
response[:type] = type
|
36
|
+
response[:cards] = cards
|
37
|
+
break
|
38
|
+
end
|
39
|
+
response
|
40
|
+
end
|
41
|
+
|
42
|
+
def high_card
|
43
|
+
self.cards.sort.reverse
|
44
|
+
end
|
45
|
+
|
46
|
+
def pair
|
47
|
+
self.pairs(1)
|
48
|
+
end
|
49
|
+
|
50
|
+
def two_pair
|
51
|
+
self.pairs(2)
|
52
|
+
end
|
53
|
+
|
54
|
+
def three_of_a_kind
|
55
|
+
nil
|
56
|
+
end
|
57
|
+
|
58
|
+
def straight
|
59
|
+
return nil unless self.cards.length == 5
|
60
|
+
cs = self.cards.sort.reverse
|
61
|
+
|
62
|
+
# Ace's low
|
63
|
+
if cs.first.value == 'a' and cs[1].value == 5
|
64
|
+
# Move ace to end
|
65
|
+
ace = cs.first
|
66
|
+
cs = cs[1..4]
|
67
|
+
cs << ace
|
68
|
+
|
69
|
+
# Check succession
|
70
|
+
csr = cs.reverse
|
71
|
+
4.times do |i|
|
72
|
+
next if i == 0
|
73
|
+
return nil unless csr[i].value_index == i - 1
|
74
|
+
end
|
75
|
+
|
76
|
+
# Normal
|
77
|
+
else
|
78
|
+
# Check range
|
79
|
+
return nil unless cs.first.value_index - cs.last.value_index == 4
|
80
|
+
|
81
|
+
# Check succession
|
82
|
+
4.times do |i|
|
83
|
+
return nil unless cs[i].value_index == cs[i + 1].value_index + 1
|
84
|
+
end
|
85
|
+
end
|
86
|
+
cs
|
87
|
+
end
|
88
|
+
|
89
|
+
def flush
|
90
|
+
# If all of the cards are the same suite, we have a flush
|
91
|
+
return nil unless self.suites.length == 1
|
92
|
+
self.cards.sort.reverse
|
93
|
+
end
|
94
|
+
|
95
|
+
def full_house
|
96
|
+
# TODO: Implement
|
97
|
+
nil
|
98
|
+
end
|
99
|
+
|
100
|
+
def four_of_a_kind
|
101
|
+
# TODO: Implement
|
102
|
+
nil
|
103
|
+
end
|
104
|
+
|
105
|
+
def straight_flush
|
106
|
+
# TODO: Implement
|
107
|
+
nil
|
108
|
+
end
|
109
|
+
|
110
|
+
protected
|
111
|
+
|
112
|
+
def hand_index
|
113
|
+
best = self.best_hand
|
114
|
+
return -1 if best.nil?
|
115
|
+
HAND_ORDER.index(best[:type].to_s)
|
116
|
+
end
|
117
|
+
|
118
|
+
def duplicates
|
119
|
+
pairs = self.cards.collect(&:value)
|
120
|
+
pairs.uniq.select{ |e| (pairs - [e]).size < pairs.size - 1 }
|
121
|
+
end
|
122
|
+
|
123
|
+
def pairs(min)
|
124
|
+
dupes = self.duplicates
|
125
|
+
return nil if dupes.length < min
|
126
|
+
|
127
|
+
hand = self.cards.select do |card|
|
128
|
+
dupes.include?(card.value)
|
129
|
+
end
|
130
|
+
|
131
|
+
hand = hand.sort.reverse
|
132
|
+
hand << (self.cards - hand).sort.reverse
|
133
|
+
hand.flatten
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
data/lib/hands.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'hands/version'
|
2
|
+
require 'hands/card'
|
3
|
+
require 'hands/hand'
|
4
|
+
|
5
|
+
module Hands
|
6
|
+
SUITES = %w{ clubs diamonds hearts spades }
|
7
|
+
VALUES = %w{ 2 3 4 5 6 7 8 9 10 j q k a }
|
8
|
+
VALUE_DESCRIPTIONS = %w{ two three four five six seven eight nine ten jack queen king ace }
|
9
|
+
|
10
|
+
# See http://www.pagat.com/poker/rules/ranking.html
|
11
|
+
HAND_ORDER = %w{ high_card pair two_pair three_of_a_kind straight flush full_house four_of_a_kind straight_flush }
|
12
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Hands::Card do
|
4
|
+
it 'should validate cards' do
|
5
|
+
card = Hands::Card.new
|
6
|
+
card.is_valid?.should eq(false)
|
7
|
+
card.is_invalid?.should eq(true)
|
8
|
+
|
9
|
+
card.suite = :hearts
|
10
|
+
card.is_valid?.should eq(false)
|
11
|
+
|
12
|
+
card.value = 9
|
13
|
+
card.is_valid?.should eq(true)
|
14
|
+
|
15
|
+
card.suite = 17
|
16
|
+
card.is_valid?.should eq(false)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should allow for integers instead of characters for high cards' do
|
20
|
+
card1 = Hands::Card.new(:value => 11, :suite => :clubs)
|
21
|
+
|
22
|
+
card1.is_valid?.should eq(true)
|
23
|
+
card1.value.should eq('j')
|
24
|
+
|
25
|
+
card2 = Hands::Card.new(:value => 'j', :suite => :clubs)
|
26
|
+
card2.should eq(card1)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should be comparable' do
|
30
|
+
card1 = Hands::Card.new(:value => 2, :suite => :hearts)
|
31
|
+
card2 = Hands::Card.new(:value => 3, :suite => :clubs)
|
32
|
+
|
33
|
+
(card2 > card1).should eq(true)
|
34
|
+
(card1 < card2).should eq(true)
|
35
|
+
|
36
|
+
card1.value = 3
|
37
|
+
(card1 == card2).should eq(true)
|
38
|
+
(card1.<=>(card2, true)).should eq(1)
|
39
|
+
(card2.<=>(card1, true)).should eq(-1)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should be sortable' do
|
43
|
+
c2 = Hands::Card.new(:value => 2, :suite => :hearts)
|
44
|
+
c3 = Hands::Card.new(:value => 3, :suite => :hearts)
|
45
|
+
c4 = Hands::Card.new(:value => 4, :suite => :hearts)
|
46
|
+
c5 = Hands::Card.new(:value => 5, :suite => :hearts)
|
47
|
+
c6 = Hands::Card.new(:value => 6, :suite => :hearts)
|
48
|
+
c7 = Hands::Card.new(:value => 7, :suite => :hearts)
|
49
|
+
c8 = Hands::Card.new(:value => 8, :suite => :hearts)
|
50
|
+
c9 = Hands::Card.new(:value => 9, :suite => :hearts)
|
51
|
+
c10 = Hands::Card.new(:value => 10, :suite => :hearts)
|
52
|
+
cJ = Hands::Card.new(:value => 'j', :suite => :hearts)
|
53
|
+
cQ = Hands::Card.new(:value => 'q', :suite => :hearts)
|
54
|
+
cK = Hands::Card.new(:value => 'k', :suite => :hearts)
|
55
|
+
cA = Hands::Card.new(:value => 'a', :suite => :hearts)
|
56
|
+
|
57
|
+
cards = [c2, c3, c4, c5, c6, c7, c8, c9, c10, cJ, cQ, cK, cA]
|
58
|
+
cards.sort.should eq(cards)
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Hands::Hand do
|
4
|
+
it 'should order different types of hands' do
|
5
|
+
pair = Hands::Hand.new
|
6
|
+
pair << Hands::Card[2, :hearts]
|
7
|
+
pair << Hands::Card[2, :clubs]
|
8
|
+
|
9
|
+
flush = Hands::Hand.new
|
10
|
+
flush << Hands::Card[6, :hearts]
|
11
|
+
flush << Hands::Card[7, :hearts]
|
12
|
+
flush << Hands::Card[8, :hearts]
|
13
|
+
flush << Hands::Card[2, :hearts]
|
14
|
+
flush << Hands::Card[4, :hearts]
|
15
|
+
(flush > pair).should eq(true)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should order same types of hands' do
|
19
|
+
small_pair = Hands::Hand.new
|
20
|
+
small_pair << Hands::Card[2, :hearts]
|
21
|
+
small_pair << Hands::Card[2, :clubs]
|
22
|
+
|
23
|
+
large_pair = Hands::Hand.new
|
24
|
+
large_pair << Hands::Card['A', :hearts]
|
25
|
+
large_pair << Hands::Card['A', :clubs]
|
26
|
+
(large_pair > small_pair).should eq(true)
|
27
|
+
|
28
|
+
small_kicker = Hands::Hand.new
|
29
|
+
small_kicker << Hands::Card['A', :spades]
|
30
|
+
small_kicker << Hands::Card['A', :diamonds]
|
31
|
+
small_kicker << Hands::Card[2, :diamonds]
|
32
|
+
small_kicker << Hands::Card[3, :diamonds]
|
33
|
+
small_kicker << Hands::Card[4, :diamonds]
|
34
|
+
|
35
|
+
big_kicker = Hands::Hand.new
|
36
|
+
big_kicker << Hands::Card['A', :hearts]
|
37
|
+
big_kicker << Hands::Card['A', :clubs]
|
38
|
+
big_kicker << Hands::Card[10, :diamonds]
|
39
|
+
big_kicker << Hands::Card[9, :diamonds]
|
40
|
+
big_kicker << Hands::Card[7, :diamonds]
|
41
|
+
(big_kicker > small_kicker).should eq(true)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should collect suites' do
|
45
|
+
hand = Hands::Hand.new
|
46
|
+
hand << Hands::Card[2, :hearts]
|
47
|
+
hand << Hands::Card[2, :clubs]
|
48
|
+
hand.suites.should eq([:hearts, :clubs])
|
49
|
+
|
50
|
+
hand << Hands::Card[3, :clubs]
|
51
|
+
hand.suites.should eq([:hearts, :clubs])
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'should recognize high card' do
|
55
|
+
hand = Hands::Hand.new
|
56
|
+
hand << Hands::Card[2, :hearts]
|
57
|
+
hand << Hands::Card[9, :clubs]
|
58
|
+
hand << Hands::Card[7, :hearts]
|
59
|
+
hand << Hands::Card['a', :spades]
|
60
|
+
hand << Hands::Card[4, :diamonds]
|
61
|
+
hand.high_card.collect(&:value).should eq(['a', 9, 7, 4, 2])
|
62
|
+
hand.pair.should eql(nil)
|
63
|
+
hand.two_pair.should eql(nil)
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should recognize a pair' do
|
67
|
+
hand = Hands::Hand.new
|
68
|
+
hand << Hands::Card[9, :hearts]
|
69
|
+
hand << Hands::Card[9, :clubs]
|
70
|
+
hand << Hands::Card[7, :hearts]
|
71
|
+
hand << Hands::Card[2, :spades]
|
72
|
+
hand << Hands::Card[4, :diamonds]
|
73
|
+
hand.pair.collect(&:value).should eq([9, 9, 7, 4, 2])
|
74
|
+
hand.two_pair.should eql(nil)
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'should recognize two pair' do
|
78
|
+
hand = Hands::Hand.new
|
79
|
+
hand << Hands::Card[7, :hearts]
|
80
|
+
hand << Hands::Card[7, :spades]
|
81
|
+
hand << Hands::Card[4, :diamonds]
|
82
|
+
hand << Hands::Card[9, :hearts]
|
83
|
+
hand << Hands::Card[9, :clubs]
|
84
|
+
hand.two_pair.collect(&:value).should eq([9, 9, 7, 7, 4])
|
85
|
+
hand.two_pair.should eql(hand.pair)
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'should recognize three of a kind'
|
89
|
+
|
90
|
+
it 'should recognize a straight' do
|
91
|
+
hand1 = Hands::Hand.new
|
92
|
+
hand1 << Hands::Card[2, :hearts]
|
93
|
+
hand1 << Hands::Card[3, :spades]
|
94
|
+
hand1 << Hands::Card[4, :diamonds]
|
95
|
+
hand1 << Hands::Card[5, :hearts]
|
96
|
+
hand1 << Hands::Card[6, :clubs]
|
97
|
+
hand1.best_hand[:type].should eq('straight')
|
98
|
+
|
99
|
+
hand2 = Hands::Hand.new
|
100
|
+
hand2 << Hands::Card['A', :hearts]
|
101
|
+
hand2 << Hands::Card[2, :spades]
|
102
|
+
hand2 << Hands::Card[3, :diamonds]
|
103
|
+
hand2 << Hands::Card[4, :hearts]
|
104
|
+
hand2 << Hands::Card[5, :clubs]
|
105
|
+
hand2.best_hand[:type].should eq('straight')
|
106
|
+
|
107
|
+
hand3 = Hands::Hand.new
|
108
|
+
hand3 << Hands::Card[10, :hearts]
|
109
|
+
hand3 << Hands::Card['J', :spades]
|
110
|
+
hand3 << Hands::Card['Q', :diamonds]
|
111
|
+
hand3 << Hands::Card['K', :hearts]
|
112
|
+
hand3 << Hands::Card['A', :clubs]
|
113
|
+
hand3.best_hand[:type].should eq('straight')
|
114
|
+
|
115
|
+
hand4 = Hands::Hand.new
|
116
|
+
hand4 << Hands::Card['J', :spades]
|
117
|
+
hand4 << Hands::Card['Q', :diamonds]
|
118
|
+
hand4 << Hands::Card['K', :hearts]
|
119
|
+
hand4 << Hands::Card['A', :clubs]
|
120
|
+
hand4 << Hands::Card[2, :hearts]
|
121
|
+
hand4.best_hand[:type].should eq('high_card')
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'should recognize a flush' do
|
125
|
+
hand = Hands::Hand.new
|
126
|
+
hand << Hands::Card[6, :hearts]
|
127
|
+
hand << Hands::Card[7, :hearts]
|
128
|
+
hand << Hands::Card[8, :hearts]
|
129
|
+
hand << Hands::Card[2, :hearts]
|
130
|
+
hand << Hands::Card[4, :hearts]
|
131
|
+
hand.best_hand[:type].should eq('flush')
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'should recognize a full house'
|
135
|
+
it 'should recognize four of a kind'
|
136
|
+
it 'should recognize a straight flush'
|
137
|
+
|
138
|
+
it 'should recognize the best hand' do
|
139
|
+
hand = Hands::Hand.new
|
140
|
+
hand << Hands::Card[7, :hearts]
|
141
|
+
hand << Hands::Card[7, :spades]
|
142
|
+
hand << Hands::Card[4, :diamonds]
|
143
|
+
hand << Hands::Card[9, :hearts]
|
144
|
+
hand << Hands::Card[9, :clubs]
|
145
|
+
hand.best_hand[:type].should eq('two_pair')
|
146
|
+
end
|
147
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: hands
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Sam Soffes
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-12-23 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Simple library for various poker hands calculations.
|
15
|
+
email:
|
16
|
+
- sam@samsoff.es
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- .gitignore
|
22
|
+
- Gemfile
|
23
|
+
- LICENSE
|
24
|
+
- Rakefile
|
25
|
+
- Readme.markdown
|
26
|
+
- hands.gemspec
|
27
|
+
- lib/hands.rb
|
28
|
+
- lib/hands/card.rb
|
29
|
+
- lib/hands/hand.rb
|
30
|
+
- lib/hands/version.rb
|
31
|
+
- spec/models/card_spec.rb
|
32
|
+
- spec/models/hand_spec.rb
|
33
|
+
- spec/spec_helper.rb
|
34
|
+
homepage: http://github.com/samsoffes/hands
|
35
|
+
licenses: []
|
36
|
+
post_install_message:
|
37
|
+
rdoc_options: []
|
38
|
+
require_paths:
|
39
|
+
- lib
|
40
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
47
|
+
none: false
|
48
|
+
requirements:
|
49
|
+
- - ! '>='
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '0'
|
52
|
+
requirements: []
|
53
|
+
rubyforge_project:
|
54
|
+
rubygems_version: 1.8.11
|
55
|
+
signing_key:
|
56
|
+
specification_version: 3
|
57
|
+
summary: Simple library for various poker hands calculations.
|
58
|
+
test_files:
|
59
|
+
- spec/models/card_spec.rb
|
60
|
+
- spec/models/hand_spec.rb
|
61
|
+
- spec/spec_helper.rb
|