poker_hands 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +0 -0
- data/Rakefile +6 -0
- data/lib/deck/card.rb +10 -0
- data/lib/deck/cards.rb +4 -0
- data/lib/deck/deck.rb +17 -0
- data/lib/deck/hand.rb +37 -0
- data/lib/deck/rank_selector.rb +58 -0
- data/lib/poker_hands.rb +32 -0
- data/lib/rank/flush.rb +5 -0
- data/lib/rank/four_of_a_kind.rb +11 -0
- data/lib/rank/full_house.rb +11 -0
- data/lib/rank/high_card.rb +5 -0
- data/lib/rank/pair.rb +15 -0
- data/lib/rank/rank.rb +18 -0
- data/lib/rank/straight.rb +5 -0
- data/lib/rank/straight_flush.rb +5 -0
- data/lib/rank/three_of_a_kind.rb +11 -0
- data/lib/rank/two_pairs.rb +9 -0
- data/poker-hands.gemspec +18 -0
- data/spec/hand_spec.rb +72 -0
- data/spec/spec_helper.rb +43 -0
- data/spec/support/test_helpers.rb +321 -0
- data/spec/table_spec.rb +202 -0
- metadata +68 -0
data/README.md
ADDED
File without changes
|
data/Rakefile
ADDED
data/lib/deck/card.rb
ADDED
data/lib/deck/cards.rb
ADDED
data/lib/deck/deck.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
module Deck
|
2
|
+
class Deck
|
3
|
+
attr_reader :cards
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@cards = []
|
7
|
+
end
|
8
|
+
|
9
|
+
def create_cards
|
10
|
+
::Deck::Cards::VALUES.each do |value|
|
11
|
+
::Deck::Cards::SUITS.each do |suit|
|
12
|
+
@cards << {value: value, suit: suit}
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/deck/hand.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
module Deck
|
2
|
+
class Hand
|
3
|
+
include Deck::RankSelector
|
4
|
+
include Comparable
|
5
|
+
|
6
|
+
attr_reader :hand, :rank
|
7
|
+
|
8
|
+
def initialize(hand)
|
9
|
+
@hand = hand
|
10
|
+
@rank = select_rank
|
11
|
+
end
|
12
|
+
|
13
|
+
def only_values
|
14
|
+
@hand.map { |card| card.value}
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def select_rank
|
20
|
+
return Rank::StraightFlush.new(self) if is_straight_flush?
|
21
|
+
return Rank::FourOfAKind.new(self) if is_four_of_a_kind?
|
22
|
+
return Rank::FullHouse.new(self) if is_full_house?
|
23
|
+
return Rank::Flush.new(self) if is_flush?
|
24
|
+
return Rank::Straight.new(self) if is_straight?
|
25
|
+
return Rank::ThreeOfAKind.new(self) if is_three_of_a_kind?
|
26
|
+
return Rank::TwoPairs.new(self) if is_two_pairs?
|
27
|
+
return Rank::Pair.new(self) if is_pair?
|
28
|
+
Rank::HighCard.new(self)
|
29
|
+
end
|
30
|
+
|
31
|
+
def <=>(hand)
|
32
|
+
self.rank <=> hand.rank
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Deck::RankSelector
|
2
|
+
|
3
|
+
def is_pair?
|
4
|
+
only_value = @hand.map { |card| card.value}
|
5
|
+
only_value.detect { |card| only_value.count(card) > 1}
|
6
|
+
end
|
7
|
+
|
8
|
+
def is_two_pairs?
|
9
|
+
only_value = @hand.map { |card| card.value}
|
10
|
+
first_value = only_value.detect { |card| only_value.count(card) == 2}
|
11
|
+
if first_value
|
12
|
+
only_value.delete(first_value)
|
13
|
+
return only_value.detect { |card| only_value.count(card) == 2}
|
14
|
+
end
|
15
|
+
nil
|
16
|
+
end
|
17
|
+
|
18
|
+
def is_three_of_a_kind?
|
19
|
+
only_value = @hand.map { |card| card.value}
|
20
|
+
only_value.detect { |card| only_value.count(card) == 3}
|
21
|
+
end
|
22
|
+
|
23
|
+
def is_straight?
|
24
|
+
only_value = @hand.map { |card| card.value}
|
25
|
+
sorted_only_value = only_value.sort
|
26
|
+
only_value === sorted_only_value
|
27
|
+
end
|
28
|
+
|
29
|
+
def is_flush?
|
30
|
+
only_suits = @hand.map { |card| card.suit}
|
31
|
+
only_suits.detect { |card| only_suits.count(card) == 5}
|
32
|
+
end
|
33
|
+
|
34
|
+
def is_full_house?
|
35
|
+
only_value = @hand.map { |card| card.value}
|
36
|
+
first_value = only_value.detect { |card| only_value.count(card) == 3}
|
37
|
+
if first_value
|
38
|
+
only_value.delete(first_value)
|
39
|
+
return only_value.detect { |card| only_value.count(card) == 2}
|
40
|
+
end
|
41
|
+
nil
|
42
|
+
end
|
43
|
+
|
44
|
+
def is_four_of_a_kind?
|
45
|
+
only_value = @hand.map { |card| card.value}
|
46
|
+
only_value.detect { |card| only_value.count(card) == 4}
|
47
|
+
end
|
48
|
+
|
49
|
+
def is_straight_flush?
|
50
|
+
only_suits = @hand.map { |card| card.suit}
|
51
|
+
all_same_suit = only_suits.detect { |card| only_suits.count(card) == 5}
|
52
|
+
|
53
|
+
only_value = @hand.map { |card| card.value}
|
54
|
+
sorted_only_value = only_value.sort
|
55
|
+
all_same_suit && only_value === sorted_only_value
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
data/lib/poker_hands.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
class PokerHands
|
2
|
+
attr_accessor :hands
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
@hands = []
|
6
|
+
end
|
7
|
+
|
8
|
+
def winner
|
9
|
+
sorted_hands = @hands.sort { |a, b| a.rank.class::SCORE <=> b.rank.class::SCORE }
|
10
|
+
if sorted_hands.size > 1 && same_best_rank?(sorted_hands.reverse)
|
11
|
+
find_winner_if_same_rank(sorted_hands.reverse)
|
12
|
+
else
|
13
|
+
sorted_hands.last
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def <<(hand)
|
18
|
+
@hands << hand
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def same_best_rank?(rank)
|
24
|
+
rank.first.rank.class == rank.second.rank.class
|
25
|
+
end
|
26
|
+
|
27
|
+
def find_winner_if_same_rank(sorted_hands)
|
28
|
+
rank_class = sorted_hands.first.rank.class
|
29
|
+
same_rank_hands = sorted_hands.select{|hand| hand.rank.class == rank_class}
|
30
|
+
same_rank_hands.sort.last
|
31
|
+
end
|
32
|
+
end
|
data/lib/rank/flush.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
module Rank
|
2
|
+
class FourOfAKind < Rank
|
3
|
+
SCORE = 8
|
4
|
+
|
5
|
+
def <=>(hand)
|
6
|
+
first_value = @hand.only_values.detect { |hd| @hand.only_values.count(hd) == 4}
|
7
|
+
second_value = hand.only_values.detect { |hd| @hand.only_values.count(hd) == 4}
|
8
|
+
first_value <=> second_value
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Rank
|
2
|
+
class FullHouse < Rank
|
3
|
+
SCORE = 7
|
4
|
+
|
5
|
+
def <=>(hand)
|
6
|
+
first_value = @hand.only_values.detect { |hd| @hand.only_values.count(hd) == 3}
|
7
|
+
second_value = hand.only_values.detect { |hd| hand.only_values.count(hd) == 3}
|
8
|
+
first_value <=> second_value
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
data/lib/rank/pair.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
module Rank
|
2
|
+
class Pair < Rank
|
3
|
+
SCORE = 2
|
4
|
+
|
5
|
+
def <=>(hand)
|
6
|
+
hand_1 = @hand.only_values
|
7
|
+
hand_2 = hand.only_values
|
8
|
+
first_value = hand_1.detect { |hd| hand_1.count(hd) == 2}
|
9
|
+
second_value = hand_2.detect { |hd| hand_2.count(hd) == 2}
|
10
|
+
hand_1.delete_if { |card| card == first_value }
|
11
|
+
hand_2.delete_if { |card| card == second_value }
|
12
|
+
hand_1 <=> hand_2
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/rank/rank.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
module Rank
|
2
|
+
class Rank
|
3
|
+
include Comparable
|
4
|
+
def initialize(hand)
|
5
|
+
@hand = hand
|
6
|
+
end
|
7
|
+
|
8
|
+
def only_values
|
9
|
+
@hand.hand.map { |card| card.value}
|
10
|
+
end
|
11
|
+
|
12
|
+
def <=>(hand)
|
13
|
+
hand_1 = @hand.only_values.sort.join('').to_i
|
14
|
+
hand_2 = hand.only_values.sort.join('').to_i
|
15
|
+
hand_1 <=> hand_2
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Rank
|
2
|
+
class ThreeOfAKind < Rank
|
3
|
+
SCORE = 4
|
4
|
+
|
5
|
+
def <=>(hand)
|
6
|
+
first_value = @hand.only_values.detect { |hd| @hand.only_values.count(hd) == 3}
|
7
|
+
second_value = hand.only_values.detect { |hd| @hand.only_values.count(hd) == 3}
|
8
|
+
first_value <=> second_value
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
data/poker-hands.gemspec
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'poker_hands'
|
7
|
+
s.date = '2013-08-16'
|
8
|
+
s.summary = "Sample app to play poker"
|
9
|
+
s.description = "Sample app to play poker"
|
10
|
+
s.authors = ["Cosimo Ranieri"]
|
11
|
+
s.email = 'co.ranieri@gmail.com'
|
12
|
+
s.files = %w(README.md Rakefile poker-hands.gemspec)
|
13
|
+
s.files += Dir.glob("lib/**/*")
|
14
|
+
s.files += Dir.glob("spec/**/*")
|
15
|
+
s.version = '0.0.1'
|
16
|
+
s.homepage = 'https://rubygems.org/gems/poker-hands'
|
17
|
+
s.license = 'MIT'
|
18
|
+
end
|
data/spec/hand_spec.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Hand do
|
4
|
+
|
5
|
+
describe ".new" do
|
6
|
+
context "the hand is a high card" do
|
7
|
+
let(:hand) { Hand.new(high_card)}
|
8
|
+
it "creates a high card hand" do
|
9
|
+
expect(hand.rank.class).to eq HighCard
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
context "the hand is a pair" do
|
14
|
+
let(:hand) { Hand.new(pair)}
|
15
|
+
it "creates a high card hand" do
|
16
|
+
expect(hand.rank.class).to eq Pair
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context "the hand is two pairs" do
|
21
|
+
let(:hand) { Hand.new(two_pairs)}
|
22
|
+
it "creates a high card hand" do
|
23
|
+
expect(hand.rank.class).to eq TwoPairs
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context "the hand is three of a kind" do
|
28
|
+
let(:hand) { Hand.new(three_of_a_kind)}
|
29
|
+
it "creates a high card hand" do
|
30
|
+
expect(hand.rank.class).to eq ThreeOfAKind
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context "the hand is straight" do
|
35
|
+
let(:hand) { Hand.new(straight)}
|
36
|
+
it "creates a high card hand" do
|
37
|
+
expect(hand.rank.class).to eq Straight
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context "the hand is a flush" do
|
42
|
+
let(:hand) { Hand.new(flush)}
|
43
|
+
it "creates a flush hand" do
|
44
|
+
expect(hand.rank.class).to eq Flush
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "the hand is a full house" do
|
49
|
+
let(:hand) { Hand.new(full_house)}
|
50
|
+
it "creates a flush full house" do
|
51
|
+
expect(hand.rank.class).to eq FullHouse
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context "the hand is a four of a kind" do
|
56
|
+
let(:hand) { Hand.new(four_of_a_kind)}
|
57
|
+
it "creates a four of a kind full house" do
|
58
|
+
expect(hand.rank.class).to eq FourOfAKind
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "the hand is a straight flush" do
|
63
|
+
let(:hand) { Hand.new(straight_flush)}
|
64
|
+
it "creates a four of a straight flush" do
|
65
|
+
expect(hand.rank.class).to eq StraightFlush
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
# This file is copied to spec/ when you run 'rails generate rspec:install'
|
2
|
+
ENV["RAILS_ENV"] ||= 'test'
|
3
|
+
require File.expand_path("../../config/environment", __FILE__)
|
4
|
+
require 'rspec/rails'
|
5
|
+
require 'rspec/autorun'
|
6
|
+
|
7
|
+
# Requires supporting ruby files with custom matchers and macros, etc,
|
8
|
+
# in spec/support/ and its subdirectories.
|
9
|
+
#Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
|
10
|
+
Dir["spec/support/**/*.rb"].each { |f| require File.expand_path(f) }
|
11
|
+
|
12
|
+
RSpec.configure do |config|
|
13
|
+
# ## Mock Framework
|
14
|
+
#
|
15
|
+
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
|
16
|
+
#
|
17
|
+
# config.mock_with :mocha
|
18
|
+
# config.mock_with :flexmock
|
19
|
+
# config.mock_with :rr
|
20
|
+
|
21
|
+
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
|
22
|
+
config.fixture_path = "#{::Rails.root}/spec/fixtures"
|
23
|
+
|
24
|
+
# If you're not using ActiveRecord, or you'd prefer not to run each of your
|
25
|
+
# examples within a transaction, remove the following line or assign false
|
26
|
+
# instead of true.
|
27
|
+
config.use_transactional_fixtures = true
|
28
|
+
|
29
|
+
# If true, the base class of anonymous controllers will be inferred
|
30
|
+
# automatically. This will be the default behavior in future versions of
|
31
|
+
# rspec-rails.
|
32
|
+
config.infer_base_class_for_anonymous_controllers = false
|
33
|
+
|
34
|
+
# Run specs in random order to surface order dependencies. If you find an
|
35
|
+
# order dependency and want to debug it, you can fix the order by providing
|
36
|
+
# the seed, which is printed after each run.
|
37
|
+
# --seed 1234
|
38
|
+
config.order = "random"
|
39
|
+
|
40
|
+
config.include TestHelpers
|
41
|
+
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,321 @@
|
|
1
|
+
module TestHelpers
|
2
|
+
def high_card
|
3
|
+
[{:value=>"2", :suit=>"D"},
|
4
|
+
{:value=>"5", :suit=>"H"},
|
5
|
+
{:value=>"4", :suit=>"D"},
|
6
|
+
{:value=>"7", :suit=>"D"},
|
7
|
+
{:value=>"8", :suit=>"D"}]
|
8
|
+
end
|
9
|
+
|
10
|
+
def high_card_same_highest_1
|
11
|
+
[{:value=>"2", :suit=>"D"},
|
12
|
+
{:value=>"5", :suit=>"H"},
|
13
|
+
{:value=>"4", :suit=>"D"},
|
14
|
+
{:value=>"7", :suit=>"D"},
|
15
|
+
{:value=>"8", :suit=>"D"}]
|
16
|
+
end
|
17
|
+
|
18
|
+
def high_card_same_highest_2
|
19
|
+
[{:value=>"2", :suit=>"D"},
|
20
|
+
{:value=>"5", :suit=>"H"},
|
21
|
+
{:value=>"4", :suit=>"D"},
|
22
|
+
{:value=>"6", :suit=>"D"},
|
23
|
+
{:value=>"8", :suit=>"D"}]
|
24
|
+
end
|
25
|
+
|
26
|
+
def hand_high_card_same_highest
|
27
|
+
[Hand.new(high_card_same_highest_1),
|
28
|
+
Hand.new(high_card_same_highest_2)]
|
29
|
+
end
|
30
|
+
|
31
|
+
def pair
|
32
|
+
[{:value=>"2", :suit=>"D"},
|
33
|
+
{:value=>"2", :suit=>"H"},
|
34
|
+
{:value=>"4", :suit=>"D"},
|
35
|
+
{:value=>"3", :suit=>"D"},
|
36
|
+
{:value=>"8", :suit=>"D"}]
|
37
|
+
end
|
38
|
+
|
39
|
+
def same_pair_1
|
40
|
+
[{:value=>"2", :suit=>"D"},
|
41
|
+
{:value=>"2", :suit=>"H"},
|
42
|
+
{:value=>"3", :suit=>"S"},
|
43
|
+
{:value=>"5", :suit=>"D"},
|
44
|
+
{:value=>"8", :suit=>"D"}]
|
45
|
+
end
|
46
|
+
|
47
|
+
def same_pair_2
|
48
|
+
[{:value=>"2", :suit=>"D"},
|
49
|
+
{:value=>"2", :suit=>"H"},
|
50
|
+
{:value=>"3", :suit=>"S"},
|
51
|
+
{:value=>"4", :suit=>"D"},
|
52
|
+
{:value=>"7", :suit=>"D"}]
|
53
|
+
end
|
54
|
+
|
55
|
+
def hand_same_pair
|
56
|
+
[Hand.new(same_pair_1),
|
57
|
+
Hand.new(same_pair_2)]
|
58
|
+
end
|
59
|
+
|
60
|
+
def two_pairs
|
61
|
+
[{:value=>"2", :suit=>"D"},
|
62
|
+
{:value=>"2", :suit=>"H"},
|
63
|
+
{:value=>"9", :suit=>"H"},
|
64
|
+
{:value=>"9", :suit=>"S"},
|
65
|
+
{:value=>"8", :suit=>"D"}]
|
66
|
+
end
|
67
|
+
|
68
|
+
def same_two_pair_1
|
69
|
+
[{:value=>"2", :suit=>"D"},
|
70
|
+
{:value=>"2", :suit=>"H"},
|
71
|
+
{:value=>"9", :suit=>"H"},
|
72
|
+
{:value=>"9", :suit=>"S"},
|
73
|
+
{:value=>"8", :suit=>"D"}]
|
74
|
+
end
|
75
|
+
|
76
|
+
def same_two_pair_2
|
77
|
+
[{:value=>"2", :suit=>"D"},
|
78
|
+
{:value=>"2", :suit=>"H"},
|
79
|
+
{:value=>"9", :suit=>"H"},
|
80
|
+
{:value=>"9", :suit=>"S"},
|
81
|
+
{:value=>"6", :suit=>"D"}]
|
82
|
+
end
|
83
|
+
|
84
|
+
def hand_same_two_pairs
|
85
|
+
[Hand.new(same_pair_1),
|
86
|
+
Hand.new(same_pair_2)]
|
87
|
+
end
|
88
|
+
|
89
|
+
def three_of_a_kind
|
90
|
+
[{:value=>"2", :suit=>"D"},
|
91
|
+
{:value=>"2", :suit=>"H"},
|
92
|
+
{:value=>"2", :suit=>"H"},
|
93
|
+
{:value=>"9", :suit=>"S"},
|
94
|
+
{:value=>"8", :suit=>"D"}]
|
95
|
+
end
|
96
|
+
|
97
|
+
def same_three_of_a_kind_1
|
98
|
+
[{:value=>"2", :suit=>"D"},
|
99
|
+
{:value=>"2", :suit=>"H"},
|
100
|
+
{:value=>"2", :suit=>"H"},
|
101
|
+
{:value=>"6", :suit=>"S"},
|
102
|
+
{:value=>"8", :suit=>"D"}]
|
103
|
+
end
|
104
|
+
|
105
|
+
def same_three_of_a_kind_2
|
106
|
+
[{:value=>"2", :suit=>"D"},
|
107
|
+
{:value=>"2", :suit=>"H"},
|
108
|
+
{:value=>"2", :suit=>"H"},
|
109
|
+
{:value=>"7", :suit=>"S"},
|
110
|
+
{:value=>"8", :suit=>"D"}]
|
111
|
+
end
|
112
|
+
|
113
|
+
def hand_some_three_of_a_kind
|
114
|
+
[Hand.new(same_three_of_a_kind_1),
|
115
|
+
Hand.new(same_three_of_a_kind_2)]
|
116
|
+
end
|
117
|
+
|
118
|
+
def straight
|
119
|
+
[{:value=>"2", :suit=>"D"},
|
120
|
+
{:value=>"3", :suit=>"H"},
|
121
|
+
{:value=>"4", :suit=>"H"},
|
122
|
+
{:value=>"5", :suit=>"S"},
|
123
|
+
{:value=>"6", :suit=>"D"}]
|
124
|
+
end
|
125
|
+
|
126
|
+
def same_stright_1
|
127
|
+
[{:value=>"2", :suit=>"D"},
|
128
|
+
{:value=>"3", :suit=>"H"},
|
129
|
+
{:value=>"4", :suit=>"H"},
|
130
|
+
{:value=>"5", :suit=>"S"},
|
131
|
+
{:value=>"6", :suit=>"D"}]
|
132
|
+
end
|
133
|
+
|
134
|
+
def same_stright_2
|
135
|
+
[{:value=>"2", :suit=>"D"},
|
136
|
+
{:value=>"3", :suit=>"H"},
|
137
|
+
{:value=>"4", :suit=>"H"},
|
138
|
+
{:value=>"5", :suit=>"S"},
|
139
|
+
{:value=>"8", :suit=>"D"}]
|
140
|
+
end
|
141
|
+
|
142
|
+
def hand_same_straight
|
143
|
+
[Hand.new(same_stright_1),
|
144
|
+
Hand.new(same_stright_2)]
|
145
|
+
end
|
146
|
+
|
147
|
+
def flush
|
148
|
+
[{:value=>"2", :suit=>"D"},
|
149
|
+
{:value=>"3", :suit=>"D"},
|
150
|
+
{:value=>"8", :suit=>"D"},
|
151
|
+
{:value=>"5", :suit=>"D"},
|
152
|
+
{:value=>"6", :suit=>"D"}]
|
153
|
+
end
|
154
|
+
|
155
|
+
def flush_1
|
156
|
+
[{:value=>"2", :suit=>"D"},
|
157
|
+
{:value=>"3", :suit=>"D"},
|
158
|
+
{:value=>"8", :suit=>"D"},
|
159
|
+
{:value=>"5", :suit=>"D"},
|
160
|
+
{:value=>"6", :suit=>"D"}]
|
161
|
+
end
|
162
|
+
|
163
|
+
def flush_2
|
164
|
+
[{:value=>"2", :suit=>"D"},
|
165
|
+
{:value=>"3", :suit=>"D"},
|
166
|
+
{:value=>"4", :suit=>"D"},
|
167
|
+
{:value=>"5", :suit=>"D"},
|
168
|
+
{:value=>"6", :suit=>"D"}]
|
169
|
+
end
|
170
|
+
|
171
|
+
def hand_two_flush
|
172
|
+
[Hand.new(same_stright_1),
|
173
|
+
Hand.new(same_stright_2)]
|
174
|
+
end
|
175
|
+
|
176
|
+
def full_house
|
177
|
+
[{:value=>"4", :suit=>"D"},
|
178
|
+
{:value=>"4", :suit=>"D"},
|
179
|
+
{:value=>"4", :suit=>"H"},
|
180
|
+
{:value=>"5", :suit=>"S"},
|
181
|
+
{:value=>"5", :suit=>"D"}]
|
182
|
+
end
|
183
|
+
|
184
|
+
def same_full_house_1
|
185
|
+
[{:value=>"4", :suit=>"D"},
|
186
|
+
{:value=>"4", :suit=>"D"},
|
187
|
+
{:value=>"4", :suit=>"H"},
|
188
|
+
{:value=>"3", :suit=>"S"},
|
189
|
+
{:value=>"3", :suit=>"D"}]
|
190
|
+
end
|
191
|
+
|
192
|
+
def same_full_house_2
|
193
|
+
[{:value=>"5", :suit=>"D"},
|
194
|
+
{:value=>"5", :suit=>"D"},
|
195
|
+
{:value=>"5", :suit=>"H"},
|
196
|
+
{:value=>"2", :suit=>"S"},
|
197
|
+
{:value=>"2", :suit=>"D"}]
|
198
|
+
end
|
199
|
+
|
200
|
+
def hand_same_full_house
|
201
|
+
[Hand.new(same_full_house_1),
|
202
|
+
Hand.new(same_full_house_2)]
|
203
|
+
end
|
204
|
+
|
205
|
+
def four_of_a_kind
|
206
|
+
[{:value=>"4", :suit=>"D"},
|
207
|
+
{:value=>"4", :suit=>"D"},
|
208
|
+
{:value=>"4", :suit=>"H"},
|
209
|
+
{:value=>"4", :suit=>"S"},
|
210
|
+
{:value=>"5", :suit=>"D"}]
|
211
|
+
end
|
212
|
+
|
213
|
+
def same_four_of_a_kind
|
214
|
+
[{:value=>"5", :suit=>"D"},
|
215
|
+
{:value=>"5", :suit=>"D"},
|
216
|
+
{:value=>"5", :suit=>"H"},
|
217
|
+
{:value=>"5", :suit=>"S"},
|
218
|
+
{:value=>"6", :suit=>"D"}]
|
219
|
+
end
|
220
|
+
|
221
|
+
def hand_same_four_of_a_kind
|
222
|
+
[Hand.new(four_of_a_kind),
|
223
|
+
Hand.new(same_four_of_a_kind)]
|
224
|
+
end
|
225
|
+
|
226
|
+
def straight_flush
|
227
|
+
[{:value=>"2", :suit=>"D"},
|
228
|
+
{:value=>"3", :suit=>"D"},
|
229
|
+
{:value=>"4", :suit=>"D"},
|
230
|
+
{:value=>"5", :suit=>"D"},
|
231
|
+
{:value=>"6", :suit=>"D"}]
|
232
|
+
end
|
233
|
+
|
234
|
+
def straight_flush_2
|
235
|
+
[{:value=>"2", :suit=>"S"},
|
236
|
+
{:value=>"3", :suit=>"S"},
|
237
|
+
{:value=>"4", :suit=>"S"},
|
238
|
+
{:value=>"6", :suit=>"S"},
|
239
|
+
{:value=>"8", :suit=>"S"}]
|
240
|
+
end
|
241
|
+
|
242
|
+
def hand_two_straight_flush
|
243
|
+
[Hand.new(straight_flush),
|
244
|
+
Hand.new(straight_flush_2)]
|
245
|
+
end
|
246
|
+
|
247
|
+
def hand_straight_flush
|
248
|
+
[Hand.new(straight_flush),
|
249
|
+
Hand.new(four_of_a_kind),
|
250
|
+
Hand.new(full_house),
|
251
|
+
Hand.new(flush),
|
252
|
+
Hand.new(straight),
|
253
|
+
Hand.new(three_of_a_kind),
|
254
|
+
Hand.new(two_pairs),
|
255
|
+
Hand.new(pair)]
|
256
|
+
end
|
257
|
+
|
258
|
+
def hand_four_of_a_kind
|
259
|
+
[Hand.new(four_of_a_kind),
|
260
|
+
Hand.new(full_house),
|
261
|
+
Hand.new(flush),
|
262
|
+
Hand.new(straight),
|
263
|
+
Hand.new(three_of_a_kind),
|
264
|
+
Hand.new(two_pairs),
|
265
|
+
Hand.new(pair)]
|
266
|
+
end
|
267
|
+
|
268
|
+
def hand_full_house
|
269
|
+
[Hand.new(full_house),
|
270
|
+
Hand.new(flush),
|
271
|
+
Hand.new(straight),
|
272
|
+
Hand.new(three_of_a_kind),
|
273
|
+
Hand.new(two_pairs),
|
274
|
+
Hand.new(pair)]
|
275
|
+
end
|
276
|
+
|
277
|
+
def hand_flush
|
278
|
+
[Hand.new(flush),
|
279
|
+
Hand.new(straight),
|
280
|
+
Hand.new(three_of_a_kind),
|
281
|
+
Hand.new(two_pairs),
|
282
|
+
Hand.new(pair)]
|
283
|
+
end
|
284
|
+
|
285
|
+
def hand_flush
|
286
|
+
[Hand.new(flush),
|
287
|
+
Hand.new(straight),
|
288
|
+
Hand.new(three_of_a_kind),
|
289
|
+
Hand.new(two_pairs),
|
290
|
+
Hand.new(pair)]
|
291
|
+
end
|
292
|
+
|
293
|
+
def hand_straight
|
294
|
+
[Hand.new(straight),
|
295
|
+
Hand.new(three_of_a_kind),
|
296
|
+
Hand.new(two_pairs),
|
297
|
+
Hand.new(pair)]
|
298
|
+
end
|
299
|
+
|
300
|
+
def hand_three_of_a_kind
|
301
|
+
[Hand.new(three_of_a_kind),
|
302
|
+
Hand.new(two_pairs),
|
303
|
+
Hand.new(pair)]
|
304
|
+
end
|
305
|
+
|
306
|
+
def hand_two_pairs
|
307
|
+
[Hand.new(two_pairs),
|
308
|
+
Hand.new(pair)]
|
309
|
+
end
|
310
|
+
|
311
|
+
def hand_pair
|
312
|
+
[Hand.new(pair),
|
313
|
+
Hand.new(high_card)]
|
314
|
+
end
|
315
|
+
|
316
|
+
def hand_high_card
|
317
|
+
[Hand.new(high_card)]
|
318
|
+
end
|
319
|
+
|
320
|
+
|
321
|
+
end
|
data/spec/table_spec.rb
ADDED
@@ -0,0 +1,202 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Table do
|
4
|
+
describe "#winner" do
|
5
|
+
let(:table) { Table.new}
|
6
|
+
context "the table contains a straight flush as best hand" do
|
7
|
+
context "there is only one straight flush hand" do
|
8
|
+
before do
|
9
|
+
table.hands = hand_straight_flush
|
10
|
+
end
|
11
|
+
it "return an array where the last element is a straight flush " do
|
12
|
+
expect(table.winner.rank.class).to eq StraightFlush
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context "there are two straight flush hands" do
|
17
|
+
before do
|
18
|
+
table.hands = hand_two_straight_flush
|
19
|
+
end
|
20
|
+
it "return an array where the last element is the highest straight flush " do
|
21
|
+
only_val = Hand.new(table.winner.hand).only_values
|
22
|
+
expect(only_val.max).to eq "8"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
context "the table contains a four of a kind as best hand" do
|
29
|
+
context "there is one four of a kind hand" do
|
30
|
+
before do
|
31
|
+
table.hands = hand_four_of_a_kind
|
32
|
+
end
|
33
|
+
it "return an array where the last element is a four of a kind " do
|
34
|
+
expect(table.winner.rank.class).to eq FourOfAKind
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context "there are two four of a kind hands" do
|
39
|
+
before do
|
40
|
+
table.hands = hand_same_four_of_a_kind
|
41
|
+
end
|
42
|
+
it "return an array where the last element is a four of a kind " do
|
43
|
+
only_val = Hand.new(table.winner.hand).only_values
|
44
|
+
expect(only_val.max).to eq "5"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context "the table contains a full house as best hand" do
|
50
|
+
context "there is only one full house" do
|
51
|
+
before do
|
52
|
+
table.hands = hand_full_house
|
53
|
+
end
|
54
|
+
it "return an array where the last element is a full house hand " do
|
55
|
+
expect(table.winner.rank.class).to eq FullHouse
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "there are two full house hands" do
|
60
|
+
before do
|
61
|
+
table.hands = hand_same_full_house
|
62
|
+
end
|
63
|
+
it "return an array where the last element is highest full house " do
|
64
|
+
only_val = Hand.new(table.winner.hand).only_values
|
65
|
+
p only_val
|
66
|
+
expect(only_val.max).to eq "5"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
context "the table contains a flush as best hand" do
|
73
|
+
context "there is only one flush hand" do
|
74
|
+
before do
|
75
|
+
table.hands = hand_flush
|
76
|
+
end
|
77
|
+
it "return an array where the last element is a flush " do
|
78
|
+
expect(table.winner.rank.class).to eq Flush
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context "there is two one flush hand" do
|
83
|
+
before do
|
84
|
+
table.hands = hand_two_flush
|
85
|
+
end
|
86
|
+
it "return an array where the last element is the highest flush " do
|
87
|
+
only_val = Hand.new(table.winner.hand).only_values
|
88
|
+
expect(only_val.max).to eq "8"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
context "the table contains a straight as best hand" do
|
95
|
+
context "there is only one straight hand" do
|
96
|
+
before do
|
97
|
+
table.hands = hand_straight
|
98
|
+
end
|
99
|
+
it "return an array where the last element is a straight " do
|
100
|
+
expect(table.winner.rank.class).to eq Straight
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context "there are two straight hands" do
|
105
|
+
before do
|
106
|
+
table.hands = hand_same_straight
|
107
|
+
end
|
108
|
+
it "return an array where the last element the highest straight" do
|
109
|
+
only_val = Hand.new(table.winner.hand).only_values
|
110
|
+
expect(only_val.last).to eq "8"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
context "the table contains a three of a kind as best hand" do
|
117
|
+
context "there is only one three of a kind hand" do
|
118
|
+
before do
|
119
|
+
table.hands = hand_three_of_a_kind
|
120
|
+
end
|
121
|
+
it "return an array where the last element is a three of a kind " do
|
122
|
+
expect(table.winner.rank.class).to eq ThreeOfAKind
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
context "there are two three of a kind hands" do
|
127
|
+
before do
|
128
|
+
table.hands = hand_some_three_of_a_kind
|
129
|
+
end
|
130
|
+
it "return an array where the last element is a three of a kind " do
|
131
|
+
only_val = Hand.new(table.winner.hand).only_values
|
132
|
+
expect(only_val.last).to eq "8"
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
context "the table contains a two pairs as best hand" do
|
138
|
+
before do
|
139
|
+
table.hands = hand_two_pairs
|
140
|
+
end
|
141
|
+
it "return an array where the last element is a two pairs " do
|
142
|
+
expect(table.winner.rank.class).to eq TwoPairs
|
143
|
+
end
|
144
|
+
|
145
|
+
context "the tables contains thw hands with same two pairs" do
|
146
|
+
before do
|
147
|
+
table.hands = hand_same_two_pairs
|
148
|
+
end
|
149
|
+
it "return an array where the last element is the two pairs with the highest remaining card" do
|
150
|
+
only_val = Hand.new(table.winner.hand).only_values
|
151
|
+
expect(only_val.last).to eq "8"
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
context "the table contains a pair as best hand" do
|
157
|
+
context "the tables contains a unique pair hand" do
|
158
|
+
before do
|
159
|
+
table.hands = hand_pair
|
160
|
+
end
|
161
|
+
it "return an array where the last element is a pair " do
|
162
|
+
expect(table.winner.rank.class).to eq Pair
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
context "the tables contains the hands with same pairs" do
|
167
|
+
before do
|
168
|
+
table.hands = hand_same_pair
|
169
|
+
end
|
170
|
+
it "return an array where the last element is the pair with the highest remaining card" do
|
171
|
+
only_val = Hand.new(table.winner.hand).only_values
|
172
|
+
expect(only_val.last).to eq "8"
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
end
|
177
|
+
|
178
|
+
context "the table contains a high card as best hand" do
|
179
|
+
context "the highest cards have the same value" do
|
180
|
+
before do
|
181
|
+
table.hands = hand_high_card_same_highest
|
182
|
+
end
|
183
|
+
it "return an array where the last element is a high card with the next highest value" do
|
184
|
+
only_val = Hand.new(table.winner.hand).only_values
|
185
|
+
only_val.sort!
|
186
|
+
expect(only_val[only_val.length - 2]).to eq "7"
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
context "the highest card is unique" do
|
191
|
+
before do
|
192
|
+
table.hands = hand_high_card
|
193
|
+
end
|
194
|
+
it "return an array where the last element is a high card " do
|
195
|
+
expect(table.winner.rank.class).to eq HighCard
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
end
|
200
|
+
|
201
|
+
end
|
202
|
+
end
|
metadata
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: poker_hands
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Cosimo Ranieri
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-08-16 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Sample app to play poker
|
15
|
+
email: co.ranieri@gmail.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- README.md
|
21
|
+
- Rakefile
|
22
|
+
- poker-hands.gemspec
|
23
|
+
- lib/deck/card.rb
|
24
|
+
- lib/deck/cards.rb
|
25
|
+
- lib/deck/deck.rb
|
26
|
+
- lib/deck/hand.rb
|
27
|
+
- lib/deck/rank_selector.rb
|
28
|
+
- lib/poker_hands.rb
|
29
|
+
- lib/rank/flush.rb
|
30
|
+
- lib/rank/four_of_a_kind.rb
|
31
|
+
- lib/rank/full_house.rb
|
32
|
+
- lib/rank/high_card.rb
|
33
|
+
- lib/rank/pair.rb
|
34
|
+
- lib/rank/rank.rb
|
35
|
+
- lib/rank/straight.rb
|
36
|
+
- lib/rank/straight_flush.rb
|
37
|
+
- lib/rank/three_of_a_kind.rb
|
38
|
+
- lib/rank/two_pairs.rb
|
39
|
+
- spec/hand_spec.rb
|
40
|
+
- spec/spec_helper.rb
|
41
|
+
- spec/support/test_helpers.rb
|
42
|
+
- spec/table_spec.rb
|
43
|
+
homepage: https://rubygems.org/gems/poker-hands
|
44
|
+
licenses:
|
45
|
+
- MIT
|
46
|
+
post_install_message:
|
47
|
+
rdoc_options: []
|
48
|
+
require_paths:
|
49
|
+
- lib
|
50
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ! '>='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
requirements: []
|
63
|
+
rubyforge_project:
|
64
|
+
rubygems_version: 1.8.23
|
65
|
+
signing_key:
|
66
|
+
specification_version: 3
|
67
|
+
summary: Sample app to play poker
|
68
|
+
test_files: []
|