rubycards 0.0.1 → 0.0.2
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 +1 -0
- data/lib/rubycards/card.rb +110 -108
- data/lib/rubycards/deck.rb +33 -31
- data/lib/rubycards/hand.rb +43 -41
- data/lib/rubycards/version.rb +2 -2
- data/rubycards.gemspec +1 -1
- data/spec/card_spec.rb +2 -0
- metadata +1 -1
data/README.md
CHANGED
data/lib/rubycards/card.rb
CHANGED
@@ -1,131 +1,133 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require 'colored'
|
3
3
|
|
4
|
-
|
4
|
+
module RubyCards
|
5
|
+
class Card
|
5
6
|
|
6
|
-
|
7
|
+
include Comparable
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
# constants for glyphs
|
10
|
+
CLUB = '♣'
|
11
|
+
DIAMOND = '♦'
|
12
|
+
HEART = '♥'
|
13
|
+
SPADE = '♠'
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
end
|
18
|
-
|
19
|
-
# returns the rank of the card
|
20
|
-
# optional short parameter will limit face cards to one character
|
21
|
-
def rank(short = false)
|
22
|
-
if (2..10) === @rank
|
23
|
-
@rank.to_s
|
24
|
-
else
|
25
|
-
h = { 11 => 'Jack', 12 => 'Queen', 13 => 'King', 14 => 'Ace' }
|
26
|
-
h[@rank] && short ? h[@rank][0] : h[@rank]
|
15
|
+
def initialize(rank = 'Ace', suit = 'Spades')
|
16
|
+
@rank = rank_to_i(rank)
|
17
|
+
@suit = suit_to_i(suit)
|
27
18
|
end
|
28
|
-
end
|
29
19
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
glyph ? HEART.red : 'Hearts'
|
40
|
-
when 4
|
41
|
-
glyph ? SPADE.black.bold : 'Spades'
|
20
|
+
# returns the rank of the card
|
21
|
+
# optional short parameter will limit face cards to one character
|
22
|
+
def rank(short = false)
|
23
|
+
if (2..10) === @rank
|
24
|
+
@rank.to_s
|
25
|
+
else
|
26
|
+
h = { 11 => 'Jack', 12 => 'Queen', 13 => 'King', 14 => 'Ace' }
|
27
|
+
h[@rank] && short ? h[@rank][0] : h[@rank]
|
28
|
+
end
|
42
29
|
end
|
43
|
-
end
|
44
30
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
31
|
+
# returns the suit of a card
|
32
|
+
# optional glyph parameter displays a colored unicode character
|
33
|
+
def suit(glyph = false)
|
34
|
+
case @suit
|
35
|
+
when 1
|
36
|
+
glyph ? CLUB.black.bold : 'Clubs'
|
37
|
+
when 2
|
38
|
+
glyph ? DIAMOND.red : 'Diamonds'
|
39
|
+
when 3
|
40
|
+
glyph ? HEART.red : 'Hearts'
|
41
|
+
when 4
|
42
|
+
glyph ? SPADE.black.bold : 'Spades'
|
43
|
+
end
|
44
|
+
end
|
49
45
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
46
|
+
# returns the short rank, followed by suit icon
|
47
|
+
def short
|
48
|
+
"#{rank(true)}#{suit(true)}"
|
49
|
+
end
|
54
50
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
51
|
+
# comparator
|
52
|
+
def <=>(c)
|
53
|
+
self.to_i <=> c.to_i
|
54
|
+
end
|
59
55
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
# YY represents the placement of the card's rank
|
64
|
-
template = <<-TPL.gsub(/^\s+/,'')
|
65
|
-
╭───────╮
|
66
|
-
| X X X |
|
67
|
-
| X X X |
|
68
|
-
| X YYX |
|
69
|
-
| X X X |
|
70
|
-
╰───────╯
|
71
|
-
TPL
|
72
|
-
|
73
|
-
# the patterns represent the configuration of glyphys
|
74
|
-
# read from left to right, top to bottom
|
75
|
-
# X means place a glyph, _ means clear the space
|
76
|
-
case @rank
|
77
|
-
when 2; pattern = '_X_______X_'
|
78
|
-
when 3; pattern = '_X__X____X_'
|
79
|
-
when 4; pattern = 'X_X_____X_X'
|
80
|
-
when 5; pattern = 'X_X_X___X_X'
|
81
|
-
when 6; pattern = 'X_XX_X__X_X'
|
82
|
-
when 7; pattern = 'X_X_X_XXX_X'
|
83
|
-
when 8; pattern = 'X_XX_XXXX_X'
|
84
|
-
when 9; pattern = 'X_XXXXXXX_X'
|
85
|
-
when 10; pattern = 'XXXX_XXXXXX'
|
86
|
-
when 11..14;
|
87
|
-
pattern = 'X_________X'
|
56
|
+
# returns the numerical representation of the rank
|
57
|
+
def to_i
|
58
|
+
@rank
|
88
59
|
end
|
89
60
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
61
|
+
# draws a card picture
|
62
|
+
def to_s
|
63
|
+
# A simple template with X's as placeholders
|
64
|
+
# YY represents the placement of the card's rank
|
65
|
+
template = <<-TPL.gsub(/^\s+/,'')
|
66
|
+
╭───────╮
|
67
|
+
| X X X |
|
68
|
+
| X X X |
|
69
|
+
| X YYX |
|
70
|
+
| X X X |
|
71
|
+
╰───────╯
|
72
|
+
TPL
|
73
|
+
|
74
|
+
# the patterns represent the configuration of glyphys
|
75
|
+
# read from left to right, top to bottom
|
76
|
+
# X means place a glyph, _ means clear the space
|
77
|
+
case @rank
|
78
|
+
when 2; pattern = '_X_______X_'
|
79
|
+
when 3; pattern = '_X__X____X_'
|
80
|
+
when 4; pattern = 'X_X_____X_X'
|
81
|
+
when 5; pattern = 'X_X_X___X_X'
|
82
|
+
when 6; pattern = 'X_XX_X__X_X'
|
83
|
+
when 7; pattern = 'X_X_X_XXX_X'
|
84
|
+
when 8; pattern = 'X_XX_XXXX_X'
|
85
|
+
when 9; pattern = 'X_XXXXXXX_X'
|
86
|
+
when 10; pattern = 'XXXX_XXXXXX'
|
87
|
+
when 11..14;
|
88
|
+
pattern = 'X_________X'
|
97
89
|
end
|
98
|
-
end
|
99
90
|
|
100
|
-
|
101
|
-
|
102
|
-
|
91
|
+
pattern.each_char do |c|
|
92
|
+
# replace X's with glyphs
|
93
|
+
if c == 'X'
|
94
|
+
template.sub!(/X/, "#{suit(true)}")
|
95
|
+
# replace _'s with whitespace
|
96
|
+
else
|
97
|
+
template.sub!(/X/, " ")
|
98
|
+
end
|
99
|
+
end
|
103
100
|
|
104
|
-
|
105
|
-
|
106
|
-
# converts the string representation of a rank to an integer
|
107
|
-
def rank_to_i(rank)
|
108
|
-
case rank.to_s
|
109
|
-
when /^(a|ace)/i; 14
|
110
|
-
when /^(k|king)/i; 13
|
111
|
-
when /^(q|queen)/i; 12
|
112
|
-
when /^(j|jack)/i; 11
|
113
|
-
when '10'; 10
|
114
|
-
when '2'..'9'; rank
|
115
|
-
else 0
|
101
|
+
# place the card rank (left-padded)
|
102
|
+
template.sub(/YY/, rank(true).ljust(2))
|
116
103
|
end
|
117
|
-
end
|
118
104
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
105
|
+
private
|
106
|
+
|
107
|
+
# converts the string representation of a rank to an integer
|
108
|
+
def rank_to_i(rank)
|
109
|
+
case rank.to_s
|
110
|
+
when /^(a|ace)/i; 14
|
111
|
+
when /^(k|king)/i; 13
|
112
|
+
when /^(q|queen)/i; 12
|
113
|
+
when /^(j|jack)/i; 11
|
114
|
+
when '10'; 10
|
115
|
+
when '2'..'9'; rank
|
116
|
+
else 0
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# converts the string representation of a suit to an integer
|
121
|
+
# suits are ordered alphabetically
|
122
|
+
def suit_to_i(suit)
|
123
|
+
case suit
|
124
|
+
when /^club/i; 1
|
125
|
+
when /^diamond/i; 2
|
126
|
+
when /^heart/i; 3
|
127
|
+
when /^spade/i; 4
|
128
|
+
else 0
|
129
|
+
end
|
128
130
|
end
|
129
|
-
end
|
130
131
|
|
132
|
+
end
|
131
133
|
end
|
data/lib/rubycards/deck.rb
CHANGED
@@ -1,45 +1,47 @@
|
|
1
|
-
|
1
|
+
module RubyCards
|
2
|
+
class Deck
|
2
3
|
|
3
|
-
|
4
|
+
include Enumerable
|
4
5
|
|
5
|
-
|
6
|
+
attr_reader :cards
|
6
7
|
|
7
|
-
|
8
|
-
|
8
|
+
RANKS = [*2..10, 'Jack', 'Queen', 'King', 'Ace']
|
9
|
+
SUITS = %w{ Clubs Diamonds Hearts Spades }
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
11
|
+
# initialize a deck of cards using the RANKS and SUITS constants
|
12
|
+
def initialize
|
13
|
+
@cards = []
|
13
14
|
|
14
|
-
|
15
|
-
|
15
|
+
RANKS.product(SUITS).each do |rank, suit|
|
16
|
+
@cards << Card.new(rank, suit)
|
17
|
+
end
|
16
18
|
end
|
17
|
-
end
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
# shuffle the deck
|
21
|
+
def shuffle!
|
22
|
+
@cards.shuffle!
|
23
|
+
end
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
# draw a card from the deck
|
26
|
+
def draw
|
27
|
+
@cards.shift
|
28
|
+
end
|
28
29
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
30
|
+
# determines if the deck is empty
|
31
|
+
def empty?
|
32
|
+
@cards.empty?
|
33
|
+
end
|
33
34
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
35
|
+
# Enumerable#each
|
36
|
+
def each(&block)
|
37
|
+
@cards.each do |card|
|
38
|
+
if block_given?
|
39
|
+
block.call card
|
40
|
+
else
|
41
|
+
yield card
|
42
|
+
end
|
41
43
|
end
|
42
44
|
end
|
43
|
-
end
|
44
45
|
|
46
|
+
end
|
45
47
|
end
|
data/lib/rubycards/hand.rb
CHANGED
@@ -1,57 +1,59 @@
|
|
1
|
-
|
1
|
+
module RubyCards
|
2
|
+
class Hand
|
2
3
|
|
3
|
-
|
4
|
+
include Enumerable
|
4
5
|
|
5
|
-
|
6
|
+
attr_reader :cards
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
# initialize with an array of cards
|
9
|
+
def initialize(cards = [])
|
10
|
+
@cards = []
|
11
|
+
cards.each do |card|
|
12
|
+
self << card
|
13
|
+
end
|
12
14
|
end
|
13
|
-
end
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
# add a card if it is valid
|
17
|
+
def add(card)
|
18
|
+
@cards << card if card.instance_of? Card
|
19
|
+
end
|
19
20
|
|
20
|
-
|
21
|
-
|
21
|
+
# alias array push (<<) to add method
|
22
|
+
alias_method :<<, :add
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
24
|
+
# indexing
|
25
|
+
def [](n)
|
26
|
+
@cards[n]
|
27
|
+
end
|
27
28
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
29
|
+
# sorting
|
30
|
+
def sort!
|
31
|
+
@cards.sort!
|
32
|
+
end
|
32
33
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
34
|
+
# draw n cards from a deck
|
35
|
+
def draw(deck, n = 1)
|
36
|
+
n.times do
|
37
|
+
@cards << deck.draw unless deck.empty?
|
38
|
+
end
|
37
39
|
end
|
38
|
-
end
|
39
40
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
41
|
+
# Enumerable#each
|
42
|
+
def each(&block)
|
43
|
+
@cards.each do |card|
|
44
|
+
if block_given?
|
45
|
+
block.call card
|
46
|
+
else
|
47
|
+
yield card
|
48
|
+
end
|
47
49
|
end
|
48
50
|
end
|
49
|
-
end
|
50
51
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
52
|
+
# displaying the card icons
|
53
|
+
# using extensions/string.rb for String#next
|
54
|
+
def to_s
|
55
|
+
@cards.map(&:to_s).inject(:next)
|
56
|
+
end
|
56
57
|
|
58
|
+
end
|
57
59
|
end
|
data/lib/rubycards/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
module
|
2
|
-
VERSION = "0.0.
|
1
|
+
module RubyCards
|
2
|
+
VERSION = "0.0.2"
|
3
3
|
end
|
data/rubycards.gemspec
CHANGED
@@ -5,7 +5,7 @@ require 'rubycards/version'
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |gem|
|
7
7
|
gem.name = "rubycards"
|
8
|
-
gem.version =
|
8
|
+
gem.version = RubyCards::VERSION
|
9
9
|
gem.authors = ["Jordan Scales", "Joe Letizia"]
|
10
10
|
gem.email = ["scalesjordan@gmail.com", "joe.letizia@gmail.com"]
|
11
11
|
gem.description = "RubyCards"
|
data/spec/card_spec.rb
CHANGED