Решение на Четвърта задача от Йоан Динков

Обратно към всички решения

Към профила на Йоан Динков

Резултати

  • 5 точки от тестове
  • 0 бонус точки
  • 5 точки общо
  • 47 успешни тест(а)
  • 10 неуспешни тест(а)

Код

class Card
def initialize(rank, suit, position = 0)
@rank = rank
@suit = suit
@position = position
end
attr_accessor :position
attr_reader :suit
attr_reader :rank
def <=>(other)
comparison = other.suit <=> suit
if comparison.zero? && position.zero?
comparison = other.rank.to_s <=> rank.to_s
elsif comparison.zero?
comparison = other.position <=> position
end
comparison
end
def ==(other)
(self <=> other).zero?
end
def to_s
"#{rank.to_s.capitalize} of #{suit.to_s.capitalize}"
end
end
class Deck
include Enumerable
def initialize(cards = nil, ranks: nil, hand_type: nil, hand_size: 52)
@hand_type = hand_type
@hand_size = hand_size
ranks ||= [2, 3, 4, 5, 6, 7, 8, 9, 10, :jack, :queen, :king, :ace]
@cards = cards || create_new_deck(ranks)
update_ranks(ranks)
end
def size
@cards.count
end
def top_card
@cards.first
end
def draw_top_card
@cards.shift
end
def draw_bottom_card
@cards.pop
end
def bottom_card
@cards.last
end
def shuffle
@cards.shuffle!
end
def sort
@cards.sort!
end
def deal
@hand_type.new(@cards.shift(@hand_size))
end
def each
@cards.each { |card| yield card }
end
def to_s
@cards.each(&:to_s)
end
private
def create_new_deck(ranks)
suits = %i(spades hearts diamonds clubs)
suits.product(ranks.to_a).shuffle.map do |product|
suit, rank = product
Card.new(rank, suit)
end
end
def update_ranks(ranks)
@cards.each do |card|
card.position = ranks.index(card.rank) + 1
end
end
end
class Hand
def initialize(cards = nil)
@cards = cards
end
def size
@cards.count
end
private
def deck_contains_pair?(suit)
deck_contains?(:queen, suit) && deck_contains?(:king, suit)
end
def deck_contains?(rank, suit)
@cards.include? Card.new(rank, suit)
end
end
class WarHand < Hand
def play_card
@cards.shift
end
def allow_face_up?
size <= 3
end
end
class WarDeck < Deck
def initialize(cards = nil)
super(cards, hand_size: 26,
hand_type: WarHand)
end
end
class BeloteHand < Hand
def highest_of_suit(suit)
@cards.select { |card| card.suit == suit }.sort.first
end
def belote?
%i(spades hearts diamonds clubs).each do |suit|
return true if deck_contains_pair? suit
end
false
end
def tierce?
consecutive?(3) || false
end
def quarte?
consecutive?(4) || false
end
def quint?
consecutive?(5) || false
end
def carre_of_jacks?
carre? :jack
end
def carre_of_nines?
carre? '9'
end
def carre_of_aces?
carre? :ace
end
private
def carre?(type)
@cards.count { |card| card.rank == type } == 4
end
def consecutive?(count)
@cards.group_by(&:suit).each do |_, cards|
positions = cards.each.map(&:position)
return true if positions
.sort
.each_cons(count)
.chunk{|a,b| a.succ == b || nil}.to_a.length > 0
end
false
end
end
class BeloteDeck < Deck
def initialize(cards = nil)
super(cards, hand_size: 8,
ranks: [7, 8, 9, :jack, :queen, :king, 10, :ace],
hand_type: BeloteHand)
end
end
class SixtySixHand < Hand
def twenty?(trump_suit)
no_trump_suits = [:spades, :hearts, :diamonds, :clubs] - [trump_suit]
has_twenty = false
no_trump_suits.each do |suit|
has_twenty = true if deck_contains_pair?(suit)
end
has_twenty
end
def forty?(trump_suit)
deck_contains_pair?(trump_suit)
end
end
class SixtySixDeck < Deck
def initialize(cards = nil)
super(cards, hand_size: 6,
ranks: [9, :jack, :queen, :king, 10, :ace],
hand_type: SixtySixHand)
end
end

Лог от изпълнението

....F......F.....F......F..FF..........F....F......F..F..

