This repository has been archived by the owner on Oct 18, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
Allie's poker implementation #1
Open
acreilly
wants to merge
49
commits into
gmacdougall:master
Choose a base branch
from
acreilly:master
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
49 commits
Select commit
Hold shift + click to select a range
525fe65
Change namespace from to-poker to poker
acreilly 2c9535f
Set up base Poker::Card model with specs
acreilly a99294e
Added constants SUITS and RANKS with specs
acreilly 0cc265f
Add deck file and require it
acreilly d873367
Make create! happen immediately on initialize. Added specs
acreilly 10ff6cb
Add shuffle method with specs
acreilly a8ece76
Create number_value method
acreilly d0299d7
Set up hand model and #sets method to organize hand cards
acreilly 5d437c0
Set up four_of_a_kind, three_of_a_kind and one pair with specs
acreilly 391b4d1
Add two_pair? method with specs
acreilly f292d20
Add #straight? method with specs
acreilly 9746382
Refactor one pair spec
e9641fd
Merge pull request #1 from gmacdougall/refactored-one-pair-spec
acreilly 616dfbb
Move sets to private and remove its specs
acreilly d761a5e
Refactor four_of_a_kind? specs
acreilly f805452
Refactor straight? specs
acreilly 6f028bb
Refactored three_of_a_kind? spec
acreilly 537ce51
Refactored two_pair? spec
acreilly 7632db0
Remove unused cyo_card method from specs
acreilly d720b2d
Add #flush? with specs
acreilly 273f059
Set up specs for full_house?
acreilly 2ac80f3
Full house implementation with testing
e142fbd
Merge pull request #2 from gmacdougall/full-house-implementation
acreilly e464e38
Implemented #straight_flush? with specs
acreilly 989ca15
Fix #straight? method by checking for set key length to eq 5
acreilly cea868f
Refactor straight? to consider low ace options
acreilly 9c847dd
Add #level to determine hand type
acreilly d455e03
Change contents to cards to make more sense and remove shuffle method…
acreilly 504ca8e
Raise error if not enough cards are delt
acreilly f1c002c
Set up dealer, selects an array of winners in the case that there is …
acreilly a01fb9b
Cleaning up unused code/comments
acreilly 2410bc1
Move frozen_string_literal to top line
acreilly 525de7b
Refactor deal_round
acreilly 4924ea5
Move creation of cards to initialize and remove create spec
acreilly 9aa83c2
Include enumerable to add more methods to deck
acreilly 75f6974
Remove error from poker hand and add custom error to poker dealer
acreilly 944131c
Refactored sets and fixed all methods affected by refactor
acreilly e45d987
Change spec to match_array instead of include with wild card so it is…
acreilly fdb106b
Refactor #winner method significantly
acreilly 1775059
Add comparable method to compare a hands rank to another, also added …
acreilly b963ee5
Install factory_girl
acreilly 2e189e5
Set up hand factory
acreilly 2c8ad02
Add specs to level
acreilly a841989
Refactor <=> method and add sorted_sets method, add passing specs
acreilly 06c3a8f
Fix sorted_sets since it was not always sorting correctly
acreilly db1504a
Fix #winner method to utilize .max enumerable to select the winner
acreilly e06d697
Fix errors in factories
acreilly 394fd9d
Refactor specs to be cleaner
acreilly 182bd83
Add adjust_ace to sorted sets in case of low ace straight
acreilly File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# frozen_string_literal: true | ||
require 'pry' | ||
require 'poker/card' | ||
require 'poker/deck' | ||
require 'poker/hand' | ||
require 'poker/dealer' | ||
# Poker Top Level Library | ||
module Poker | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
module Poker | ||
class Card | ||
attr_reader :rank, :suit | ||
|
||
RANKS = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A'] | ||
SUITS = ['Hearts', 'Spades', 'Diamonds', 'Clubs'] | ||
|
||
def initialize(rank, suit) | ||
@rank = rank | ||
@suit = suit | ||
end | ||
|
||
def number_value | ||
RANKS.index(rank) + 1 | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
module Poker | ||
class Dealer | ||
class EmptyDeckError < StandardError; end | ||
|
||
attr_reader :deck, :hands | ||
|
||
def initialize(num_players) | ||
@num_players = num_players | ||
@deck = Poker::Deck.new | ||
@hands = [] | ||
end | ||
|
||
def deal_round | ||
@hands = Array.new(@num_players) { deal } | ||
end | ||
|
||
def winner | ||
@hands.select { |hand| hand == @hands.max } | ||
end | ||
|
||
|
||
private | ||
|
||
def deal | ||
Poker::Hand.new(@deck.cards.pop(5)) | ||
|
||
raise EmptyDeckError if @deck.cards.empty? | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
module Poker | ||
class Deck | ||
include Enumerable | ||
|
||
attr_reader :cards | ||
|
||
def initialize | ||
@cards = Poker::Card::RANKS.flat_map do |rank| | ||
Poker::Card::SUITS.flat_map do |suit| | ||
Poker::Card.new(rank, suit) | ||
end | ||
end.shuffle! | ||
end | ||
|
||
def each(&block) | ||
@cards.each(&block) | ||
end | ||
|
||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
module Poker | ||
class Hand | ||
include Comparable | ||
|
||
def initialize(cards) | ||
@cards = cards | ||
@sets = sets | ||
end | ||
|
||
def straight_flush? | ||
straight? && flush? | ||
end | ||
|
||
def four_of_a_kind? | ||
of_a_kind?(4) | ||
end | ||
|
||
def full_house? | ||
three_of_a_kind? && one_pair? | ||
end | ||
|
||
def flush? | ||
@cards.map { |c| c.suit }.uniq.length == 1 | ||
end | ||
|
||
def straight? | ||
standard_straight? || ace_low_straight? | ||
end | ||
|
||
def three_of_a_kind? | ||
of_a_kind?(3) | ||
end | ||
|
||
def two_pair? | ||
one_pair? && @sets.select { |k,v| v == 2 }.length == 2 | ||
end | ||
|
||
def one_pair? | ||
of_a_kind?(2) | ||
end | ||
|
||
def of_a_kind?(number) | ||
@sets.values.any? {|s| s == number } | ||
end | ||
|
||
def level | ||
if straight_flush? | ||
8 | ||
elsif four_of_a_kind? | ||
7 | ||
elsif full_house? | ||
6 | ||
elsif flush? | ||
5 | ||
elsif straight? | ||
4 | ||
elsif three_of_a_kind? | ||
3 | ||
elsif two_pair? | ||
2 | ||
elsif one_pair? | ||
1 | ||
else | ||
0 | ||
end | ||
end | ||
|
||
def <=>(other_hand) | ||
lvl_compare = level <=> other_hand.level | ||
|
||
return lvl_compare unless lvl_compare == 0 | ||
|
||
sorted_sets <=> other_hand.sorted_sets | ||
end | ||
|
||
def sorted_sets | ||
# &:reverse makes sure that the hash sorts by value first then key | ||
@sorted_sets = @sets.sort_by(&:reverse).reverse.to_h.keys | ||
|
||
adjust_ace if ace_low_straight? | ||
|
||
@sorted_sets | ||
end | ||
|
||
private | ||
|
||
def standard_straight? | ||
@sets.keys.length == 5 && @sets.keys == (@sets.keys.first..@sets.keys.last).to_a | ||
end | ||
|
||
def ace_low_straight? | ||
sets.keys == [1, 2, 3, 4, 13] | ||
end | ||
|
||
def adjust_ace | ||
@sorted_sets.shift | ||
@sorted_sets.push(0) | ||
end | ||
|
||
def sets | ||
sets = @cards.inject(Hash.new(0)) do |hash, card| | ||
hash[card.number_value] += 1 | ||
hash | ||
end | ||
|
||
Hash[sets.sort] | ||
end | ||
end | ||
end |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
FactoryGirl.define do | ||
factory :hand, class: Poker::Hand do | ||
initialize_with do | ||
ranks = Poker::Card::RANKS.shuffle | ||
suits = Poker::Card::SUITS | ||
new((0..4).map {|c| Poker::Card.new(ranks.pop, suits.sample) }) | ||
end | ||
end | ||
|
||
factory :straight_flush, class: Poker::Hand do | ||
initialize_with do | ||
new( | ||
[ | ||
Poker::Card.new('2', 'Diamonds'), | ||
Poker::Card.new('3', 'Diamonds'), | ||
Poker::Card.new('4', 'Diamonds'), | ||
Poker::Card.new('5', 'Diamonds'), | ||
Poker::Card.new('6', 'Diamonds'), | ||
] | ||
) | ||
end | ||
end | ||
|
||
factory :four_of_a_kind, class: Poker::Hand do | ||
initialize_with do | ||
new( | ||
[ | ||
Poker::Card.new('2', 'Diamonds'), | ||
Poker::Card.new('2', 'Spades'), | ||
Poker::Card.new('2', 'Hearts'), | ||
Poker::Card.new('5', 'Clubs'), | ||
Poker::Card.new('2', 'Clubs'), | ||
] | ||
) | ||
end | ||
end | ||
|
||
factory :full_house, class: Poker::Hand do | ||
initialize_with do | ||
new( | ||
[ | ||
Poker::Card.new('7', 'Diamonds'), | ||
Poker::Card.new('7', 'Hearts'), | ||
Poker::Card.new('7', 'Spades'), | ||
Poker::Card.new('8', 'Diamonds'), | ||
Poker::Card.new('8', 'Spades'), | ||
] | ||
) | ||
end | ||
end | ||
|
||
factory :flush, class: Poker::Hand do | ||
initialize_with do | ||
new( | ||
[ | ||
Poker::Card.new('2', 'Hearts'), | ||
Poker::Card.new('3', 'Hearts'), | ||
Poker::Card.new('8', 'Hearts'), | ||
Poker::Card.new('5', 'Hearts'), | ||
Poker::Card.new('6', 'Hearts'), | ||
] | ||
) | ||
end | ||
end | ||
|
||
factory :straight, class: Poker::Hand do | ||
initialize_with do | ||
new( | ||
[ | ||
Poker::Card.new('2', 'Spades'), | ||
Poker::Card.new('3', 'Spades'), | ||
Poker::Card.new('4', 'Spades'), | ||
Poker::Card.new('5', 'Spades'), | ||
Poker::Card.new('6', 'Clubs'), | ||
] | ||
) | ||
end | ||
end | ||
|
||
factory :straight_with_ace, class: Poker::Hand do | ||
initialize_with do | ||
new( | ||
[ | ||
Poker::Card.new('A', 'Clubs'), | ||
Poker::Card.new('2', 'Diamonds'), | ||
Poker::Card.new('3', 'Diamonds'), | ||
Poker::Card.new('4', 'Diamonds'), | ||
Poker::Card.new('5', 'Diamonds'), | ||
] | ||
) | ||
end | ||
end | ||
|
||
factory :three_of_a_kind, class: Poker::Hand do | ||
transient do | ||
match_rank nil | ||
high_card nil | ||
end | ||
|
||
initialize_with do | ||
new( | ||
[ | ||
Poker::Card.new(match_rank || '4', 'Diamonds'), | ||
Poker::Card.new(match_rank || '4', 'Spades'), | ||
Poker::Card.new(match_rank || '4', 'Hearts'), | ||
Poker::Card.new(high_card || '5', 'Clubs'), | ||
Poker::Card.new('2', 'Clubs'), | ||
] | ||
) | ||
end | ||
end | ||
|
||
factory :two_pair, class: Poker::Hand do | ||
transient do | ||
one_pair_rank nil | ||
high_card nil | ||
end | ||
|
||
initialize_with do | ||
new( | ||
[ | ||
Poker::Card.new(one_pair_rank || '7', 'Diamonds'), | ||
Poker::Card.new('J', 'Spades'), | ||
Poker::Card.new('J', 'Hearts'), | ||
Poker::Card.new(high_card || '5', 'Clubs'), | ||
Poker::Card.new(one_pair_rank || '7', 'Clubs'), | ||
] | ||
) | ||
end | ||
end | ||
|
||
factory :one_pair, class: Poker::Hand do | ||
initialize_with do | ||
new( | ||
[ | ||
Poker::Card.new('K', 'Diamonds'), | ||
Poker::Card.new('Q', 'Spades'), | ||
Poker::Card.new('J', 'Hearts'), | ||
Poker::Card.new('4', 'Clubs'), | ||
Poker::Card.new('Q', 'Clubs'), | ||
] | ||
) | ||
end | ||
end | ||
end |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The method in which this is memoized is a bit weird. We should contain this logic in the method below.