fiftytwo 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 6c00da0e98ce49dd9546e2936caf0f8b19dea1353ff953e35edf0fa4e8856e97
4
+ data.tar.gz: bd0ec3c7c3b7bb0305c3b9b8ed534865eee21dd47a9b0e61e69655d9a7d3c8ff
5
+ SHA512:
6
+ metadata.gz: c2dbb21639b82fe689c8de2ef7033783e9a5ade2fd35372f7e763b09464cec1bc46bac943cd9274499621143922fe7eb7c0d34426b9430f698ea8dcc120b3216
7
+ data.tar.gz: cebde92a30ff69c21a3244e29588eef325431c0d684cddbb2b7a66c4bf34846a397b8529edc87397862512fbde75bd9a0960ff61c0f83d86e569211aecef6d83
@@ -0,0 +1,31 @@
1
+ name: Ruby Gem
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ build:
9
+ name: Build + Publish
10
+ runs-on: ubuntu-latest
11
+ permissions:
12
+ contents: read
13
+ packages: write
14
+
15
+ steps:
16
+ - uses: actions/checkout@v2
17
+ - name: Set up Ruby 2.6
18
+ uses: actions/setup-ruby@v1
19
+ with:
20
+ ruby-version: 2.6.x
21
+
22
+ - name: Publish to RubyGems
23
+ run: |
24
+ mkdir -p $HOME/.gem
25
+ touch $HOME/.gem/credentials
26
+ chmod 0600 $HOME/.gem/credentials
27
+ printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
28
+ gem build *.gemspec
29
+ gem push *.gem
30
+ env:
31
+ GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
@@ -0,0 +1,35 @@
1
+ # This workflow uses actions that are not certified by GitHub.
2
+ # They are provided by a third-party and are governed by
3
+ # separate terms of service, privacy policy, and support
4
+ # documentation.
5
+ # This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
6
+ # For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
7
+
8
+ name: Ruby
9
+
10
+ on:
11
+ push:
12
+ branches: [ master ]
13
+ pull_request:
14
+ branches: [ master ]
15
+
16
+ jobs:
17
+ test:
18
+
19
+ runs-on: ubuntu-latest
20
+ strategy:
21
+ matrix:
22
+ ruby-version: ['2.6', '2.7', '3.0']
23
+
24
+ steps:
25
+ - uses: actions/checkout@v2
26
+ - name: Set up Ruby
27
+ # To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
28
+ # change this to (see https://github.com/ruby/setup-ruby#versioning):
29
+ # uses: ruby/setup-ruby@v1
30
+ uses: ruby/setup-ruby@473e4d8fe5dd94ee328fdfca9f8c9c7afc9dae5e
31
+ with:
32
+ ruby-version: ${{ matrix.ruby-version }}
33
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
34
+ - name: Run tests
35
+ run: bundle exec rspec
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ **.DS_Store
2
+ *.gem
3
+ Gemfile.lock
4
+ .bundle
5
+ .yardoc
6
+ doc
7
+ coverage
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ --protected lib/**/*.rb
@@ -0,0 +1,76 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, sex characteristics, gender identity and expression,
9
+ level of experience, education, socio-economic status, nationality, personal
10
+ appearance, race, religion, or sexual identity and orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at kevinstuffandthings@gmail.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72
+
73
+ [homepage]: https://www.contributor-covenant.org
74
+
75
+ For answers to common questions about this code of conduct, see
76
+ https://www.contributor-covenant.org/faq
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2021 Kevin McDonald
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/README.md ADDED
@@ -0,0 +1,151 @@
1
+ # FiftyTwo ![Build Status](https://github.com/kevinstuffandthings/fiftytwo/actions/workflows/ruby.yml/badge.svg) [![Gem Version](https://badge.fury.io/rb/fiftytwo.svg)](https://badge.fury.io/rb/fiftytwo)
2
+
3
+ A [standard 52-card deck](https://en.wikipedia.org/wiki/Standard_52-card_deck), written in Ruby.
4
+
5
+ ## Installation
6
+ Add this line to your application's Gemfile:
7
+
8
+ ```ruby
9
+ # update with the version of your choice
10
+ gem 'fiftytwo'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ ```bash
16
+ $ bundle install
17
+ ```
18
+
19
+ Or install it yourself as:
20
+
21
+ ```bash
22
+ $ gem install fiftytwo
23
+ ```
24
+
25
+ ## Usage
26
+ Get a deck of cards:
27
+ ```ruby
28
+ require "fiftytwo"
29
+
30
+ deck = FiftyTwo::Deck.standard
31
+ # => #<FiftyTwo::Deck:0x00007f905c154b10 @cards=[...]>
32
+
33
+ deck.count
34
+ # => 52
35
+ ```
36
+
37
+ Examine how neatly organized the cards are, and then do something about it:
38
+ ```ruby
39
+ deck[0..7].map(&:to_s)
40
+ # => ["2 of Clubs", "2 of Diamonds", "2 of Hearts", "2 of Spades", "3 of Clubs", "3 of Diamonds", "3 of Hearts", "3 of Spades"]
41
+
42
+ deck.shuffle! # you can always deck.sort! later
43
+ deck[0..7].map(&:to_s)
44
+ # => ["5 of Diamonds", "Jack of Spades", "Ace of Hearts", "6 of Hearts", "9 of Hearts", "2 of Diamonds", "3 of Spades", "7 of Spades"]
45
+ ```
46
+
47
+ Take a deep dive into a card:
48
+ ```ruby
49
+ card = deck.first
50
+ # => #<FiftyTwo::Card:0x00007f905c154548 ...>
51
+
52
+ card.rank
53
+ # => #<FiftyTwo::Rank:0x00007f9056a04068 @value=5, @name="5", @category=:pip>
54
+
55
+ card.suit
56
+ # => #<FiftyTwo::Suit:0x00007f9056a1f138 @name="diamonds", @color=#<FiftyTwo::Suit::Color:0x00007f9056a1f638 @name="red", @rgb="ff0000">, @symbol="♦">
57
+
58
+ card.red?
59
+ # => true
60
+
61
+ card.spades?
62
+ # => false
63
+
64
+ card.pip?
65
+ # => true
66
+
67
+ card.king?
68
+ # => false
69
+ ```
70
+
71
+ Look for types of cards in your deck, as they are currently ordered:
72
+ ```ruby
73
+ deck.kings.count
74
+ # => 4
75
+
76
+ deck.faces.reds.count
77
+ # => 6
78
+
79
+ deck.faces.reds.first.name
80
+ # => "Queen of Hearts"
81
+
82
+ deck.locate("AS").name
83
+ # => "Ace of Spades"
84
+
85
+ deck.locate("10C").name
86
+ # => "Ten of Clubs"
87
+ ```
88
+
89
+ Draw a card from the deck, and give it back later:
90
+ ```ruby
91
+ deck.shuffle!
92
+ card = deck.draw
93
+ # => #<FiftyTwo::Card:0x00007fb3d2284960 ...>
94
+
95
+ deck.count
96
+ # => 51
97
+ card.name
98
+ # => "9 of Diamonds"
99
+
100
+ deck << card
101
+ deck.count
102
+ # => 52
103
+ deck.last.name
104
+ # => "9 of Diamonds"
105
+ ```
106
+
107
+ Deal some cards from the deck to yourself and a friend:
108
+ ```ruby
109
+ my_hand = FiftyTwo::Hand.new
110
+ # => #<FiftyTwo::Hand:0x00007fb3d50ca7c0 @cards=[]>
111
+ your_hand = FiftyTwo::Hand.new
112
+ # => #<FiftyTwo::Hand:0x00007fb3d21c68c0 @cards=[]>
113
+
114
+ deck.deal([my_hand, your_hand], hand_size: 5)
115
+ "Deck has #{deck.count} cards, I have #{my_hand.count} cards, you have #{your_hand.count} cards"
116
+ # => "Deck has 42 cards, I have 5 cards, you have 5 cards"
117
+
118
+ puts my_hand.render, your_hand.render # by the way renderings are colored red/black in your terminal, just like the suit!
119
+ 3♦ 4♠ 5♦ 7♥ 2♣
120
+ 6♠ A♦ 5♠ 10♦ Q♣
121
+ ```
122
+
123
+ Hands, just like the deck, can be shuffled, sorted, searched, etc:
124
+ ```ruby
125
+ your_hand.sort!
126
+ puts your_hand.render
127
+ 5♠ 6♠ 10♦ Q♣ A♦
128
+
129
+ your_hand.aces.count
130
+ # => 1
131
+ ```
132
+
133
+ Pass your cards around:
134
+ ```ruby
135
+ my_hand.transfer("4S", your_hand)
136
+ puts my_hand.render, your_hand.render
137
+ 3♦ 5♦ 7♥ 2♣
138
+ 5♠ 6♠ 10♦ Q♣ A♦ 4♠
139
+
140
+ your_hand.transfer("QC") # goes back to the deck
141
+ puts my_hand.render, your_hand.render
142
+ 3♦ 5♦ 7♥ 2♣
143
+ 5♠ 6♠ 10♦ A♦ 4♠
144
+
145
+ deck.count
146
+ # => 43
147
+ ```
148
+
149
+ # Problems?
150
+ Please submit an [issue](https://github.com/kevinstuffandthings/fiftytwo/issues).
151
+ We'll figure out how to get you up and running with FiftyTwo as smoothly as possible.
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/setup"
4
+ require "bundler/gem_tasks"
5
+ require "standard/rake"
6
+
7
+ Dir.glob("lib/tasks/*.rake").each { |r| load r }
data/fiftytwo.gemspec ADDED
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path("../lib", __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require "fiftytwo/version"
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "fiftytwo"
9
+ spec.version = FiftyTwo::VERSION
10
+ spec.authors = ["Kevin McDonald"]
11
+ spec.email = ["kevinstuffandthings@gmail.com"]
12
+ spec.summary = "A deck of cards, written in Ruby"
13
+ spec.description = spec.summary
14
+ spec.homepage = "https://github.com/kevinstuffandthings/fiftytwo"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0")
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_dependency "activesupport"
23
+ spec.add_dependency "colorize"
24
+
25
+ spec.add_development_dependency "bundler"
26
+ spec.add_development_dependency "pry"
27
+ spec.add_development_dependency "pry-byebug"
28
+ spec.add_development_dependency "rack-test"
29
+ spec.add_development_dependency "rake"
30
+ spec.add_development_dependency "rspec"
31
+ spec.add_development_dependency "simplecov"
32
+ spec.add_development_dependency "standard"
33
+ spec.add_development_dependency "yard"
34
+ end
data/lib/fiftytwo.rb ADDED
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fiftytwo/version"
4
+ require "active_support"
5
+ require "active_support/core_ext"
6
+
7
+ %w[rank suit card hand deck].each { |f| require "fiftytwo/#{f}" }
8
+
9
+ # FiftyTwo
10
+ module FiftyTwo
11
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "colorize"
4
+
5
+ module FiftyTwo
6
+ class Card
7
+ include Comparable
8
+
9
+ attr_reader :deck, :rank, :suit
10
+ delegate :color, to: :suit
11
+
12
+ def initialize(deck, rank, suit)
13
+ @deck = deck
14
+ @rank = rank
15
+ @suit = suit
16
+ end
17
+
18
+ def code
19
+ "#{rank.code}#{suit.code}"
20
+ end
21
+
22
+ def to_s
23
+ "#{rank} of #{suit}"
24
+ end
25
+ alias_method :name, :to_s
26
+
27
+ def identifier
28
+ "#{rank.identifier}#{suit.identifier}"
29
+ end
30
+
31
+ def render
32
+ code.rjust(3).send(suit.color.name)
33
+ end
34
+
35
+ def <=>(other)
36
+ [rank, suit] <=> [other.rank, other.suit]
37
+ end
38
+
39
+ def method_missing(name, **args, &block)
40
+ return super unless name.to_s.ends_with?("?")
41
+
42
+ attributes.each do |attribute|
43
+ return attribute.send(name) if attribute.respond_to?(name)
44
+ end
45
+
46
+ super
47
+ end
48
+
49
+ def respond_to_missing?(name, include_private = false)
50
+ return false unless name.to_s.ends_with?("?")
51
+ return false unless attributes.any? { |a| a.respond_to?(name) }
52
+ end
53
+
54
+ private
55
+
56
+ def attributes
57
+ [rank, suit]
58
+ end
59
+ end
60
+ end