poker_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/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: []
|