podos 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/Gemfile +3 -0
- data/README.md +32 -0
- data/Rakefile +2 -0
- data/lib/podos.rb +8 -0
- data/lib/podos/card.rb +48 -0
- data/lib/podos/deck.rb +41 -0
- data/lib/podos/full_deck.rb +17 -0
- data/lib/podos/poker_hand.rb +69 -0
- data/lib/podos/version.rb +3 -0
- data/main.rb +53 -0
- data/podos.gemspec +23 -0
- data/test.rb +6 -0
- metadata +84 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8c68be9ac85d277dcb18eef3d6c0e24a7c102b31
|
4
|
+
data.tar.gz: cf64613db498c69a54aa305f95a3d8320df98be6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7bf6a9b22f3dc7ef742f8486b8f6e5f52101a88ba2a6ad0d95e63d267930555b5c3d59365c8153c2c0c7ed01db5ba308aa50485cb0194ddbcfea5bcbc4ca3135
|
7
|
+
data.tar.gz: eed5681a57d595ae1318362375a8ba1a4942cc2cda3c805594a86b97de0b7e3307f5a54f62ac82b51e4b04269c79cf86f1110a330378a6265bbb738f2b7b9d1d
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
coverage
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# Podos
|
2
|
+
|
3
|
+
Elegant poker hand ranker written in Ruby.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'podos'
|
11
|
+
```
|
12
|
+
|
13
|
+
## Usage
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
require 'podos'
|
17
|
+
|
18
|
+
full_deck = Podos::FullDeck.new
|
19
|
+
cards = full_deck.deal(5)
|
20
|
+
hand = Podos::PokerHand.new cards
|
21
|
+
hand.rank
|
22
|
+
```
|
23
|
+
|
24
|
+
## Development
|
25
|
+
|
26
|
+
After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
27
|
+
|
28
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
29
|
+
|
30
|
+
## Contributing
|
31
|
+
|
32
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/oguzbilgic/podos.
|
data/Rakefile
ADDED
data/lib/podos.rb
ADDED
data/lib/podos/card.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
module Podos
|
2
|
+
class Card
|
3
|
+
attr_accessor :rank, :suit
|
4
|
+
|
5
|
+
RANKS = (2..14)
|
6
|
+
SUITS = [:club, :diamond, :heart, :spade]
|
7
|
+
SUIT_SYMBOLS = { club: '♣', heart: '♥', spade: '♠', diamond: '♦' }
|
8
|
+
|
9
|
+
def initialize rank, suit
|
10
|
+
raise 'rank is not valid' unless RANKS.include? rank
|
11
|
+
raise 'suit is not valid' unless SUITS.include? suit
|
12
|
+
|
13
|
+
@rank = rank
|
14
|
+
@suit = suit
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.from_str str
|
18
|
+
rank = str.to_i
|
19
|
+
rank = 14 if str.include? 'A'
|
20
|
+
rank = 13 if str.include? 'K'
|
21
|
+
rank = 12 if str.include? 'Q'
|
22
|
+
rank = 11 if str.include? 'J'
|
23
|
+
|
24
|
+
suit = :club if str.include? '♣'
|
25
|
+
suit = :heart if str.include? '♥'
|
26
|
+
suit = :spade if str.include? '♠'
|
27
|
+
suit = :diamond if str.include? '♦'
|
28
|
+
|
29
|
+
Card.new rank, suit
|
30
|
+
end
|
31
|
+
|
32
|
+
def rank_to_s
|
33
|
+
return "J" if @rank == 11
|
34
|
+
return "Q" if @rank == 12
|
35
|
+
return "K" if @rank == 13
|
36
|
+
return "A" if @rank == 14
|
37
|
+
@rank
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_s
|
41
|
+
"#{@rank_to_s}#{@SUIT_SYMBOLS[@suit]}"
|
42
|
+
end
|
43
|
+
|
44
|
+
# def == other_card
|
45
|
+
# other_card.rank == @rank && other_card.suit == @suit
|
46
|
+
# end
|
47
|
+
end
|
48
|
+
end
|
data/lib/podos/deck.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
module Podos
|
4
|
+
class Deck
|
5
|
+
extend Forwardable
|
6
|
+
|
7
|
+
def_delegators :@cards, :count, :<<, :map, :shuffle!
|
8
|
+
|
9
|
+
attr_accessor :cards
|
10
|
+
|
11
|
+
def initialize cards = []
|
12
|
+
# Todo raise if duplicate
|
13
|
+
|
14
|
+
@cards = cards
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.from_str str
|
18
|
+
self.new str.split(' ').map { |str| Card.from_str str }
|
19
|
+
end
|
20
|
+
|
21
|
+
def deal number
|
22
|
+
@cards.shift number
|
23
|
+
end
|
24
|
+
|
25
|
+
# def remove_card(card)
|
26
|
+
# cards = @cards.select { |c| c != card }
|
27
|
+
# end
|
28
|
+
|
29
|
+
def to_s
|
30
|
+
@cards.map(&:to_s).join ' '
|
31
|
+
end
|
32
|
+
|
33
|
+
def + other_deck
|
34
|
+
self.new @cards + other_deck.cards
|
35
|
+
end
|
36
|
+
|
37
|
+
def - other_deck
|
38
|
+
self.new @cards.select { |c| !other_deck.cards.include? c }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Podos
|
2
|
+
ALL_CARDS = []
|
3
|
+
|
4
|
+
Card::SUITS.each do |suit|
|
5
|
+
Card::RANKS.each do |rank|
|
6
|
+
ALL_CARDS << Card.new(rank, suit)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class FullDeck < Deck
|
11
|
+
def initialize
|
12
|
+
super ALL_CARDS.clone
|
13
|
+
|
14
|
+
self.shuffle!
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module Podos
|
2
|
+
class PokerHand < Deck
|
3
|
+
def initialize cards
|
4
|
+
raise 'doesnt have 5 cards' if cards.count != 5
|
5
|
+
|
6
|
+
super cards
|
7
|
+
end
|
8
|
+
|
9
|
+
def rank
|
10
|
+
return :royal_flush if royal_flush?
|
11
|
+
return :straight_flush if straight_flush?
|
12
|
+
return :four_of_a_kind if four_of_a_kind?
|
13
|
+
return :full_house if full_house?
|
14
|
+
return :flush if flush?
|
15
|
+
return :straight if straight?
|
16
|
+
return :two_pair if two_pair?
|
17
|
+
return :pair if pair?
|
18
|
+
:high_card
|
19
|
+
end
|
20
|
+
|
21
|
+
def royal_flush?
|
22
|
+
return unless straight_flush?
|
23
|
+
|
24
|
+
@cards.map(&:rank).max == 14
|
25
|
+
end
|
26
|
+
|
27
|
+
def straight_flush?
|
28
|
+
straight? && flush?
|
29
|
+
end
|
30
|
+
|
31
|
+
def four_of_a_kind?
|
32
|
+
card_counts_by_rank.include? 4
|
33
|
+
end
|
34
|
+
|
35
|
+
def full_house?
|
36
|
+
pair? && three_of_a_kind?
|
37
|
+
end
|
38
|
+
|
39
|
+
def flush?
|
40
|
+
@cards.group_by(&:suit).count == 1
|
41
|
+
end
|
42
|
+
|
43
|
+
def straight?
|
44
|
+
return if card_counts_by_rank != [1,1,1,1,1]
|
45
|
+
|
46
|
+
card_ranks = @cards.map(&:rank)
|
47
|
+
|
48
|
+
(card_ranks.max - card_ranks.min) == 4
|
49
|
+
end
|
50
|
+
|
51
|
+
def three_of_a_kind?
|
52
|
+
card_counts_by_rank.include? 3
|
53
|
+
end
|
54
|
+
|
55
|
+
def two_pair?
|
56
|
+
card_counts_by_rank == [2,2,1].sort!
|
57
|
+
end
|
58
|
+
|
59
|
+
def pair?
|
60
|
+
card_counts_by_rank.include? 2
|
61
|
+
end
|
62
|
+
|
63
|
+
protected
|
64
|
+
|
65
|
+
def card_counts_by_rank
|
66
|
+
@card_counts_by_rank ||= @cards.group_by(&:rank).values.map(&:count).sort!
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/main.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'benchmark'
|
2
|
+
require './lib/card.rb'
|
3
|
+
require './lib/deck.rb'
|
4
|
+
require './lib/full_deck.rb'
|
5
|
+
require './lib/poker_hand.rb'
|
6
|
+
|
7
|
+
# def pair_odd player_cards, community_cards
|
8
|
+
# visible_cards = player_cards + community_cards
|
9
|
+
# remaining_cards = FullDeck.new - visible_cards
|
10
|
+
#
|
11
|
+
# puts visible_cards.count
|
12
|
+
# puts remaining_cards.count
|
13
|
+
#
|
14
|
+
# uniq_count = visible_cards.map(&:rank).uniq.count
|
15
|
+
# if uniq_count < visible_cards.count
|
16
|
+
# 1
|
17
|
+
# else
|
18
|
+
# uniq_count * 4 % remaining_cards.count
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# player_cards = Deck.new
|
23
|
+
# player_cards << Card.new(14, :club)
|
24
|
+
# player_cards << Card.new(13, :diamond)
|
25
|
+
#
|
26
|
+
# community_cards = Deck.new
|
27
|
+
# # community_cards << Card.new(10, :diamond)
|
28
|
+
#
|
29
|
+
# x = pair_odd player_cards, community_cards
|
30
|
+
# puts x
|
31
|
+
|
32
|
+
# ranks = 100000.times.map do
|
33
|
+
# cards = FullDeck.new.deal(5)
|
34
|
+
# hand = PokerHand.new cards
|
35
|
+
# hand.rank
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# puts ranks.group_by(&:itself).map { |k,v| [k, v.size]}
|
39
|
+
|
40
|
+
def deal_and_rank
|
41
|
+
full_deck = FullDeck.new
|
42
|
+
cards = full_deck.deal(5)
|
43
|
+
hand = PokerHand.new cards
|
44
|
+
hand.rank
|
45
|
+
end
|
46
|
+
|
47
|
+
# 100000.times do
|
48
|
+
# puts :straight_flush if deal_and_rank == :straight_flush
|
49
|
+
# end
|
50
|
+
|
51
|
+
puts Benchmark.measure {
|
52
|
+
100000.times { deal_and_rank }
|
53
|
+
}
|
data/podos.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
lib = File.expand_path("../lib", __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require "podos/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "podos"
|
7
|
+
spec.version = Podos::VERSION
|
8
|
+
spec.authors = ["Oguz Bilgic"]
|
9
|
+
spec.email = ["fisyonet@gmail.com"]
|
10
|
+
|
11
|
+
spec.summary = %q{Elegant poker hand ranker}
|
12
|
+
spec.homepage = "http://www.github.com/oguzbilgic/podos"
|
13
|
+
|
14
|
+
# Specify which files should be added to the gem when it is released.
|
15
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
16
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
17
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
end
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.17"
|
22
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
23
|
+
end
|
data/test.rb
ADDED
metadata
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: podos
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Oguz Bilgic
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-12-23 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.17'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.17'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
description:
|
42
|
+
email:
|
43
|
+
- fisyonet@gmail.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- ".gitignore"
|
49
|
+
- Gemfile
|
50
|
+
- README.md
|
51
|
+
- Rakefile
|
52
|
+
- lib/podos.rb
|
53
|
+
- lib/podos/card.rb
|
54
|
+
- lib/podos/deck.rb
|
55
|
+
- lib/podos/full_deck.rb
|
56
|
+
- lib/podos/poker_hand.rb
|
57
|
+
- lib/podos/version.rb
|
58
|
+
- main.rb
|
59
|
+
- podos.gemspec
|
60
|
+
- test.rb
|
61
|
+
homepage: http://www.github.com/oguzbilgic/podos
|
62
|
+
licenses: []
|
63
|
+
metadata: {}
|
64
|
+
post_install_message:
|
65
|
+
rdoc_options: []
|
66
|
+
require_paths:
|
67
|
+
- lib
|
68
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '0'
|
73
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
requirements: []
|
79
|
+
rubyforge_project:
|
80
|
+
rubygems_version: 2.6.11
|
81
|
+
signing_key:
|
82
|
+
specification_version: 4
|
83
|
+
summary: Elegant poker hand ranker
|
84
|
+
test_files: []
|