Class: PokerTrump::Cards

Inherits:
Array
  • Object
show all
Includes:
Comparable
Defined in:
lib/poker_trump/cards.rb

Constant Summary collapse

DeleteError =
Class.new(StandardError)

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.from_json(json) ⇒ Object



21
22
23
24
25
# File 'lib/poker_trump/cards.rb', line 21

def from_json(json)
  cards = JSON.parse(json).map { |c| PokerTrump::Card.new(rank: c['rank'], suit: c['suit'].to_sym) }

  new(cards)
end

.from_string(string) ⇒ Object



15
16
17
18
19
# File 'lib/poker_trump/cards.rb', line 15

def from_string(string)
  cards = string.scan(/[AKQJT2-9][shdc]/).map { |s| PokerTrump::Card.from_string(s) }

  new(cards)
end

.new_deckObject



7
8
9
10
11
12
13
# File 'lib/poker_trump/cards.rb', line 7

def new_deck
  cards = PokerTrump::Card::RANKS.product(PokerTrump::Card::SUITS).map do |rank, suit|
    PokerTrump::Card.new(rank: rank, suit: suit)
  end

  new(cards)
end

Instance Method Details

#<=>(other) ⇒ Object



212
213
214
# File 'lib/poker_trump/cards.rb', line 212

def <=>(other)
  score <=> other.score
end

#add_card(card) ⇒ Object



57
58
59
60
# File 'lib/poker_trump/cards.rb', line 57

def add_card(card)
  clone_cards = clone
  clone_cards.push(card)
end

#add_card!(card) ⇒ Object



62
63
64
# File 'lib/poker_trump/cards.rb', line 62

def add_card!(card)
  push(card)
end

#add_cards(cards) ⇒ Object



66
67
68
69
70
71
# File 'lib/poker_trump/cards.rb', line 66

def add_cards(cards)
  clone_cards = clone

  cards.each { |card| clone_cards.add_card!(card) }
  clone_cards
end

#add_cards!(cards) ⇒ Object



73
74
75
76
# File 'lib/poker_trump/cards.rb', line 73

def add_cards!(cards)
  cards.each { |card| add_card!(card) }
  self
end

#delete_card(card) ⇒ Object

Raises:



36
37
38
39
40
41
42
43
44
# File 'lib/poker_trump/cards.rb', line 36

def delete_card(card)
  i = index(card)
  raise DeleteError if i.nil?

  clone_cards = clone
  clone_cards.delete_at(i)

  clone_cards
end

#delete_card!(card) ⇒ Object

Raises:



28
29
30
31
32
33
34
# File 'lib/poker_trump/cards.rb', line 28

def delete_card!(card)
  i = index(card)
  raise DeleteError if i.nil?

  delete_at(i)
  self
end

#delete_cards(cards) ⇒ Object



51
52
53
54
55
# File 'lib/poker_trump/cards.rb', line 51

def delete_cards(cards)
  clone_cards = clone
  cards.each { |t| clone_cards.delete_card!(t) }
  clone_cards
end

#delete_cards!(cards) ⇒ Object



46
47
48
49
# File 'lib/poker_trump/cards.rb', line 46

def delete_cards!(cards)
  cards.each { |t| delete_card!(t) }
  self
end

#flush_rateObject



129
130
131
132
133
134
135
136
137
138
# File 'lib/poker_trump/cards.rb', line 129

def flush_rate
  group_by_suit.each do |_k, v|
    next if v.size < 5

    z = v.sort_by_rank
    return [6, z[0].rank_value, z[1].rank_value, z[2].rank_value, z[3].rank_value, z[4].rank_value]
  end

  nil
end

#four_of_a_kind_rateObject



108
109
110
111
112
113
114
115
116
# File 'lib/poker_trump/cards.rb', line 108

def four_of_a_kind_rate
  a = sort_by_rank.to_s.match(/(.). \1. \1. \1./)

  if a
    b = (a.pre_match + a.post_match).match(/(\S)/).to_s

    [8, PokerTrump::Card::RANK_VALUE[a[1]], PokerTrump::Card::RANK_VALUE[b.to_s], 0, 0, 0]
  end
end

#full_house_rateObject



118
119
120
121
122
123
124
125
126
127
# File 'lib/poker_trump/cards.rb', line 118

def full_house_rate
  case sort_by_rank.to_s
  when /(.). \1. \1. (.*)(.). \3./
    [7, PokerTrump::Card::RANK_VALUE[Regexp.last_match(1)], PokerTrump::Card::RANK_VALUE[Regexp.last_match(3)], 0,
     0, 0]
  when /((.). \2.) (.*)((.). \5. \5.)/
    [7, PokerTrump::Card::RANK_VALUE[Regexp.last_match(5)], PokerTrump::Card::RANK_VALUE[Regexp.last_match(2)], 0,
     0, 0]
  end
end

#group_by_suitObject



90
91
92
# File 'lib/poker_trump/cards.rb', line 90

def group_by_suit
  @group_by_suit ||= group_by(&:suit).each_with_object({}) { |(k, v), h| h[k] = self.class.new(v) }
end

#high_card_rateObject



201
202
203
204
205
206
# File 'lib/poker_trump/cards.rb', line 201

def high_card_rate
  arranged_hand = sort_by_rank.to_s

  [1, PokerTrump::Card::RANK_VALUE[arranged_hand[0]], PokerTrump::Card::RANK_VALUE[arranged_hand[3]],
   PokerTrump::Card::RANK_VALUE[arranged_hand[6]], PokerTrump::Card::RANK_VALUE[arranged_hand[9]], PokerTrump::Card::RANK_VALUE[arranged_hand[12]]]