Failures:

  1) WarDeck behaves like a deck fills the deck if no initialize parameters are given
     Failure/Error: expect(deck.to_a).to match_array all_available_cards
       expected collection contained:  [#<Card:0x007f7d005bf778 @rank=:queen, @suit=:spades, @position=0>, #<Card:0x007f7d005bf750 @rank=:king, @suit=:spades, @position=0>, #<Card:0x007f7d005bf7a0 @rank=:jack, @suit=:spades, @position=0>, #<Card:0x007f7d005bf728 @rank=:ace, @suit=:spades, @position=0>, #<Card:0x007f7d005bf7f0 @rank=9, @suit=:spades, @position=0>, #<Card:0x007f7d005bf818 @rank=8, @suit=:spades, @position=0>, #<Card:0x007f7d005bf840 @rank=7, @suit=:spades, @position=0>, #<Card:0x007f7d005bf890 @rank=6, @suit=:spades, @position=0>, #<Card:0x007f7d005bf8e0 @rank=5, @suit=:spades, @position=0>, #<Card:0x007f7d005bf908 @rank=4, @suit=:spades, @position=0>, #<Card:0x007f7d005bf930 @rank=3, @suit=:spades, @position=0>, #<Card:0x007f7d005bf958 @rank=2, @suit=:spades, @position=0>, #<Card:0x007f7d005bf7c8 @rank=10, @suit=:spades, @position=0>, #<Card:0x007f7d005bf9f8 @rank=:queen, @suit=:hearts, @position=0>, #<Card:0x007f7d005bf9a8 @rank=:king, @suit=:hearts, @position=0>, #<Card:0x007f7d005bfa20 @rank=:jack, @suit=:hearts, @position=0>, #<Card:0x007f7d005bf980 @rank=:ace, @suit=:hearts, @position=0>, #<Card:0x007f7d005bfa98 @rank=9, @suit=:hearts, @position=0>, #<Card:0x007f7d005bfae8 @rank=8, @suit=:hearts, @position=0>, #<Card:0x007f7d005bfb10 @rank=7, @suit=:hearts, @position=0>, #<Card:0x007f7d005bfb38 @rank=6, @suit=:hearts, @position=0>, #<Card:0x007f7d005bfb88 @rank=5, @suit=:hearts, @position=0>, #<Card:0x007f7d005bfbb0 @rank=4, @suit=:hearts, @position=0>, #<Card:0x007f7d005bfbd8 @rank=3, @suit=:hearts, @position=0>, #<Card:0x007f7d005bfc00 @rank=2, @suit=:hearts, @position=0>, #<Card:0x007f7d005bfa70 @rank=10, @suit=:hearts, @position=0>, #<Card:0x007f7d005bfca0 @rank=:queen, @suit=:diamonds, @position=0>, #<Card:0x007f7d005bfc78 @rank=:king, @suit=:diamonds, @position=0>, #<Card:0x007f7d005bfcc8 @rank=:jack, @suit=:diamonds, @position=0>, #<Card:0x007f7d005bfc28 @rank=:ace, @suit=:diamonds, @position=0>, #<Card:0x007f7d005bfd90 @rank=9, @suit=:diamonds, @position=0>, #<Card:0x007f7d005bfde0 @rank=8, @suit=:diamonds, @position=0>, #<Card:0x007f7d005bfe08 @rank=7, @suit=:diamonds, @position=0>, #<Card:0x007f7d005bfe30 @rank=6, @suit=:diamonds, @position=0>, #<Card:0x007f7d005bfe80 @rank=5, @suit=:diamonds, @position=0>, #<Card:0x007f7d005bfea8 @rank=4, @suit=:diamonds, @position=0>, #<Card:0x007f7d005bfed0 @rank=3, @suit=:diamonds, @position=0>, #<Card:0x007f7d005bff20 @rank=2, @suit=:diamonds, @position=0>, #<Card:0x007f7d005bfcf0 @rank=10, @suit=:diamonds, @position=0>, #<Card:0x007f7d005bff98 @rank=:queen, @suit=:clubs, @position=0>, #<Card:0x007f7d005bff70 @rank=:king, @suit=:clubs, @position=0>, #<Card:0x007f7d005c0948 @rank=:jack, @suit=:clubs, @position=0>, #<Card:0x007f7d005bff48 @rank=:ace, @suit=:clubs, @position=0>, #<Card:0x007f7d005c0010 @rank=9, @suit=:clubs, @position=0>, #<Card:0x007f7d005c0060 @rank=8, @suit=:clubs, @position=0>, #<Card:0x007f7d005c00b0 @rank=7, @suit=:clubs, @position=0>, #<Card:0x007f7d005c00d8 @rank=6, @suit=:clubs, @position=0>, #<Card:0x007f7d005c0100 @rank=5, @suit=:clubs, @position=0>, #<Card:0x007f7d005c0128 @rank=4, @suit=:clubs, @position=0>, #<Card:0x007f7d005c0150 @rank=3, @suit=:clubs, @position=0>, #<Card:0x007f7d005c0178 @rank=2, @suit=:clubs, @position=0>, #<Card:0x007f7d005c03a8 @rank=10, @suit=:clubs, @position=0>]
       actual collection contained:    [#<Card:0x007f7d005c15a0 @rank=:ace, @suit=:spades, @position=13>, #<Card:0x007f7d005c1438 @rank=:king, @suit=:spades, @position=12>, #<Card:0x007f7d005c1690 @rank=:queen, @suit=:spades, @position=11>, #<Card:0x007f7d005c12d0 @rank=:jack, @suit=:spades, @position=10>, #<Card:0x007f7d005c1e10 @rank=10, @suit=:spades, @position=9>, #<Card:0x007f7d005c1258 @rank=9, @suit=:spades, @position=8>, #<Card:0x007f7d005c19d8 @rank=8, @suit=:spades, @position=7>, #<Card:0x007f7d005c1bb8 @rank=7, @suit=:spades, @position=6>, #<Card:0x007f7d005c1cf8 @rank=6, @suit=:spades, @position=5>, #<Card:0x007f7d005c1eb0 @rank=5, @suit=:spades, @position=4>, #<Card:0x007f7d005c16b8 @rank=4, @suit=:spades, @position=3>, #<Card:0x007f7d005c2018 @rank=3, @suit=:spades, @position=2>, #<Card:0x007f7d005c2090 @rank=2, @suit=:spades, @position=1>, #<Card:0x007f7d005c1550 @rank=:ace, @suit=:hearts, @position=13>, #<Card:0x007f7d005c1a78 @rank=:king, @suit=:hearts, @position=12>, #<Card:0x007f7d005c1230 @rank=:queen, @suit=:hearts, @position=11>, #<Card:0x007f7d005c1b40 @rank=:jack, @suit=:hearts, @position=10>, #<Card:0x007f7d005c1b18 @rank=10, @suit=:hearts, @position=9>, #<Card:0x007f7d005c1f28 @rank=9, @suit=:hearts, @position=8>, #<Card:0x007f7d005c1780 @rank=8, @suit=:hearts, @position=7>, #<Card:0x007f7d005c1b90 @rank=7, @suit=:hearts, @position=6>, #<Card:0x007f7d005c2040 @rank=6, @suit=:hearts, @position=5>, #<Card:0x007f7d005c13c0 @rank=5, @suit=:hearts, @position=4>, #<Card:0x007f7d005c15f0 @rank=4, @suit=:hearts, @position=3>, #<Card:0x007f7d005c1c58 @rank=3, @suit=:hearts, @position=2>, #<Card:0x007f7d005c1910 @rank=2, @suit=:hearts, @position=1>, #<Card:0x007f7d005c18e8 @rank=:ace, @suit=:diamonds, @position=13>, #<Card:0x007f7d005c1370 @rank=:king, @suit=:diamonds, @position=12>, #<Card:0x007f7d005c1578 @rank=:queen, @suit=:diamonds, @position=11>, #<Card:0x007f7d005c1668 @rank=:jack, @suit=:diamonds, @position=10>, #<Card:0x007f7d005c1fa0 @rank=10, @suit=:diamonds, @position=9>, #<Card:0x007f7d005c1500 @rank=9, @suit=:diamonds, @position=8>, #<Card:0x007f7d005c1a28 @rank=8, @suit=:diamonds, @position=7>, #<Card:0x007f7d005c1f00 @rank=7, @suit=:diamonds, @position=6>, #<Card:0x007f7d005c1e38 @rank=6, @suit=:diamonds, @position=5>, #<Card:0x007f7d005c20e0 @rank=5, @suit=:diamonds, @position=4>, #<Card:0x007f7d005c1e88 @rank=4, @suit=:diamonds, @position=3>, #<Card:0x007f7d005c1398 @rank=3, @suit=:diamonds, @position=2>, #<Card:0x007f7d005c1ed8 @rank=2, @suit=:diamonds, @position=1>, #<Card:0x007f7d005c1ff0 @rank=:ace, @suit=:clubs, @position=13>, #<Card:0x007f7d005c1320 @rank=:king, @suit=:clubs, @position=12>, #<Card:0x007f7d005c18c0 @rank=:queen, @suit=:clubs, @position=11>, #<Card:0x007f7d005c1e60 @rank=:jack, @suit=:clubs, @position=10>, #<Card:0x007f7d005c1de8 @rank=10, @suit=:clubs, @position=9>, #<Card:0x007f7d005c1960 @rank=9, @suit=:clubs, @position=8>, #<Card:0x007f7d005c1aa0 @rank=8, @suit=:clubs, @position=7>, #<Card:0x007f7d005c1618 @rank=7, @suit=:clubs, @position=6>, #<Card:0x007f7d005c1758 @rank=6, @suit=:clubs, @position=5>, #<Card:0x007f7d005c2158 @rank=5, @suit=:clubs, @position=4>, #<Card:0x007f7d005c1410 @rank=4, @suit=:clubs, @position=3>, #<Card:0x007f7d005c14b0 @rank=3, @suit=:clubs, @position=2>, #<Card:0x007f7d005c17d0 @rank=2, @suit=:clubs, @position=1>]
       the extra elements were:        [#<Card:0x007f7d005c15a0 @rank=:ace, @suit=:spades, @position=13>, #<Card:0x007f7d005c1438 @rank=:king, @suit=:spades, @position=12>, #<Card:0x007f7d005c1690 @rank=:queen, @suit=:spades, @position=11>, #<Card:0x007f7d005c12d0 @rank=:jack, @suit=:spades, @position=10>, #<Card:0x007f7d005c1e10 @rank=10, @suit=:spades, @position=9>, #<Card:0x007f7d005c1258 @rank=9, @suit=:spades, @position=8>, #<Card:0x007f7d005c19d8 @rank=8, @suit=:spades, @position=7>, #<Card:0x007f7d005c1bb8 @rank=7, @suit=:spades, @position=6>, #<Card:0x007f7d005c1cf8 @rank=6, @suit=:spades, @position=5>, #<Card:0x007f7d005c1eb0 @rank=5, @suit=:spades, @position=4>, #<Card:0x007f7d005c16b8 @rank=4, @suit=:spades, @position=3>, #<Card:0x007f7d005c2018 @rank=3, @suit=:spades, @position=2>, #<Card:0x007f7d005c2090 @rank=2, @suit=:spades, @position=1>, #<Card:0x007f7d005c1550 @rank=:ace, @suit=:hearts, @position=13>, #<Card:0x007f7d005c1a78 @rank=:king, @suit=:hearts, @position=12>, #<Card:0x007f7d005c1230 @rank=:queen, @suit=:hearts, @position=11>, #<Card:0x007f7d005c1b40 @rank=:jack, @suit=:hearts, @position=10>, #<Card:0x007f7d005c1b18 @rank=10, @suit=:hearts, @position=9>, #<Card:0x007f7d005c1f28 @rank=9, @suit=:hearts, @position=8>, #<Card:0x007f7d005c1780 @rank=8, @suit=:hearts, @position=7>, #<Card:0x007f7d005c1b90 @rank=7, @suit=:hearts, @position=6>, #<Card:0x007f7d005c2040 @rank=6, @suit=:hearts, @position=5>, #<Card:0x007f7d005c13c0 @rank=5, @suit=:hearts, @position=4>, #<Card:0x007f7d005c15f0 @rank=4, @suit=:hearts, @position=3>, #<Card:0x007f7d005c1c58 @rank=3, @suit=:hearts, @position=2>, #<Card:0x007f7d005c1910 @rank=2, @suit=:hearts, @position=1>, #<Card:0x007f7d005c18e8 @rank=:ace, @suit=:diamonds, @position=13>, #<Card:0x007f7d005c1370 @rank=:king, @suit=:diamonds, @position=12>, #<Card:0x007f7d005c1578 @rank=:queen, @suit=:diamonds, @position=11>, #<Card:0x007f7d005c1668 @rank=:jack, @suit=:diamonds, @position=10>, #<Card:0x007f7d005c1fa0 @rank=10, @suit=:diamonds, @position=9>, #<Card:0x007f7d005c1500 @rank=9, @suit=:diamonds, @position=8>, #<Card:0x007f7d005c1a28 @rank=8, @suit=:diamonds, @position=7>, #<Card:0x007f7d005c1f00 @rank=7, @suit=:diamonds, @position=6>, #<Card:0x007f7d005c1e38 @rank=6, @suit=:diamonds, @position=5>, #<Card:0x007f7d005c20e0 @rank=5, @suit=:diamonds, @position=4>, #<Card:0x007f7d005c1e88 @rank=4, @suit=:diamonds, @position=3>, #<Card:0x007f7d005c1398 @rank=3, @suit=:diamonds, @position=2>, #<Card:0x007f7d005c1ed8 @rank=2, @suit=:diamonds, @position=1>, #<Card:0x007f7d005c1ff0 @rank=:ace, @suit=:clubs, @position=13>, #<Card:0x007f7d005c1320 @rank=:king, @suit=:clubs, @position=12>, #<Card:0x007f7d005c18c0 @rank=:queen, @suit=:clubs, @position=11>, #<Card:0x007f7d005c1e60 @rank=:jack, @suit=:clubs, @position=10>, #<Card:0x007f7d005c1de8 @rank=10, @suit=:clubs, @position=9>, #<Card:0x007f7d005c1960 @rank=9, @suit=:clubs, @position=8>, #<Card:0x007f7d005c1aa0 @rank=8, @suit=:clubs, @position=7>, #<Card:0x007f7d005c1618 @rank=7, @suit=:clubs, @position=6>, #<Card:0x007f7d005c1758 @rank=6, @suit=:clubs, @position=5>, #<Card:0x007f7d005c2158 @rank=5, @suit=:clubs, @position=4>, #<Card:0x007f7d005c1410 @rank=4, @suit=:clubs, @position=3>, #<Card:0x007f7d005c14b0 @rank=3, @suit=:clubs, @position=2>, #<Card:0x007f7d005c17d0 @rank=2, @suit=:clubs, @position=1>]
     Shared Example Group: "a deck" called from /tmp/d20151112-27349-1t5b6kg/spec.rb:140
     # /tmp/d20151112-27349-1t5b6kg/spec.rb:18:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  2) WarDeck behaves like a deck #to_s returns the names of the cards, each on its own line
     Failure/Error: expect(small_deck.to_s.strip).to eq "Ace of Spades\n9 of Clubs"
     NoMethodError:
       undefined method `strip' for #<Array:0x007f7d014677a8>
     Shared Example Group: "a deck" called from /tmp/d20151112-27349-1t5b6kg/spec.rb:140
     # /tmp/d20151112-27349-1t5b6kg/spec.rb:68:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  3) BeloteDeck behaves like a deck fills the deck if no initialize parameters are given
     Failure/Error: expect(deck.to_a).to match_array all_available_cards
       expected collection contained:  [#<Card:0x007f7d013ed610 @rank=:queen, @suit=:spades, @position=0>, #<Card:0x007f7d013ed5c0 @rank=:king, @suit=:spades, @position=0>, #<Card:0x007f7d013ed6d8 @rank=:jack, @suit=:spades, @position=0>, #<Card:0x007f7d013ed570 @rank=:ace, @suit=:spades, @position=0>, #<Card:0x007f7d013ed700 @rank=9, @suit=:spades, @position=0>, #<Card:0x007f7d013ed728 @rank=8, @suit=:spades, @position=0>, #<Card:0x007f7d013ed750 @rank=7, @suit=:spades, @position=0>, #<Card:0x007f7d013ed598 @rank=10, @suit=:spades, @position=0>, #<Card:0x007f7d013ed818 @rank=:queen, @suit=:hearts, @position=0>, #<Card:0x007f7d013ed7f0 @rank=:king, @suit=:hearts, @position=0>, #<Card:0x007f7d013ed840 @rank=:jack, @suit=:hearts, @position=0>, #<Card:0x007f7d013ed7a0 @rank=:ace, @suit=:hearts, @position=0>, #<Card:0x007f7d013ed868 @rank=9, @suit=:hearts, @position=0>, #<Card:0x007f7d013ed890 @rank=8, @suit=:hearts, @position=0>, #<Card:0x007f7d013ed8b8 @rank=7, @suit=:hearts, @position=0>, #<Card:0x007f7d013ed7c8 @rank=10, @suit=:hearts, @position=0>, #<Card:0x007f7d013eda20 @rank=:queen, @suit=:diamonds, @position=0>, #<Card:0x007f7d013ed9f8 @rank=:king, @suit=:diamonds, @position=0>, #<Card:0x007f7d013eda48 @rank=:jack, @suit=:diamonds, @position=0>, #<Card:0x007f7d013ed8e0 @rank=:ace, @suit=:diamonds, @position=0>, #<Card:0x007f7d013eda98 @rank=9, @suit=:diamonds, @position=0>, #<Card:0x007f7d013edae8 @rank=8, @suit=:diamonds, @position=0>, #<Card:0x007f7d013edbd8 @rank=7, @suit=:diamonds, @position=0>, #<Card:0x007f7d013ed9d0 @rank=10, @suit=:diamonds, @position=0>, #<Card:0x007f7d013edd40 @rank=:queen, @suit=:clubs, @position=0>, #<Card:0x007f7d013edcf0 @rank=:king, @suit=:clubs, @position=0>, #<Card:0x007f7d013edd68 @rank=:jack, @suit=:clubs, @position=0>, #<Card:0x007f7d013edc28 @rank=:ace, @suit=:clubs, @position=0>, #<Card:0x007f7d013edd90 @rank=9, @suit=:clubs, @position=0>, #<Card:0x007f7d013eddb8 @rank=8, @suit=:clubs, @position=0>, #<Card:0x007f7d013edef8 @rank=7, @suit=:clubs, @position=0>, #<Card:0x007f7d013edca0 @rank=10, @suit=:clubs, @position=0>]
       actual collection contained:    [#<Card:0x007f7d013eeee8 @rank=:ace, @suit=:spades, @position=8>, #<Card:0x007f7d013ef078 @rank=10, @suit=:spades, @position=7>, #<Card:0x007f7d013eec90 @rank=:king, @suit=:spades, @position=6>, #<Card:0x007f7d013ee9e8 @rank=:queen, @suit=:spades, @position=5>, #<Card:0x007f7d013eea60 @rank=:jack, @suit=:spades, @position=4>, #<Card:0x007f7d013eead8 @rank=9, @suit=:spades, @position=3>, #<Card:0x007f7d013eeda8 @rank=8, @suit=:spades, @position=2>, #<Card:0x007f7d013eef88 @rank=7, @suit=:spades, @position=1>, #<Card:0x007f7d013eec68 @rank=:ace, @suit=:hearts, @position=8>, #<Card:0x007f7d013eec18 @rank=10, @suit=:hearts, @position=7>, #<Card:0x007f7d013eee98 @rank=:king, @suit=:hearts, @position=6>, #<Card:0x007f7d013eeec0 @rank=:queen, @suit=:hearts, @position=5>, #<Card:0x007f7d013eed30 @rank=:jack, @suit=:hearts, @position=4>, #<Card:0x007f7d013eeba0 @rank=9, @suit=:hearts, @position=3>, #<Card:0x007f7d013eed08 @rank=8, @suit=:hearts, @position=2>, #<Card:0x007f7d013eeab0 @rank=7, @suit=:hearts, @position=1>, #<Card:0x007f7d013ee9c0 @rank=:ace, @suit=:diamonds, @position=8>, #<Card:0x007f7d013ef0c8 @rank=10, @suit=:diamonds, @position=7>, #<Card:0x007f7d013eefb0 @rank=:king, @suit=:diamonds, @position=6>, #<Card:0x007f7d013eea88 @rank=:queen, @suit=:diamonds, @position=5>, #<Card:0x007f7d013ee998 @rank=:jack, @suit=:diamonds, @position=4>, #<Card:0x007f7d013eec40 @rank=9, @suit=:diamonds, @position=3>, #<Card:0x007f7d013eef38 @rank=8, @suit=:diamonds, @position=2>, #<Card:0x007f7d013eef60 @rank=7, @suit=:diamonds, @position=1>, #<Card:0x007f7d013eed58 @rank=:ace, @suit=:clubs, @position=8>, #<Card:0x007f7d013eebc8 @rank=10, @suit=:clubs, @position=7>, #<Card:0x007f7d013ef0a0 @rank=:king, @suit=:clubs, @position=6>, #<Card:0x007f7d013eecb8 @rank=:queen, @suit=:clubs, @position=5>, #<Card:0x007f7d013eefd8 @rank=:jack, @suit=:clubs, @position=4>, #<Card:0x007f7d013eea38 @rank=9, @suit=:clubs, @position=3>, #<Card:0x007f7d013eece0 @rank=8, @suit=:clubs, @position=2>, #<Card:0x007f7d013eeb78 @rank=7, @suit=:clubs, @position=1>]
       the extra elements were:        [#<Card:0x007f7d013eeee8 @rank=:ace, @suit=:spades, @position=8>, #<Card:0x007f7d013ef078 @rank=10, @suit=:spades, @position=7>, #<Card:0x007f7d013eec90 @rank=:king, @suit=:spades, @position=6>, #<Card:0x007f7d013ee9e8 @rank=:queen, @suit=:spades, @position=5>, #<Card:0x007f7d013eea60 @rank=:jack, @suit=:spades, @position=4>, #<Card:0x007f7d013eead8 @rank=9, @suit=:spades, @position=3>, #<Card:0x007f7d013eeda8 @rank=8, @suit=:spades, @position=2>, #<Card:0x007f7d013eef88 @rank=7, @suit=:spades, @position=1>, #<Card:0x007f7d013eec68 @rank=:ace, @suit=:hearts, @position=8>, #<Card:0x007f7d013eec18 @rank=10, @suit=:hearts, @position=7>, #<Card:0x007f7d013eee98 @rank=:king, @suit=:hearts, @position=6>, #<Card:0x007f7d013eeec0 @rank=:queen, @suit=:hearts, @position=5>, #<Card:0x007f7d013eed30 @rank=:jack, @suit=:hearts, @position=4>, #<Card:0x007f7d013eeba0 @rank=9, @suit=:hearts, @position=3>, #<Card:0x007f7d013eed08 @rank=8, @suit=:hearts, @position=2>, #<Card:0x007f7d013eeab0 @rank=7, @suit=:hearts, @position=1>, #<Card:0x007f7d013ee9c0 @rank=:ace, @suit=:diamonds, @position=8>, #<Card:0x007f7d013ef0c8 @rank=10, @suit=:diamonds, @position=7>, #<Card:0x007f7d013eefb0 @rank=:king, @suit=:diamonds, @position=6>, #<Card:0x007f7d013eea88 @rank=:queen, @suit=:diamonds, @position=5>, #<Card:0x007f7d013ee998 @rank=:jack, @suit=:diamonds, @position=4>, #<Card:0x007f7d013eec40 @rank=9, @suit=:diamonds, @position=3>, #<Card:0x007f7d013eef38 @rank=8, @suit=:diamonds, @position=2>, #<Card:0x007f7d013eef60 @rank=7, @suit=:diamonds, @position=1>, #<Card:0x007f7d013eed58 @rank=:ace, @suit=:clubs, @position=8>, #<Card:0x007f7d013eebc8 @rank=10, @suit=:clubs, @position=7>, #<Card:0x007f7d013ef0a0 @rank=:king, @suit=:clubs, @position=6>, #<Card:0x007f7d013eecb8 @rank=:queen, @suit=:clubs, @position=5>, #<Card:0x007f7d013eefd8 @rank=:jack, @suit=:clubs, @position=4>, #<Card:0x007f7d013eea38 @rank=9, @suit=:clubs, @position=3>, #<Card:0x007f7d013eece0 @rank=8, @suit=:clubs, @position=2>, #<Card:0x007f7d013eeb78 @rank=7, @suit=:clubs, @position=1>]
     Shared Example Group: "a deck" called from /tmp/d20151112-27349-1t5b6kg/spec.rb:191
     # /tmp/d20151112-27349-1t5b6kg/spec.rb:18:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  4) BeloteDeck behaves like a deck #to_s returns the names of the cards, each on its own line
     Failure/Error: expect(small_deck.to_s.strip).to eq "Ace of Spades\n9 of Clubs"
     NoMethodError:
       undefined method `strip' for #<Array:0x007f7d0130c778>
     Shared Example Group: "a deck" called from /tmp/d20151112-27349-1t5b6kg/spec.rb:191
     # /tmp/d20151112-27349-1t5b6kg/spec.rb:68:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  5) BeloteDeck hand #highest_of_suit returns the strongest card of the specified suit
     Failure/Error: expect(hand.highest_of_suit(:clubs)).to eq Card.new(:ace, :clubs)
       
       expected: #<Card:0x007f7d012d7708 @rank=:ace, @suit=:clubs, @position=0>
            got: #<Card:0x007f7d012d7b18 @rank=:ace, @suit=:clubs, @position=8>
       
       (compared using ==)
       
       Diff:
       @@ -1,2 +1,2 @@
       -#<Card:0x007f7d012d7708 @position=0, @rank=:ace, @suit=:clubs>
       +#<Card:0x007f7d012d7b18 @position=8, @rank=:ace, @suit=:clubs>
     # /tmp/d20151112-27349-1t5b6kg/spec.rb:232:in `block (4 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  6) BeloteDeck hand #belote? returns true if there is a king and a queen of the same suit
     Failure/Error: expect(hand.belote?).to be true
       
       expected #<TrueClass:20> => true
            got #<FalseClass:0> => false
       
       Compared using equal?, which compares object identity,
       but expected and actual are not the same object. Use
       `expect(actual).to eq(expected)` if you don't care about
       object identity in this example.
     # /tmp/d20151112-27349-1t5b6kg/spec.rb:251:in `block (4 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  7) BeloteDeck hand #carre_of_nines? behaves like carre-checking method returns true when there is a carre
     Failure/Error: expect(hand.public_send(method)).to be true
       
       expected #<TrueClass:20> => true
            got #<FalseClass:0> => false
       
       Compared using equal?, which compares object identity,
       but expected and actual are not the same object. Use
       `expect(actual).to eq(expected)` if you don't care about
       object identity in this example.
     Shared Example Group: "carre-checking method" called from /tmp/d20151112-27349-1t5b6kg/spec.rb:390
     # /tmp/d20151112-27349-1t5b6kg/spec.rb:86:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  8) SixtySixDeck behaves like a deck fills the deck if no initialize parameters are given
     Failure/Error: expect(deck.to_a).to match_array all_available_cards
       expected collection contained:  [#<Card:0x007f7d00f7b9d8 @rank=:queen, @suit=:spades, @position=0>, #<Card:0x007f7d00f7b960 @rank=:king, @suit=:spades, @position=0>, #<Card:0x007f7d00f7baa0 @rank=:jack, @suit=:spades, @position=0>, #<Card:0x007f7d00f7b8e8 @rank=:ace, @suit=:spades, @position=0>, #<Card:0x007f7d00f7bac8 @rank=9, @suit=:spades, @position=0>, #<Card:0x007f7d00f7b938 @rank=10, @suit=:spades, @position=0>, #<Card:0x007f7d00f7bc30 @rank=:queen, @suit=:hearts, @position=0>, #<Card:0x007f7d00f7bc08 @rank=:king, @suit=:hearts, @position=0>, #<Card:0x007f7d00f7bca8 @rank=:jack, @suit=:hearts, @position=0>, #<Card:0x007f7d00f7baf0 @rank=:ace, @suit=:hearts, @position=0>, #<Card:0x007f7d00f7be60 @rank=9, @suit=:hearts, @position=0>, #<Card:0x007f7d00f7bbb8 @rank=10, @suit=:hearts, @position=0>, #<Card:0x007f7d00fa9720 @rank=:queen, @suit=:diamonds, @position=0>, #<Card:0x007f7d00fa99f0 @rank=:king, @suit=:diamonds, @position=0>, #<Card:0x007f7d00fa9680 @rank=:jack, @suit=:diamonds, @position=0>, #<Card:0x007f7d00f7bf28 @rank=:ace, @suit=:diamonds, @position=0>, #<Card:0x007f7d00fa9568 @rank=9, @suit=:diamonds, @position=0>, #<Card:0x007f7d00fa9ec8 @rank=10, @suit=:diamonds, @position=0>, #<Card:0x007f7d00fa8eb0 @rank=:queen, @suit=:clubs, @position=0>, #<Card:0x007f7d00fa9310 @rank=:king, @suit=:clubs, @position=0>, #<Card:0x007f7d00fa8758 @rank=:jack, @suit=:clubs, @position=0>, #<Card:0x007f7d00fa94c8 @rank=:ace, @suit=:clubs, @position=0>, #<Card:0x007f7d00fa85a0 @rank=9, @suit=:clubs, @position=0>, #<Card:0x007f7d00fa93d8 @rank=10, @suit=:clubs, @position=0>]
       actual collection contained:    [#<Card:0x007f7d00fa89b0 @rank=:ace, @suit=:spades, @position=6>, #<Card:0x007f7d00fa8960 @rank=10, @suit=:spades, @position=5>, #<Card:0x007f7d00fa89d8 @rank=:king, @suit=:spades, @position=4>, #<Card:0x007f7d00fa8820 @rank=:queen, @suit=:spades, @position=3>, #<Card:0x007f7d00fa8618 @rank=:jack, @suit=:spades, @position=2>, #<Card:0x007f7d00fa8a00 @rank=9, @suit=:spades, @position=1>, #<Card:0x007f7d00fa87f8 @rank=:ace, @suit=:hearts, @position=6>, #<Card:0x007f7d00fa8708 @rank=10, @suit=:hearts, @position=5>, #<Card:0x007f7d00fa8780 @rank=:king, @suit=:hearts, @position=4>, #<Card:0x007f7d00fa8a28 @rank=:queen, @suit=:hearts, @position=3>, #<Card:0x007f7d00fa8988 @rank=:jack, @suit=:hearts, @position=2>, #<Card:0x007f7d00fa8938 @rank=9, @suit=:hearts, @position=1>, #<Card:0x007f7d00fa88e8 @rank=:ace, @suit=:diamonds, @position=6>, #<Card:0x007f7d00fa8668 @rank=10, @suit=:diamonds, @position=5>, #<Card:0x007f7d00fa8ac8 @rank=:king, @suit=:diamonds, @position=4>, #<Card:0x007f7d00fa8a78 @rank=:queen, @suit=:diamonds, @position=3>, #<Card:0x007f7d00fa8870 @rank=:jack, @suit=:diamonds, @position=2>, #<Card:0x007f7d00fa86e0 @rank=9, @suit=:diamonds, @position=1>, #<Card:0x007f7d00fa88c0 @rank=:ace, @suit=:clubs, @position=6>, #<Card:0x007f7d00fa87d0 @rank=10, @suit=:clubs, @position=5>, #<Card:0x007f7d00fa8848 @rank=:king, @suit=:clubs, @position=4>, #<Card:0x007f7d00fa8910 @rank=:queen, @suit=:clubs, @position=3>, #<Card:0x007f7d00fa8898 @rank=:jack, @suit=:clubs, @position=2>, #<Card:0x007f7d00fa86b8 @rank=9, @suit=:clubs, @position=1>]
       the extra elements were:        [#<Card:0x007f7d00fa89b0 @rank=:ace, @suit=:spades, @position=6>, #<Card:0x007f7d00fa8960 @rank=10, @suit=:spades, @position=5>, #<Card:0x007f7d00fa89d8 @rank=:king, @suit=:spades, @position=4>, #<Card:0x007f7d00fa8820 @rank=:queen, @suit=:spades, @position=3>, #<Card:0x007f7d00fa8618 @rank=:jack, @suit=:spades, @position=2>, #<Card:0x007f7d00fa8a00 @rank=9, @suit=:spades, @position=1>, #<Card:0x007f7d00fa87f8 @rank=:ace, @suit=:hearts, @position=6>, #<Card:0x007f7d00fa8708 @rank=10, @suit=:hearts, @position=5>, #<Card:0x007f7d00fa8780 @rank=:king, @suit=:hearts, @position=4>, #<Card:0x007f7d00fa8a28 @rank=:queen, @suit=:hearts, @position=3>, #<Card:0x007f7d00fa8988 @rank=:jack, @suit=:hearts, @position=2>, #<Card:0x007f7d00fa8938 @rank=9, @suit=:hearts, @position=1>, #<Card:0x007f7d00fa88e8 @rank=:ace, @suit=:diamonds, @position=6>, #<Card:0x007f7d00fa8668 @rank=10, @suit=:diamonds, @position=5>, #<Card:0x007f7d00fa8ac8 @rank=:king, @suit=:diamonds, @position=4>, #<Card:0x007f7d00fa8a78 @rank=:queen, @suit=:diamonds, @position=3>, #<Card:0x007f7d00fa8870 @rank=:jack, @suit=:diamonds, @position=2>, #<Card:0x007f7d00fa86e0 @rank=9, @suit=:diamonds, @position=1>, #<Card:0x007f7d00fa88c0 @rank=:ace, @suit=:clubs, @position=6>, #<Card:0x007f7d00fa87d0 @rank=10, @suit=:clubs, @position=5>, #<Card:0x007f7d00fa8848 @rank=:king, @suit=:clubs, @position=4>, #<Card:0x007f7d00fa8910 @rank=:queen, @suit=:clubs, @position=3>, #<Card:0x007f7d00fa8898 @rank=:jack, @suit=:clubs, @position=2>, #<Card:0x007f7d00fa86b8 @rank=9, @suit=:clubs, @position=1>]
     Shared Example Group: "a deck" called from /tmp/d20151112-27349-1t5b6kg/spec.rb:400
     # /tmp/d20151112-27349-1t5b6kg/spec.rb:18:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  9) SixtySixDeck behaves like a deck #to_s returns the names of the cards, each on its own line
     Failure/Error: expect(small_deck.to_s.strip).to eq "Ace of Spades\n9 of Clubs"
     NoMethodError:
       undefined method `strip' for #<Array:0x007f7d00e248a0>
     Shared Example Group: "a deck" called from /tmp/d20151112-27349-1t5b6kg/spec.rb:400
     # /tmp/d20151112-27349-1t5b6kg/spec.rb:68:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  10) SixtySixDeck hand #twenty? returns true for king and queen not of the trump suit
     Failure/Error: expect(hand.twenty?(:hearts)).to be true
       
       expected #<TrueClass:20> => true
            got #<FalseClass:0> => false
       
       Compared using equal?, which compares object identity,
       but expected and actual are not the same object. Use
       `expect(actual).to eq(expected)` if you don't care about
       object identity in this example.
     # /tmp/d20151112-27349-1t5b6kg/spec.rb:439:in `block (4 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

Finished in 0.04942 seconds
57 examples, 10 failures

Failed examples:

rspec /tmp/d20151112-27349-1t5b6kg/spec.rb:14 # WarDeck behaves like a deck fills the deck if no initialize parameters are given
rspec /tmp/d20151112-27349-1t5b6kg/spec.rb:67 # WarDeck behaves like a deck #to_s returns the names of the cards, each on its own line
rspec /tmp/d20151112-27349-1t5b6kg/spec.rb:14 # BeloteDeck behaves like a deck fills the deck if no initialize parameters are given
rspec /tmp/d20151112-27349-1t5b6kg/spec.rb:67 # BeloteDeck behaves like a deck #to_s returns the names of the cards, each on its own line
rspec /tmp/d20151112-27349-1t5b6kg/spec.rb:220 # BeloteDeck hand #highest_of_suit returns the strongest card of the specified suit
rspec /tmp/d20151112-27349-1t5b6kg/spec.rb:239 # BeloteDeck hand #belote? returns true if there is a king and a queen of the same suit
rspec /tmp/d20151112-27349-1t5b6kg/spec.rb:74 # BeloteDeck hand #carre_of_nines? behaves like carre-checking method returns true when there is a carre
rspec /tmp/d20151112-27349-1t5b6kg/spec.rb:14 # SixtySixDeck behaves like a deck fills the deck if no initialize parameters are given
rspec /tmp/d20151112-27349-1t5b6kg/spec.rb:67 # SixtySixDeck behaves like a deck #to_s returns the names of the cards, each on its own line
rspec /tmp/d20151112-27349-1t5b6kg/spec.rb:429 # SixtySixDeck hand #twenty? returns true for king and queen not of the trump suit

История (3 версии и 1 коментар)

Йоан обнови решението на 05.11.2015 22:10 (преди над 8 години)

+class Card
+ def initialize(rank, suit, position = 0)
+ @rank = rank
+ @suit = suit
+ @position = position
+ end
+
+ def <=>(other)
+ comparison = other.suit <=> suit
+
+ comparison = other.position <=> position if comparison.zero?
+
+ comparison
+ end
+
+ def ==(other)
+ (self <=> other).zero?
+ end
+
+ def suit
+ suit_name @suit
+ end
+
+ def rank
+ rank_name @rank
+ end
+
+ def to_s
+ "#{rank} of #{suit}"
+ end
+
+ private
+
+ def rank_name(rank_key)
+ rank_names = { ace: 'Ace', king: 'King', queen: 'Queen', jack: 'Jack' }
+
+ return rank_names[rank_key] if rank_names.keys.include? rank_key
+
+ rank_key.to_s
+ end
+
+ def suit_name(suit)
+ suit_name = {
+ spades: 'Spades',
+ hearts: 'Hearts',
+ diamonds: 'Diamonds',
+ clubs: 'Clubs'
+ }
+
+ suit_name[suit]
+ end
+
+ protected
+
+ attr_reader :position
+end
+
+class Deck
+ include Enumerable
+
+ def initialize(cards = nil, hand_size = 52, ranks = nil)
+ @hand_size = hand_size
+ ranks ||= %i(2 3 4 5 6 7 8 9 10 jack queen king ace)
+ @cards = [*(cards || create_new_deck(ranks))]
+ end
+
+ def size
+ @cards.count
+ end
+
+ def top_card
+ @cards.first
+ end
+
+ def draw_top_card
+ @cards.shift
+ end
+
+ def draw_bottom_card
+ @cards.pop
+ end
+
+ def bottom_card
+ @cards.last
+ end
+
+ def shuffle
+ @cards.shuffle!
+ end
+
+ def sort
+ @cards.sort!
+ end
+
+ def deal
+ self.class.new(@cards.shift(@hand_size))
+ end
+
+ def each(&_block)
+ return to_enum unless block_given?
+
+ @cards.each { |card| yield card }
+ end
+
+ def to_s
+ @cards.each(&:to_s)
+ end
+
+ private
+
+ def create_new_deck(ranks = nil)
+ suits = %i(spades hearts diamonds clubs)
+ ranks ||= %i(2 3 4 5 6 7 8 9 10 jack queen king ace)
+
+ suits.product(ranks.each_with_index.to_a).shuffle.map do |product|
+ suit, (rank, position) = product
+
+ Card.new(rank, suit, position)
+ end
+ end
+
+ def deck_contains_pair?(suit)
+ deck_contains?(:queen, suit) && deck_contains(:king, suit)
+ end
+
+ def deck_contains?(rank, suit)
+ @cards.contains(Card.new(rank, suit))
+ end
+end
+
+class WarDeck < Deck
+ def initialize(cards = nil)
+ super(cards, 26)
+ end
+
+ alias_method :play_card, :draw_top_card
+
+ def allow_face_up?
+ size == 3
+ end
+end
+
+class BeloteDeck < Deck
+ def initialize(cards = nil)
+ super(cards, 8, %i(7 8 9 jack queen king 10 ace))
+ end
+
+ def highest_of_suit(suit)
+ @cards.select { |card| card.suit == suit }.sort.first
+ end
+
+ def belote?
+ %i(spades hearts diamonds clubs).each do |suit|
+ return true if deck_contains_pair? suit
+ end
+
+ false
+ end
+
+ def tierce?
+ false if consecutive?(3).nil?
+ end
+
+ def quarte?
+ false if consecutive?(4).nil?
+ end
+
+ def quint?
+ false if consecutive?(5).nil?
+ end
+
+ def carre_of_jacks?
+ carre? 'Jack'
+ end
+
+ def carre_of_nines?
+ carre? '9'
+ end
+
+ def carre_of_aces?
+ carre? 'Ace'
+ end
+
+ private
+
+ def carre?(type)
+ @cards.count { |card| card.rank == type } == 4
+ end
+
+ def consecutive?(count)
+ @cards.group_by(&:suit).each do |_, cards|
+ positions = cards.each.map(&:position)
+
+ true if positions.each_cons(count).to_a.length > 0
+ end
+ end
+end
+
+class SixtySixDeck < Deck
+ def initialize(cards = nil)
+ super(cards, 6, %i(9 jack queen king 10 ace))
+ end
+
+ def twenty?(trump_suit)
+ no_trump_suits = [:spades, :hearts, :diamonds, :clubs] - [trump_suit]
+
+ no_trump_suits.each do |suit|
+ return true if deck_contains_pair(suit)
+ end
+
+ false
+ end
+
+ def forty?(trump_suit)
+ deck_contains?(:queen, trump_suit) && deck_contains(:king, trump_suit)
+ end
+end

Здравей :) Няколко коментара:

  • Прегледай имплементацията си на Card отново. Сравнението ти на карти не работи.
  • Защо са ти rank_name и suit_name? Не можеш ли да ги преобразуваш с код?
  • Защо приемаш (&_block), след като използваш yield?
  • Конструкцията [*(cards || create_new_deck(ranks))] не ми допада. Прекалено сложно е и ме кара да мисля :) Това е еквивалентно на cards || create_new_deck(ranks).

Не ми допада, че използваш класовете за тестета като ръка. Ще е по-добре ако създадеш отделни класове за нещата, които връща #deal. Така няма да можеш да напишеш WarDeck.new.allow_face_up?, което е безсмислено за едно тесте. Също, няма да можеш да раздаваш карти от ръката. Това трябва да се прави само от тестето.

Има тук-там и други проблеми. Прегледай пак условието и пробвай нещата. Опитай и с негативни примери - опитай се да счупиш кода, вместо само да проверяваш дали работи :)

Йоан обнови решението на 09.11.2015 14:34 (преди над 8 години)

class Card
def initialize(rank, suit, position = 0)
@rank = rank
@suit = suit
@position = position
end
def <=>(other)
comparison = other.suit <=> suit
- comparison = other.position <=> position if comparison.zero?
+ if comparison.zero? && position.zero?
+ comparison = other.rank <=> rank
+ elsif comparison.zero?
+ comparison = other.position <=> position
+ end
comparison
end
def ==(other)
(self <=> other).zero?
end
def suit
- suit_name @suit
+ @suit.to_s.capitalize
end
def rank
- rank_name @rank
+ @rank.to_s.capitalize
end
def to_s
"#{rank} of #{suit}"
end
- private
-
- def rank_name(rank_key)
- rank_names = { ace: 'Ace', king: 'King', queen: 'Queen', jack: 'Jack' }
-
- return rank_names[rank_key] if rank_names.keys.include? rank_key
-
- rank_key.to_s
- end
-
- def suit_name(suit)
- suit_name = {
- spades: 'Spades',
- hearts: 'Hearts',
- diamonds: 'Diamonds',
- clubs: 'Clubs'
- }
-
- suit_name[suit]
- end
-
protected
attr_reader :position
end
class Deck
include Enumerable
- def initialize(cards = nil, hand_size = 52, ranks = nil)
+ def initialize(cards = nil, ranks: nil, hand_type: nil, hand_size: 52)
+ @hand_type = hand_type
@hand_size = hand_size
+
ranks ||= %i(2 3 4 5 6 7 8 9 10 jack queen king ace)
- @cards = [*(cards || create_new_deck(ranks))]
+ @cards = cards || create_new_deck(ranks)
end
def size
@cards.count
end
def top_card
@cards.first
end
def draw_top_card
@cards.shift
end
def draw_bottom_card
@cards.pop
end
def bottom_card
@cards.last
end
def shuffle
@cards.shuffle!
end
def sort
@cards.sort!
end
def deal
- self.class.new(@cards.shift(@hand_size))
+ @hand_type.new(@cards.shift(@hand_size))
end
- def each(&_block)
- return to_enum unless block_given?
-
+ def each
@cards.each { |card| yield card }
end
def to_s
@cards.each(&:to_s)
end
private
def create_new_deck(ranks = nil)
suits = %i(spades hearts diamonds clubs)
ranks ||= %i(2 3 4 5 6 7 8 9 10 jack queen king ace)
suits.product(ranks.each_with_index.to_a).shuffle.map do |product|
suit, (rank, position) = product
Card.new(rank, suit, position)
end
end
+end
+class Hand
+ def initialize(cards = nil)
+ @cards = cards
+ end
+
+ def size
+ @cards.count
+ end
+
+ private
+
def deck_contains_pair?(suit)
deck_contains?(:queen, suit) && deck_contains(:king, suit)
end
def deck_contains?(rank, suit)
@cards.contains(Card.new(rank, suit))
end
end
-class WarDeck < Deck
- def initialize(cards = nil)
- super(cards, 26)
+class WarHand < Hand
+ def play_card
+ @cards.shift
end
- alias_method :play_card, :draw_top_card
-
def allow_face_up?
- size == 3
+ size <= 3
end
end
-class BeloteDeck < Deck
+class WarDeck < Deck
def initialize(cards = nil)
- super(cards, 8, %i(7 8 9 jack queen king 10 ace))
+ super(cards, hand_size: 26,
+ hand_type: WarHand)
end
+end
+class BeloteHand < Hand
def highest_of_suit(suit)
@cards.select { |card| card.suit == suit }.sort.first
end
def belote?
%i(spades hearts diamonds clubs).each do |suit|
return true if deck_contains_pair? suit
end
false
end
def tierce?
- false if consecutive?(3).nil?
+ consecutive?(3) || false
end
def quarte?
- false if consecutive?(4).nil?
+ consecutive?(4) || false
end
def quint?
- false if consecutive?(5).nil?
+ consecutive?(5) || false
end
def carre_of_jacks?
carre? 'Jack'
end
def carre_of_nines?
carre? '9'
end
def carre_of_aces?
carre? 'Ace'
end
private
def carre?(type)
@cards.count { |card| card.rank == type } == 4
end
def consecutive?(count)
@cards.group_by(&:suit).each do |_, cards|
positions = cards.each.map(&:position)
true if positions.each_cons(count).to_a.length > 0
end
end
end
-class SixtySixDeck < Deck
+class BeloteDeck < Deck
def initialize(cards = nil)
- super(cards, 6, %i(9 jack queen king 10 ace))
+ super(cards, hand_size: 8,
+ ranks: %i(7 8 9 jack queen king 10 ace),
+ hand_type: BeloteHand)
end
+end
+class SixtySixHand < Hand
def twenty?(trump_suit)
no_trump_suits = [:spades, :hearts, :diamonds, :clubs] - [trump_suit]
+ has_twenty = false
+
no_trump_suits.each do |suit|
- return true if deck_contains_pair(suit)
+ has_twenty = true if deck_contains_pair?(suit)
end
- false
+ has_twenty
end
def forty?(trump_suit)
- deck_contains?(:queen, trump_suit) && deck_contains(:king, trump_suit)
+ deck_contains_pair?(trump_suit)
+ end
+end
+
+class SixtySixDeck < Deck
+ def initialize(cards = nil)
+ super(cards, hand_size: 6,
+ ranks: %i(9 jack queen king 10 ace),
+ hand_type: SixtySixHand)
end
end

Йоан обнови решението на 11.11.2015 14:58 (преди над 8 години)

class Card
def initialize(rank, suit, position = 0)
@rank = rank
@suit = suit
@position = position
end
+ attr_accessor :position
+ attr_reader :suit
+ attr_reader :rank
+
def <=>(other)
comparison = other.suit <=> suit
if comparison.zero? && position.zero?
- comparison = other.rank <=> rank
+ comparison = other.rank.to_s <=> rank.to_s
elsif comparison.zero?
comparison = other.position <=> position
end
comparison
end
def ==(other)
(self <=> other).zero?
end
- def suit
- @suit.to_s.capitalize
- end
-
- def rank
- @rank.to_s.capitalize
- end
-
def to_s
- "#{rank} of #{suit}"
+ "#{rank.to_s.capitalize} of #{suit.to_s.capitalize}"
end
-
- protected
-
- attr_reader :position
end
class Deck
include Enumerable
def initialize(cards = nil, ranks: nil, hand_type: nil, hand_size: 52)
@hand_type = hand_type
@hand_size = hand_size
- ranks ||= %i(2 3 4 5 6 7 8 9 10 jack queen king ace)
+ ranks ||= [2, 3, 4, 5, 6, 7, 8, 9, 10, :jack, :queen, :king, :ace]
@cards = cards || create_new_deck(ranks)
+ update_ranks(ranks)
end
def size
@cards.count
end
def top_card
@cards.first
end
def draw_top_card
@cards.shift
end
def draw_bottom_card
@cards.pop
end
def bottom_card
@cards.last
end
def shuffle
@cards.shuffle!
end
def sort
@cards.sort!
end
def deal
@hand_type.new(@cards.shift(@hand_size))
end
def each
@cards.each { |card| yield card }
end
def to_s
@cards.each(&:to_s)
end
private
- def create_new_deck(ranks = nil)
+ def create_new_deck(ranks)
suits = %i(spades hearts diamonds clubs)
- ranks ||= %i(2 3 4 5 6 7 8 9 10 jack queen king ace)
- suits.product(ranks.each_with_index.to_a).shuffle.map do |product|
- suit, (rank, position) = product
+ suits.product(ranks.to_a).shuffle.map do |product|
+ suit, rank = product
- Card.new(rank, suit, position)
+ Card.new(rank, suit)
end
end
+
+ def update_ranks(ranks)
+ @cards.each do |card|
+ card.position = ranks.index(card.rank) + 1
+ end
+ end
end
class Hand
def initialize(cards = nil)
@cards = cards
end
def size
@cards.count
end
private
def deck_contains_pair?(suit)
- deck_contains?(:queen, suit) && deck_contains(:king, suit)
+ deck_contains?(:queen, suit) && deck_contains?(:king, suit)
end
def deck_contains?(rank, suit)
- @cards.contains(Card.new(rank, suit))
+ @cards.include? Card.new(rank, suit)
end
end
class WarHand < Hand
def play_card
@cards.shift
end
def allow_face_up?
size <= 3
end
end
class WarDeck < Deck
def initialize(cards = nil)
super(cards, hand_size: 26,
hand_type: WarHand)
end
end
class BeloteHand < Hand
def highest_of_suit(suit)
@cards.select { |card| card.suit == suit }.sort.first
end
def belote?
%i(spades hearts diamonds clubs).each do |suit|
return true if deck_contains_pair? suit
end
false
end
def tierce?
consecutive?(3) || false
end
def quarte?
consecutive?(4) || false
end
def quint?
consecutive?(5) || false
end
def carre_of_jacks?
- carre? 'Jack'
+ carre? :jack
end
def carre_of_nines?
carre? '9'
end
def carre_of_aces?
- carre? 'Ace'
+ carre? :ace
end
private
def carre?(type)
@cards.count { |card| card.rank == type } == 4
end
def consecutive?(count)
@cards.group_by(&:suit).each do |_, cards|
positions = cards.each.map(&:position)
- true if positions.each_cons(count).to_a.length > 0
+ return true if positions
+ .sort
+ .each_cons(count)
+ .chunk{|a,b| a.succ == b || nil}.to_a.length > 0
end
+
+ false
end
end
class BeloteDeck < Deck
def initialize(cards = nil)
super(cards, hand_size: 8,
- ranks: %i(7 8 9 jack queen king 10 ace),
+ ranks: [7, 8, 9, :jack, :queen, :king, 10, :ace],
hand_type: BeloteHand)
end
end
class SixtySixHand < Hand
def twenty?(trump_suit)
no_trump_suits = [:spades, :hearts, :diamonds, :clubs] - [trump_suit]
has_twenty = false
no_trump_suits.each do |suit|
has_twenty = true if deck_contains_pair?(suit)
end
has_twenty
end
def forty?(trump_suit)
deck_contains_pair?(trump_suit)
end
end
class SixtySixDeck < Deck
def initialize(cards = nil)
super(cards, hand_size: 6,
- ranks: %i(9 jack queen king 10 ace),
+ ranks: [9, :jack, :queen, :king, 10, :ace],
hand_type: SixtySixHand)
end
end