rubycards 0.0.2 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +7 -0
- data/.travis.yml +4 -0
- data/Gemfile +8 -2
- data/README.md +13 -9
- data/Rakefile +12 -2
- data/lib/extensions/string.rb +6 -4
- data/lib/rubycards/card.rb +43 -14
- data/lib/rubycards/deck.rb +31 -17
- data/lib/rubycards/hand.rb +44 -27
- data/lib/rubycards/version.rb +1 -1
- data/rubycards.gemspec +5 -4
- data/spec/rubycards/card_spec.rb +129 -0
- data/spec/rubycards/deck_spec.rb +53 -0
- data/spec/rubycards/string_spec.rb +48 -0
- data/spec/spec_helper.rb +8 -1
- metadata +23 -21
- data/.rvmrc +0 -34
- data/spec/card_spec.rb +0 -75
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 32db687fd05a8fef4d6605cd5ebb8da0173bbcdd
|
4
|
+
data.tar.gz: e09c9a03e1e146d9a246b440bc8cf7e64ce9578c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2c5a916f1055cccca117ede0922691c01f3e8cbfb8a7890dca8eb071ae3e59f7b1c16fdc62e73a0eaad32f3f93dcd6ca00f59591203fe7804a5125bc593b99ba
|
7
|
+
data.tar.gz: 96c7357e0084dbf844c517692e41129499abadf5f11083203535943f2963ea8337afe5daf406749c86045caf2ad836fc7cf6244971d612614ef71b6c7979eb57
|
data/.gitignore
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# Standard ignores
|
1
2
|
*.gem
|
2
3
|
*.rbc
|
3
4
|
.bundle
|
@@ -7,6 +8,8 @@ Gemfile.lock
|
|
7
8
|
InstalledFiles
|
8
9
|
_yardoc
|
9
10
|
coverage
|
11
|
+
|
12
|
+
# Ignore gem stuff
|
10
13
|
doc/
|
11
14
|
lib/bundler/man
|
12
15
|
pkg
|
@@ -16,4 +19,8 @@ test/tmp
|
|
16
19
|
test/version_tmp
|
17
20
|
tmp
|
18
21
|
|
22
|
+
# No .DS_Store
|
19
23
|
.DS_Store
|
24
|
+
|
25
|
+
# Ignore the coveralls config
|
26
|
+
.coveralls.yml
|
data/.travis.yml
ADDED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
# Rubycards
|
2
2
|
|
3
|
+
[![Build Status](https://travis-ci.org/jdan/rubycards.png)](https://travis-ci.org/jdan/rubycards) [![Coverage Status](https://coveralls.io/repos/prezjordan/rubycards/badge.png?branch=master)](https://coveralls.io/r/prezjordan/rubycards)
|
4
|
+
|
3
5
|
Rubycards is a library to emulate playing cards (cards, hands, decks). As an added bonus, you can display the cards as tiny pictures. I'm mainly doing this as an exercise to learn better Ruby organization, as well as documentation and testing. More importantly it's just fun.
|
4
6
|
|
5
|
-
|
7
|
+
**See the extended documentation**: [http://rubydoc.info/github/jdan/rubycards](http://rubydoc.info/github/jdan/rubycards/master/frames)
|
6
8
|
|
7
|
-
![rubycards](
|
9
|
+
![rubycards](https://i.cloudup.com/mlUF8NxTxC-3000x3000.png)
|
8
10
|
|
9
11
|
## Installation
|
10
12
|
|
@@ -24,17 +26,19 @@ Or install it yourself as:
|
|
24
26
|
|
25
27
|
Here's a trivial example of declaring a new deck, shuffling, and drawing 5 cards into a hand:
|
26
28
|
|
27
|
-
|
28
|
-
|
29
|
+
```ruby
|
30
|
+
require 'rubycards'
|
31
|
+
include RubyCards
|
29
32
|
|
30
|
-
|
31
|
-
|
33
|
+
hand = Hand.new
|
34
|
+
deck = Deck.new
|
32
35
|
|
33
|
-
|
36
|
+
deck.shuffle!
|
34
37
|
|
35
|
-
|
38
|
+
hand.draw(deck, 5)
|
36
39
|
|
37
|
-
|
40
|
+
puts hand
|
41
|
+
```
|
38
42
|
|
39
43
|
Which produces the image at the top of this README.
|
40
44
|
|
data/Rakefile
CHANGED
@@ -1,6 +1,16 @@
|
|
1
|
-
require
|
1
|
+
require 'bundler/gem_tasks'
|
2
2
|
require 'rspec/core/rake_task'
|
3
3
|
|
4
4
|
RSpec::Core::RakeTask.new(:spec)
|
5
5
|
|
6
|
-
task default
|
6
|
+
task :default => :spec
|
7
|
+
|
8
|
+
desc 'Start an IRB session in the context of the current bundle'
|
9
|
+
task :irb do
|
10
|
+
sh 'bundle console'
|
11
|
+
end
|
12
|
+
|
13
|
+
desc 'Run a coveralls report (includes tests)'
|
14
|
+
task :report do
|
15
|
+
sh 'coveralls report'
|
16
|
+
end
|
data/lib/extensions/string.rb
CHANGED
@@ -1,17 +1,19 @@
|
|
1
1
|
class String
|
2
|
-
|
3
2
|
# Places a string to the right of the current string
|
4
3
|
#
|
5
4
|
# Example:
|
6
5
|
# ab ef abef
|
7
6
|
# cd .next( gh ) => cdgh
|
7
|
+
#
|
8
|
+
# @param str [String] The string to place adjacent
|
9
|
+
# @return [String] The constructed string
|
8
10
|
def next(str)
|
9
11
|
# zip the two strings, split by line breaks
|
10
|
-
zipped = self.split("\n").zip(str.split("\n"))
|
12
|
+
zipped = self.split("\n").zip(str.split("\n"))
|
11
13
|
|
12
14
|
# map the zipped strings, by joining each pair and ending
|
13
15
|
# with a new line, then joining the whole thing together
|
14
|
-
zipped.map { |e| "#{e.join}
|
16
|
+
zipped.map { |e| "#{e.join}" }.join "\n"
|
15
17
|
end
|
16
18
|
|
17
|
-
end
|
19
|
+
end
|
data/lib/rubycards/card.rb
CHANGED
@@ -2,23 +2,32 @@
|
|
2
2
|
require 'colored'
|
3
3
|
|
4
4
|
module RubyCards
|
5
|
+
|
6
|
+
# Class representation of a standard playing card. (French Design: 52 cards)
|
5
7
|
class Card
|
6
8
|
|
7
9
|
include Comparable
|
8
10
|
|
9
|
-
# constants for glyphs
|
10
11
|
CLUB = '♣'
|
11
12
|
DIAMOND = '♦'
|
12
13
|
HEART = '♥'
|
13
14
|
SPADE = '♠'
|
14
15
|
|
16
|
+
# Returns a new card instance.
|
17
|
+
#
|
18
|
+
# @param rank [String, Integer] The rank of the card
|
19
|
+
# @param suit [String] The suit of the card
|
20
|
+
# @return [Card] The constructed card
|
15
21
|
def initialize(rank = 'Ace', suit = 'Spades')
|
16
22
|
@rank = rank_to_i(rank)
|
17
23
|
@suit = suit_to_i(suit)
|
18
24
|
end
|
19
25
|
|
20
|
-
#
|
21
|
-
#
|
26
|
+
# Returns the rank of the card with an optional `short` parameter
|
27
|
+
# to limit face cards to one character.
|
28
|
+
#
|
29
|
+
# @param short [Boolean] Optional short setting
|
30
|
+
# @return [String] The string representation of the card's rank
|
22
31
|
def rank(short = false)
|
23
32
|
if (2..10) === @rank
|
24
33
|
@rank.to_s
|
@@ -28,8 +37,11 @@ module RubyCards
|
|
28
37
|
end
|
29
38
|
end
|
30
39
|
|
31
|
-
#
|
32
|
-
#
|
40
|
+
# Returns the suit of the card.
|
41
|
+
#
|
42
|
+
# @param glyph [Boolean] Optional setting to draw a unicode glyph in place
|
43
|
+
# of a word
|
44
|
+
# @return [String] The string (of glyph) representation of the card's suit
|
33
45
|
def suit(glyph = false)
|
34
46
|
case @suit
|
35
47
|
when 1
|
@@ -43,22 +55,33 @@ module RubyCards
|
|
43
55
|
end
|
44
56
|
end
|
45
57
|
|
46
|
-
#
|
58
|
+
# Returns the shortened rank, followed by a suit glyph.
|
59
|
+
#
|
60
|
+
# @return [String] The short representation of the card.
|
47
61
|
def short
|
48
62
|
"#{rank(true)}#{suit(true)}"
|
49
63
|
end
|
50
64
|
|
51
|
-
|
52
|
-
|
53
|
-
|
65
|
+
alias_method :inspect, :short
|
66
|
+
|
67
|
+
# Compares the card to another.
|
68
|
+
#
|
69
|
+
# @param other [Card] A card to use in comparison
|
70
|
+
# @return [Integer]
|
71
|
+
def <=>(other)
|
72
|
+
self.to_i <=> other.to_i
|
54
73
|
end
|
55
74
|
|
56
|
-
#
|
75
|
+
# Returns the integer representation of the rank.
|
76
|
+
#
|
77
|
+
# @return [Integer] The rank of the card
|
57
78
|
def to_i
|
58
79
|
@rank
|
59
80
|
end
|
60
81
|
|
61
|
-
#
|
82
|
+
# Returns the ASCII-art representation of the card.
|
83
|
+
#
|
84
|
+
# @return [String] The card drawn in ASCII characters.
|
62
85
|
def to_s
|
63
86
|
# A simple template with X's as placeholders
|
64
87
|
# YY represents the placement of the card's rank
|
@@ -104,7 +127,10 @@ module RubyCards
|
|
104
127
|
|
105
128
|
private
|
106
129
|
|
107
|
-
#
|
130
|
+
# Converts the string representation of a rank to an integer.
|
131
|
+
#
|
132
|
+
# @param rank [String] The rank of the card as a string
|
133
|
+
# @return [Integer] An integer representation of the rank (ordered)
|
108
134
|
def rank_to_i(rank)
|
109
135
|
case rank.to_s
|
110
136
|
when /^(a|ace)/i; 14
|
@@ -117,8 +143,11 @@ module RubyCards
|
|
117
143
|
end
|
118
144
|
end
|
119
145
|
|
120
|
-
#
|
121
|
-
#
|
146
|
+
# Converts the string representation of a suit to an integer, in
|
147
|
+
# alphabetical order.
|
148
|
+
#
|
149
|
+
# @param suit [String] The string representation of the suit
|
150
|
+
# @return [Integer] An integer representation of the suit (ordered)
|
122
151
|
def suit_to_i(suit)
|
123
152
|
case suit
|
124
153
|
when /^club/i; 1
|
data/lib/rubycards/deck.rb
CHANGED
@@ -1,14 +1,23 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
1
3
|
module RubyCards
|
2
4
|
class Deck
|
3
5
|
|
4
6
|
include Enumerable
|
7
|
+
extend Forwardable
|
5
8
|
|
6
9
|
attr_reader :cards
|
7
10
|
|
11
|
+
def_delegators :cards, :empty?, :[], :shift
|
12
|
+
|
13
|
+
alias :draw :shift
|
14
|
+
|
8
15
|
RANKS = [*2..10, 'Jack', 'Queen', 'King', 'Ace']
|
9
16
|
SUITS = %w{ Clubs Diamonds Hearts Spades }
|
10
17
|
|
11
|
-
#
|
18
|
+
# Initializes a standard deck of 52 cards
|
19
|
+
#
|
20
|
+
# @return [Deck] A standard deck of cards
|
12
21
|
def initialize
|
13
22
|
@cards = []
|
14
23
|
|
@@ -17,30 +26,35 @@ module RubyCards
|
|
17
26
|
end
|
18
27
|
end
|
19
28
|
|
20
|
-
#
|
29
|
+
# Shuffles the deck and returns it
|
30
|
+
#
|
31
|
+
# @return [Deck] The shuffled deck
|
21
32
|
def shuffle!
|
22
33
|
@cards.shuffle!
|
34
|
+
self
|
23
35
|
end
|
24
36
|
|
25
|
-
#
|
26
|
-
|
27
|
-
|
37
|
+
# Enumerates the deck
|
38
|
+
#
|
39
|
+
# @param block [Proc] The block to pass into the enumerator
|
40
|
+
# @return [Enumerable] The deck enumerator
|
41
|
+
def each(&block)
|
42
|
+
@cards.each(&block)
|
28
43
|
end
|
29
44
|
|
30
|
-
#
|
31
|
-
|
32
|
-
|
45
|
+
# Displays concise card representations in an array
|
46
|
+
#
|
47
|
+
# @return [String] The concise string representation of the deck
|
48
|
+
def to_s
|
49
|
+
"[ #{@cards.map(&:inspect).join ', '} ]"
|
33
50
|
end
|
34
51
|
|
35
|
-
#
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
yield card
|
42
|
-
end
|
43
|
-
end
|
52
|
+
# Displays a shortened version of the #to_s method for use in the
|
53
|
+
# ruby console
|
54
|
+
#
|
55
|
+
# @return [String] A shortened string output of the deck
|
56
|
+
def inspect
|
57
|
+
"[ #{@cards[0..2].map(&:inspect).join ', '}, ..., #{@cards[-3..-1].map(&:inspect).join ', '} ]"
|
44
58
|
end
|
45
59
|
|
46
60
|
end
|
data/lib/rubycards/hand.rb
CHANGED
@@ -1,11 +1,21 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
1
3
|
module RubyCards
|
2
4
|
class Hand
|
3
5
|
|
4
6
|
include Enumerable
|
7
|
+
extend Forwardable
|
5
8
|
|
6
9
|
attr_reader :cards
|
7
10
|
|
8
|
-
|
11
|
+
def_delegators :cards, :<<, :[]
|
12
|
+
|
13
|
+
alias :add :<<
|
14
|
+
|
15
|
+
# Initializes a hand of cards
|
16
|
+
#
|
17
|
+
# @param cards [Array<Card>] A predetermined array of cards
|
18
|
+
# @return [Hand] The generated hand
|
9
19
|
def initialize(cards = [])
|
10
20
|
@cards = []
|
11
21
|
cards.each do |card|
|
@@ -13,47 +23,54 @@ module RubyCards
|
|
13
23
|
end
|
14
24
|
end
|
15
25
|
|
16
|
-
#
|
17
|
-
|
18
|
-
|
19
|
-
end
|
20
|
-
|
21
|
-
# alias array push (<<) to add method
|
22
|
-
alias_method :<<, :add
|
23
|
-
|
24
|
-
# indexing
|
25
|
-
def [](n)
|
26
|
-
@cards[n]
|
27
|
-
end
|
28
|
-
|
29
|
-
# sorting
|
26
|
+
# Sorts the hand and returns it
|
27
|
+
#
|
28
|
+
# @return [Hand] The sorted hand
|
30
29
|
def sort!
|
31
30
|
@cards.sort!
|
31
|
+
self
|
32
32
|
end
|
33
33
|
|
34
|
-
#
|
34
|
+
# Draws n cards from a given deck and adds them to the Hand
|
35
|
+
#
|
36
|
+
# @param deck [Deck] The deck to draw from
|
37
|
+
# @param n [Integer] The amount of cards to draw
|
38
|
+
# @return [Hand] The new hand
|
35
39
|
def draw(deck, n = 1)
|
36
40
|
n.times do
|
37
41
|
@cards << deck.draw unless deck.empty?
|
38
42
|
end
|
43
|
+
self
|
44
|
+
end
|
45
|
+
|
46
|
+
# Returns the sum of the hand
|
47
|
+
#
|
48
|
+
# @return [Integer] The combined weights of the cards in the hand
|
49
|
+
def sum
|
50
|
+
this.cards.reduce { |memo, card| memo + card.to_i }
|
39
51
|
end
|
40
52
|
|
41
|
-
#
|
53
|
+
# Returns an enumator over the hand
|
54
|
+
#
|
55
|
+
# @param block [Proc] The block to pass into the enumerator
|
56
|
+
# @return [Enumerator] An enumerator for the hand
|
42
57
|
def each(&block)
|
43
|
-
@cards.each
|
44
|
-
if block_given?
|
45
|
-
block.call card
|
46
|
-
else
|
47
|
-
yield card
|
48
|
-
end
|
49
|
-
end
|
58
|
+
@cards.each(&block)
|
50
59
|
end
|
51
60
|
|
52
|
-
#
|
53
|
-
#
|
61
|
+
# Displays the hand using ASCII-art-style cards
|
62
|
+
#
|
63
|
+
# @return [String] The ASCII representation of the hand
|
54
64
|
def to_s
|
55
65
|
@cards.map(&:to_s).inject(:next)
|
56
66
|
end
|
57
67
|
|
68
|
+
# A shortened representation of the hand used for the console
|
69
|
+
#
|
70
|
+
# @return [String] A concise string representation of the hand
|
71
|
+
def inspect
|
72
|
+
"[ #{@cards.map(&:inspect).join ', '} ]"
|
73
|
+
end
|
74
|
+
|
58
75
|
end
|
59
|
-
end
|
76
|
+
end
|
data/lib/rubycards/version.rb
CHANGED
data/rubycards.gemspec
CHANGED
@@ -6,16 +6,17 @@ require 'rubycards/version'
|
|
6
6
|
Gem::Specification.new do |gem|
|
7
7
|
gem.name = "rubycards"
|
8
8
|
gem.version = RubyCards::VERSION
|
9
|
-
gem.authors = ["Jordan Scales", "Joe Letizia"]
|
10
|
-
gem.email = ["scalesjordan@gmail.com", "joe.letizia@gmail.com"]
|
9
|
+
gem.authors = ["Jordan Scales", "Joe Letizia", "Justin Workman"]
|
10
|
+
gem.email = ["scalesjordan@gmail.com", "joe.letizia@gmail.com", "xtagon@gmail.com"]
|
11
11
|
gem.description = "RubyCards"
|
12
|
+
gem.licenses = ["MIT"]
|
12
13
|
gem.summary = "A 52 card gem"
|
13
|
-
gem.homepage = "https://github.com/
|
14
|
+
gem.homepage = "https://github.com/jdan/rubycards"
|
14
15
|
|
15
16
|
gem.files = `git ls-files`.split($/)
|
16
17
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
18
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
19
|
gem.require_paths = ["lib"]
|
19
20
|
|
20
|
-
gem.add_dependency('colored', '
|
21
|
+
gem.add_dependency('colored', '~> 1.2')
|
21
22
|
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
include RubyCards
|
4
|
+
|
5
|
+
describe Card do
|
6
|
+
describe '#initialize' do
|
7
|
+
context 'no params' do
|
8
|
+
it 'should return the ace of spades' do
|
9
|
+
subject.suit.should == 'Spades'
|
10
|
+
subject.rank.should == 'Ace'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'params' do
|
15
|
+
it 'should return the card specified in params' do
|
16
|
+
new_card = Card.new('Queen', 'Clubs')
|
17
|
+
new_card.rank.should == 'Queen'
|
18
|
+
new_card.suit.should == 'Clubs'
|
19
|
+
|
20
|
+
new_card = Card.new(3, 'Spades')
|
21
|
+
new_card.rank.should == 3.to_s
|
22
|
+
new_card.suit.should == 'Spades'
|
23
|
+
|
24
|
+
new_card = Card.new('Jack', 'Diamonds')
|
25
|
+
new_card.rank.should == 'Jack'
|
26
|
+
new_card.suit.should == 'Diamonds'
|
27
|
+
|
28
|
+
new_card = Card.new(7, 'Hearts')
|
29
|
+
new_card.rank.should == 7.to_s
|
30
|
+
new_card.suit.should == 'Hearts'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '#comparator' do
|
36
|
+
let (:king) { Card.new('King','Clubs') }
|
37
|
+
let (:queen) { Card.new('Queen','Clubs') }
|
38
|
+
let (:jack) { Card.new('Jack','Clubs') }
|
39
|
+
let (:ace) { Card.new('Ace','Clubs') }
|
40
|
+
let (:c2) { Card.new(2,'Diamonds') }
|
41
|
+
let (:c2_heart) { Card.new(2,'Hearts') }
|
42
|
+
let (:c4) { Card.new(4,'Spades') }
|
43
|
+
|
44
|
+
it 'should reflect the correct rank when compared' do
|
45
|
+
king.should > queen
|
46
|
+
king.should > jack
|
47
|
+
king.should == king
|
48
|
+
king.should < ace
|
49
|
+
|
50
|
+
jack.should_not > queen
|
51
|
+
jack.should_not > ace
|
52
|
+
jack.should < queen
|
53
|
+
|
54
|
+
ace.should_not < queen
|
55
|
+
ace.should > c4
|
56
|
+
|
57
|
+
c2.should < c4
|
58
|
+
c2_heart.should == c2
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe '#rank' do
|
63
|
+
context 'face cards' do
|
64
|
+
let (:king) { Card.new('King', 'Clubs') }
|
65
|
+
|
66
|
+
it 'should return a long rank' do
|
67
|
+
king.rank.should == 'King'
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should return a short rank' do
|
71
|
+
king.rank(true).should == 'K'
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'numeric cards' do
|
76
|
+
let (:num) { Card.new(10, 'Diamonds') }
|
77
|
+
|
78
|
+
it 'should have the same long and short rank' do
|
79
|
+
num.rank.should == num.rank(true)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe '#display' do
|
85
|
+
BORDER_COUNT = 18 # the number of unicode characters on the border
|
86
|
+
RANKS = [*2..10, 'Jack', 'Queen', 'King', 'Ace']
|
87
|
+
|
88
|
+
it 'should have the correct number of glyps' do
|
89
|
+
RANKS.each do |rank|
|
90
|
+
card = Card.new(rank, 'hearts') # rspec doesn't play nice with dark cards
|
91
|
+
|
92
|
+
if (2..10).include? card.rank.to_i
|
93
|
+
card.to_s.scan(/[^\x00-\x7F]/).count.should == card.rank.to_i + BORDER_COUNT
|
94
|
+
else
|
95
|
+
card.to_s.scan(/[^\x00-\x7F]/).count.should == 2 + BORDER_COUNT
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'should display #inspect the same as #short' do
|
101
|
+
RANKS.each do |rank|
|
102
|
+
card = Card.new(rank, 'diamonds')
|
103
|
+
|
104
|
+
card.inspect.should == card.short
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe '#garbage' do
|
110
|
+
it 'should set a garbage rank to nil' do
|
111
|
+
runt_card1 = Card.new(0, 'Diamonds')
|
112
|
+
runt_card2 = Card.new(11, 'Diamonds')
|
113
|
+
runt_card3 = Card.new(-6, 'Spades')
|
114
|
+
|
115
|
+
runt_card1.rank.should be_nil
|
116
|
+
runt_card2.rank.should be_nil
|
117
|
+
runt_card3.rank.should be_nil
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'should set a garbage suit to nil' do
|
121
|
+
runt_card1 = Card.new(7, '')
|
122
|
+
runt_card2 = Card.new('Ace', 'Garbage')
|
123
|
+
|
124
|
+
runt_card1.suit.should be_nil
|
125
|
+
runt_card2.suit.should be_nil
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
include RubyCards
|
4
|
+
|
5
|
+
describe Deck do
|
6
|
+
subject(:deck) { Deck.new }
|
7
|
+
|
8
|
+
describe '#initialize' do
|
9
|
+
it 'initializes 52 cards' do
|
10
|
+
deck.cards.count.should == 52
|
11
|
+
# test indexing
|
12
|
+
deck[0].should be_a Card
|
13
|
+
# test enumerability
|
14
|
+
deck.each { |card| card.should be_a Card }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#shuffle!' do
|
19
|
+
it 'shuffles the cards' do
|
20
|
+
cards_before_shuffling = deck.cards.dup
|
21
|
+
deck.shuffle!
|
22
|
+
deck.cards.should_not == cards_before_shuffling
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'returns itself' do
|
26
|
+
should == deck.shuffle!
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe '#draw' do
|
31
|
+
it 'draws a single card from the deck' do
|
32
|
+
first_card = deck.cards.first
|
33
|
+
cards_expected_after_draw = deck.cards[1..-1]
|
34
|
+
deck.draw.should == first_card
|
35
|
+
deck.cards.should == cards_expected_after_draw
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe '#empty?' do
|
40
|
+
context 'empty deck' do
|
41
|
+
it 'returns true' do
|
42
|
+
deck.cards.count.times { deck.draw }
|
43
|
+
deck.empty?.should be_true
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'full deck' do
|
48
|
+
it 'returns false' do
|
49
|
+
deck.empty?.should be_false
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
include RubyCards
|
4
|
+
|
5
|
+
describe String do
|
6
|
+
describe '#next' do
|
7
|
+
context 'one liners' do
|
8
|
+
# cat <- dog == catdog
|
9
|
+
it 'should concatenate strings' do
|
10
|
+
'cat'.next('dog').should == 'catdog'
|
11
|
+
end
|
12
|
+
|
13
|
+
# hello <- "" == hello
|
14
|
+
it 'should remain unchanged' do
|
15
|
+
'hello'.next('').should == 'hello'
|
16
|
+
end
|
17
|
+
|
18
|
+
# "" <- hello == ""
|
19
|
+
it 'should return an empty string' do
|
20
|
+
''.next('hello').should == ''
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'multiple lines' do
|
25
|
+
# aa bb aabb
|
26
|
+
# aa <- bb == aabb
|
27
|
+
it 'should place blocks adjacently' do
|
28
|
+
"aa\naa".next("bb\nbb").should == "aabb\naabb"
|
29
|
+
"aaa\naaa\naaa".next("bbb\nbbb\nbbb").should == "aaabbb\naaabbb\naaabbb"
|
30
|
+
end
|
31
|
+
|
32
|
+
# aa bb aabb
|
33
|
+
# aa <- == aa
|
34
|
+
it 'should stack the second block in its entirety' do
|
35
|
+
"aa\naa".next("bb").should == "aabb\naa"
|
36
|
+
"1\n2\n3".next("4\n5").should == "14\n25\n3"
|
37
|
+
end
|
38
|
+
|
39
|
+
# aa bb aabb
|
40
|
+
# <- bb ==
|
41
|
+
it 'should cut off some of the second block' do
|
42
|
+
"aa".next("bb\nbb").should == "aabb"
|
43
|
+
"1\n2".next("4\n5\n6").should == "14\n25"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,8 +1,15 @@
|
|
1
|
+
# Coveralls!
|
2
|
+
require 'coveralls'
|
3
|
+
Coveralls.wear!
|
4
|
+
|
1
5
|
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
6
|
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
7
|
# Require this file using `require "spec_helper"` to ensure that it is only
|
4
8
|
# loaded once.
|
5
|
-
|
9
|
+
|
10
|
+
require 'rubycards'
|
11
|
+
require 'json'
|
12
|
+
|
6
13
|
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
14
|
RSpec.configure do |config|
|
8
15
|
config.treat_symbols_as_metadata_keys_with_true_values = true
|
metadata
CHANGED
@@ -1,44 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubycards
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.0.4
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Jordan Scales
|
9
8
|
- Joe Letizia
|
9
|
+
- Justin Workman
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2014-07-21 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: colored
|
17
17
|
requirement: !ruby/object:Gem::Requirement
|
18
|
-
none: false
|
19
18
|
requirements:
|
20
|
-
- -
|
19
|
+
- - "~>"
|
21
20
|
- !ruby/object:Gem::Version
|
22
21
|
version: '1.2'
|
23
22
|
type: :runtime
|
24
23
|
prerelease: false
|
25
24
|
version_requirements: !ruby/object:Gem::Requirement
|
26
|
-
none: false
|
27
25
|
requirements:
|
28
|
-
- -
|
26
|
+
- - "~>"
|
29
27
|
- !ruby/object:Gem::Version
|
30
28
|
version: '1.2'
|
31
29
|
description: RubyCards
|
32
30
|
email:
|
33
31
|
- scalesjordan@gmail.com
|
34
32
|
- joe.letizia@gmail.com
|
33
|
+
- xtagon@gmail.com
|
35
34
|
executables: []
|
36
35
|
extensions: []
|
37
36
|
extra_rdoc_files: []
|
38
37
|
files:
|
39
|
-
- .gitignore
|
40
|
-
- .rspec
|
41
|
-
- .
|
38
|
+
- ".gitignore"
|
39
|
+
- ".rspec"
|
40
|
+
- ".travis.yml"
|
42
41
|
- Gemfile
|
43
42
|
- LICENSE.txt
|
44
43
|
- README.md
|
@@ -50,35 +49,38 @@ files:
|
|
50
49
|
- lib/rubycards/hand.rb
|
51
50
|
- lib/rubycards/version.rb
|
52
51
|
- rubycards.gemspec
|
53
|
-
- spec/card_spec.rb
|
54
52
|
- spec/factory.rb
|
53
|
+
- spec/rubycards/card_spec.rb
|
54
|
+
- spec/rubycards/deck_spec.rb
|
55
|
+
- spec/rubycards/string_spec.rb
|
55
56
|
- spec/spec_helper.rb
|
56
|
-
homepage: https://github.com/
|
57
|
-
licenses:
|
57
|
+
homepage: https://github.com/jdan/rubycards
|
58
|
+
licenses:
|
59
|
+
- MIT
|
60
|
+
metadata: {}
|
58
61
|
post_install_message:
|
59
62
|
rdoc_options: []
|
60
63
|
require_paths:
|
61
64
|
- lib
|
62
65
|
required_ruby_version: !ruby/object:Gem::Requirement
|
63
|
-
none: false
|
64
66
|
requirements:
|
65
|
-
- -
|
67
|
+
- - ">="
|
66
68
|
- !ruby/object:Gem::Version
|
67
69
|
version: '0'
|
68
70
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
-
none: false
|
70
71
|
requirements:
|
71
|
-
- -
|
72
|
+
- - ">="
|
72
73
|
- !ruby/object:Gem::Version
|
73
74
|
version: '0'
|
74
75
|
requirements: []
|
75
76
|
rubyforge_project:
|
76
|
-
rubygems_version:
|
77
|
+
rubygems_version: 2.2.0.rc.1
|
77
78
|
signing_key:
|
78
|
-
specification_version:
|
79
|
+
specification_version: 4
|
79
80
|
summary: A 52 card gem
|
80
81
|
test_files:
|
81
|
-
- spec/card_spec.rb
|
82
82
|
- spec/factory.rb
|
83
|
+
- spec/rubycards/card_spec.rb
|
84
|
+
- spec/rubycards/deck_spec.rb
|
85
|
+
- spec/rubycards/string_spec.rb
|
83
86
|
- spec/spec_helper.rb
|
84
|
-
has_rdoc:
|
data/.rvmrc
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
#!/usr/bin/env bash
|
2
|
-
|
3
|
-
# This is an RVM Project .rvmrc file, used to automatically load the ruby
|
4
|
-
# development environment upon cd'ing into the directory
|
5
|
-
|
6
|
-
# First we specify our desired <ruby>[@<gemset>], the @gemset name is optional,
|
7
|
-
# Only full ruby name is supported here, for short names use:
|
8
|
-
# echo "rvm use 1.9.3" > .rvmrc
|
9
|
-
environment_id="ruby-1.9.3-p385@rubycards"
|
10
|
-
|
11
|
-
# Uncomment the following lines if you want to verify rvm version per project
|
12
|
-
# rvmrc_rvm_version="1.18.6 (stable)" # 1.10.1 seams as a safe start
|
13
|
-
# eval "$(echo ${rvm_version}.${rvmrc_rvm_version} | awk -F. '{print "[[ "$1*65536+$2*256+$3" -ge "$4*65536+$5*256+$6" ]]"}' )" || {
|
14
|
-
# echo "This .rvmrc file requires at least RVM ${rvmrc_rvm_version}, aborting loading."
|
15
|
-
# return 1
|
16
|
-
# }
|
17
|
-
|
18
|
-
# First we attempt to load the desired environment directly from the environment
|
19
|
-
# file. This is very fast and efficient compared to running through the entire
|
20
|
-
# CLI and selector. If you want feedback on which environment was used then
|
21
|
-
# insert the word 'use' after --create as this triggers verbose mode.
|
22
|
-
if [[ -d "${rvm_path:-$HOME/.rvm}/environments"
|
23
|
-
&& -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
|
24
|
-
then
|
25
|
-
\. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
|
26
|
-
[[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]] &&
|
27
|
-
\. "${rvm_path:-$HOME/.rvm}/hooks/after_use" || true
|
28
|
-
else
|
29
|
-
# If the environment file has not yet been created, use the RVM CLI to select.
|
30
|
-
rvm --create "$environment_id" || {
|
31
|
-
echo "Failed to create RVM environment '${environment_id}'."
|
32
|
-
return 1
|
33
|
-
}
|
34
|
-
fi
|
data/spec/card_spec.rb
DELETED
@@ -1,75 +0,0 @@
|
|
1
|
-
require 'rubycards'
|
2
|
-
|
3
|
-
include RubyCards
|
4
|
-
|
5
|
-
describe Card do
|
6
|
-
describe '#initialize' do
|
7
|
-
context 'no params' do
|
8
|
-
it 'should return the ace of spades' do
|
9
|
-
subject.suit.should == 'Spades'
|
10
|
-
subject.rank.should == 'Ace'
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
context 'params' do
|
15
|
-
it 'should return the card specified in params' do
|
16
|
-
new_card = Card.new('Queen', 'Clubs')
|
17
|
-
new_card.rank.should == 'Queen'
|
18
|
-
new_card.suit.should == 'Clubs'
|
19
|
-
|
20
|
-
new_card = Card.new(3, 'Spades')
|
21
|
-
new_card.rank.should == 3.to_s
|
22
|
-
new_card.suit.should == 'Spades'
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
describe '#comparator' do
|
28
|
-
let(:king){Card.new('King','Clubs')}
|
29
|
-
let(:queen){Card.new('Queen','Clubs')}
|
30
|
-
let(:jack){Card.new('Jack','Clubs')}
|
31
|
-
let(:ace){Card.new('Ace','Clubs')}
|
32
|
-
let(:c2){Card.new(2,'Diamonds')}
|
33
|
-
let(:c2_heart){Card.new(2,'Hearts')}
|
34
|
-
let(:c4){Card.new(4,'Spades')}
|
35
|
-
|
36
|
-
it 'should reflect the correct rank when compared' do
|
37
|
-
king.should > queen
|
38
|
-
king.should > jack
|
39
|
-
king.should == king
|
40
|
-
king.should < ace
|
41
|
-
|
42
|
-
jack.should_not > queen
|
43
|
-
jack.should_not > ace
|
44
|
-
jack.should < queen
|
45
|
-
|
46
|
-
ace.should_not < queen
|
47
|
-
ace.should > c4
|
48
|
-
|
49
|
-
c2.should < c4
|
50
|
-
c2_heart.should == c2
|
51
|
-
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
describe '#rank' do
|
56
|
-
context 'face cards' do
|
57
|
-
let(:king){Card.new('King','Clubs')}
|
58
|
-
|
59
|
-
it 'should return a long rank' do
|
60
|
-
king.rank.should == 'King'
|
61
|
-
end
|
62
|
-
it 'should return a short rank' do
|
63
|
-
king.rank(true).should == 'K'
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
context 'numeric cards' do
|
68
|
-
let(:num){Card.new(10,'Diamonds')}
|
69
|
-
|
70
|
-
it 'should have the same long and short rank' do
|
71
|
-
num.rank.should == num.rank(true)
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|