end

#one_pair_rateObject



190
191
192
193
194
195
196
197
198
199
# File 'lib/poker_trump/cards.rb', line 190

def one_pair_rate
  md = sort_by_rank.to_s.match(/(.). \1./)

  if md
    arranged_hand = (md.pre_match + ' ' + md.post_match).strip.squeeze(' ')

    [2, PokerTrump::Card::RANK_VALUE[md[1]], PokerTrump::Card::RANK_VALUE[arranged_hand[0]],
     PokerTrump::Card::RANK_VALUE[arranged_hand[3]], PokerTrump::Card::RANK_VALUE[arranged_hand[6]], 0]
  end
end

#royal_flush_rateObject



94
95
96
# File 'lib/poker_trump/cards.rb', line 94

def royal_flush_rate
  [10, 0, 0, 0, 0, 0] if /A(.) K\1 Q\1 J\1 T\1/.match?(sort_by_suit.to_s)
end

#scoreObject



208
209
210
# File 'lib/poker_trump/cards.rb', line 208

def score
  @score ||= royal_flush_rate || straight_flush_rate || four_of_a_kind_rate || full_house_rate || flush_rate || straight_rate || three_of_a_kind_rate || two_pair_rate || one_pair_rate || high_card_rate
end

#sort_by_rankObject



82
83
84
# File 'lib/poker_trump/cards.rb', line 82

def sort_by_rank
  @sort_by_rank ||= self.class.new(sort_by { |card| [card.rank_value, card.suit] }.reverse)
end

#sort_by_suitObject



78
79
80
# File 'lib/poker_trump/cards.rb', line 78

def sort_by_suit
  self.class.new(sort_by { |card| [card.suit, card.rank_value] }.reverse)
end

#straight_flush_rateObject



98
99
100
101
102
103
104
105
106
# File 'lib/poker_trump/cards.rb', line 98

def straight_flush_rate
  group_by_suit.each do |_k, v|
    next if v.size < 5

    a = v.straight_rate
    return [9, a[1], a[2], a[3], a[4], a[5]] if a
  end
  nil
end

#straight_rateObject



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/poker_trump/cards.rb', line 140

def straight_rate
  a = sort_by_rank.to_s.match(/(?<_A>A.+K.+Q.+J.+T)|(?<_K>K.+Q.+J.+T.+9)|(?<_Q>Q.+J.+T.+9.+8)|(?<_J>J.+T.+9.+8.+7)|(?<_T>T.+9.+8.+7.+6)|(?<_9>9.+8.+7.+6.+5)|(?<_8>8.+7.+6.+5.+4)|(?<_7>7.+6.+5.+4.+3)|(?<_6>6.+5.+4.+3.+2)|(?<_5>A.+5.+4.+3.+2)/)

  if a
    case
    when a.send(:[], :_A)
      [5, *PokerTrump::Card::RANK_VALUE.values_at('A', 'K', 'Q', 'J', 'T')]
    when a.send(:[], :_K)
      [5, *PokerTrump::Card::RANK_VALUE.values_at('K', 'Q', 'J', 'T', '9')]
    when a.send(:[], :_Q)
      [5, *PokerTrump::Card::RANK_VALUE.values_at('Q', 'J', 'T', '9', '8')]
    when a.send(:[], :_J)
      [5, *PokerTrump::Card::RANK_VALUE.values_at('J', 'T', '9', '8', '7')]
    when a.send(:[], :_T)
      [5, *PokerTrump::Card::RANK_VALUE.values_at('T', '9', '8', '7', '6')]
    when a.send(:[], :_9)
      [5, *PokerTrump::Card::RANK_VALUE.values_at('9', '8', '7', '6', '5')]
    when a.send(:[], :_8)
      [5, *PokerTrump::Card::RANK_VALUE.values_at('8', '7', '6', '5', '4')]
    when a.send(:[], :_7)
      [5, *PokerTrump::Card::RANK_VALUE.values_at('7', '6', '5', '4', '3')]
    when a.send(:[], :_6)
      [5, *PokerTrump::Card::RANK_VALUE.values_at('6', '5', '4', '3', '2')]
    when a.send(:[], :_5)
      [5, *PokerTrump::Card::RANK_VALUE.values_at('5', '4', '3', '2', 'A')]
    end
  end
end

#three_of_a_kind_rateObject



169
170
171
172
173
174
175
176
177
178
# File 'lib/poker_trump/cards.rb', line 169

def three_of_a_kind_rate
  md = sort_by_rank.to_s.match(/(.). \1. \1./)

  if md
    arranged_hand = (md.pre_match + md.post_match).strip.squeeze(' ')

    [4, PokerTrump::Card::RANK_VALUE[md[1]], PokerTrump::Card::RANK_VALUE[arranged_hand[0]],
     PokerTrump::Card::RANK_VALUE[arranged_hand[3]], 0, 0]
  end
end

#to_sObject



86
87
88
# File 'lib/poker_trump/cards.rb', line 86

def to_s
  map(&:to_s).join(' ')
end

#two_pair_rateObject



180
181
182
183
184
185
186
187
188
# File 'lib/poker_trump/cards.rb', line 180

def two_pair_rate
  md = sort_by_rank.to_s.match(/(.). \1.(.*?) (.). \3./)

  if md
    arranged_hand = (md.pre_match + ' ' + md[2] + ' ' + md.post_match).strip.squeeze(' ')
    [3, PokerTrump::Card::RANK_VALUE[md[1]], PokerTrump::Card::RANK_VALUE[md[3]],
     PokerTrump::Card::RANK_VALUE[arranged_hand[0]], 0, 0]
  end
end