Решение на Четвърта задача от Мариян Борисов

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

Към профила на Мариян Борисов

Резултати

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

Код

class Card
attr_accessor :rank, :suit
def initialize(rank, suit)
@rank = rank
@suit = suit
end
def to_s
"#{@rank.to_s.capitalize} of #{@suit.to_s.capitalize}"
end
def ==(card)
@rank == card.rank and @suit == card.suit
end
end
class Hand
def initialize(cards)
@cards = cards.dup
end
def size
@cards.size
end
def has_queen_and_king?(suits)
suits.any? do |suit|
[:queen, :king].all? { |rank| @cards.include? Card.new(rank, suit) }
end
end
end
class WarHand < Hand
def play_card
@cards.delete_at(rand(@cards.length))
end
def allow_face_up?
@cards.size <= 3
end
end
class BeloteHand < Hand
def highest_of_suit(suit)
cards_of_suit = @cards.select { |card| card.suit == suit }
cards_of_suit.max_by { |card| BeloteDeck::RANKS.index(card.rank) }
end
def belote?
has_queen_and_king?(BeloteDeck::SUITS)
end
def tierce?
cards_in_a_row?(3)
end
def quarte?
cards_in_a_row?(4)
end
def quint?
cards_in_a_row?(5)
end
def carre_of_jacks?
carre?(:jack)
end
def carre_of_nines?
carre?(9)
end
def carre_of_aces?
carre?(:ace)
end
private
def cards_in_a_row?(count)
BeloteDeck::SUITS.any? do |suit|
cards_of_suit = @cards.select { |card| card.suit == suit }
cards_of_suit.map!(&:rank)
ranks_included = BeloteDeck::RANKS.map do |rank|
cards_of_suit.include?(rank)
end
chunks = ranks_included.chunk { |included| included }
consecutive_chunks = chunks.select { |chunk| chunk.first }
consecutive_chunks.max_by { |chunk| chunk.last.size }.last.size == count
end
end
def carre?(rank)
@cards.count { |card| card.rank == rank } == 4
end
end
class SixtySixHand < Hand
def twenty?(trump_suit)
has_queen_and_king?(SixtySixDeck::SUITS - trump_suit)
end
def forty?(trump_suit)
has_queen_and_king?([trump_suit])
end
end
class Deck
include Enumerable
RANKS = [2, 3, 4, 5, 6, 7, 8, 9, 10, :jack, :queen, :king, :ace].freeze
SUITS = [:spades, :hearts, :diamonds, :clubs].freeze
DEAL_COUNT = 1
def initialize(cards = nil)
if cards == nil
@cards = self.class::RANKS.product(self.class::SUITS).map do |card|
Card.new(card[0], card[1])
end
else
@cards = cards.dup
end
end
def each(&block)
@cards.each &block
end
def size
@cards.size
end
def draw_top_card
@cards.shift
end
def draw_bottom_card
@cards.pop
end
def top_card
@cards[0]
end
def bottom_card
@cards[-1]
end
def shuffle
@cards.shuffle!
self
end
def sort
ranks = self.class::RANKS
suits = self.class::SUITS
@cards.sort! do |first_card, second_card|
if first_card.suit == second_card.suit
ranks.index(second_card.rank) <=> ranks.index(first_card.rank)
else
suits.index(first_card.suit) <=> suits.index(second_card.suit)
end
end
self
end
def to_s
@cards.join "\n"
end
def deal
self.class::DEAL_CLASS.new(@cards.slice!(0, self.class::DEAL_COUNT))
end
end
class WarDeck < Deck
DEAL_COUNT = 26
DEAL_CLASS = WarHand
end
class BeloteDeck < Deck
RANKS = [7, 8, 9, :jack, :queen, :king, 10, :ace].freeze
DEAL_COUNT = 8
DEAL_CLASS = BeloteHand
end
class SixtySixDeck < Deck
RANKS = [9, :jack, :queen, :king, 10, :ace].freeze
DEAL_COUNT = 6
DEAL_CLASS = SixtySixHand
end

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

..............................F...F.F.................FFF

Failures:

  1) BeloteDeck hand #tierce? with tierce returns true for cards with names
     Failure/Error: expect(hand.tierce?).to be true
     NoMethodError:
       undefined method `last' for nil:NilClass
     # /tmp/d20151112-27349-x3e767/solution.rb:96:in `block in cards_in_a_row?'
     # /tmp/d20151112-27349-x3e767/solution.rb:88:in `any?'
     # /tmp/d20151112-27349-x3e767/solution.rb:88:in `cards_in_a_row?'
     # /tmp/d20151112-27349-x3e767/solution.rb:62:in `tierce?'
     # /tmp/d20151112-27349-x3e767/spec.rb:284:in `block (5 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) BeloteDeck hand #quarte? does not return true if there is no quarte
     Failure/Error: expect(hand.quarte?).to be false
     NoMethodError:
       undefined method `last' for nil:NilClass
     # /tmp/d20151112-27349-x3e767/solution.rb:96:in `block in cards_in_a_row?'
     # /tmp/d20151112-27349-x3e767/solution.rb:88:in `any?'
     # /tmp/d20151112-27349-x3e767/solution.rb:88:in `cards_in_a_row?'
     # /tmp/d20151112-27349-x3e767/solution.rb:66:in `quarte?'
     # /tmp/d20151112-27349-x3e767/spec.rb:349: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)>'

  3) BeloteDeck hand #quint? does not return true if there is no quint
     Failure/Error: expect(hand.quint?).to be false
     NoMethodError:
       undefined method `last' for nil:NilClass
     # /tmp/d20151112-27349-x3e767/solution.rb:96:in `block in cards_in_a_row?'
     # /tmp/d20151112-27349-x3e767/solution.rb:88:in `any?'
     # /tmp/d20151112-27349-x3e767/solution.rb:88:in `cards_in_a_row?'
     # /tmp/d20151112-27349-x3e767/solution.rb:70:in `quint?'
     # /tmp/d20151112-27349-x3e767/spec.rb:381: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)>'

  4) SixtySixDeck hand #twenty? returns true for king and queen not of the trump suit
     Failure/Error: expect(hand.twenty?(:hearts)).to be true
     TypeError:
       no implicit conversion of Symbol into Array
     # /tmp/d20151112-27349-x3e767/solution.rb:109:in `-'
     # /tmp/d20151112-27349-x3e767/solution.rb:109:in `twenty?'
     # /tmp/d20151112-27349-x3e767/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)>'

  5) SixtySixDeck hand #twenty? returns false for king and queen of the trump suit
     Failure/Error: expect(hand.twenty?(:clubs)).to be false
     TypeError:
       no implicit conversion of Symbol into Array
     # /tmp/d20151112-27349-x3e767/solution.rb:109:in `-'
     # /tmp/d20151112-27349-x3e767/solution.rb:109:in `twenty?'
     # /tmp/d20151112-27349-x3e767/spec.rb:452: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) SixtySixDeck hand #twenty? returns false for hands without a king and queen of the same suit
     Failure/Error: expect(hand.twenty?(:hearts)).to be false
     TypeError:
       no implicit conversion of Symbol into Array
     # /tmp/d20151112-27349-x3e767/solution.rb:109:in `-'
     # /tmp/d20151112-27349-x3e767/solution.rb:109:in `twenty?'
     # /tmp/d20151112-27349-x3e767/spec.rb:465: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.0419 seconds
57 examples, 6 failures

Failed examples:

rspec /tmp/d20151112-27349-x3e767/spec.rb:272 # BeloteDeck hand #tierce? with tierce returns true for cards with names
rspec /tmp/d20151112-27349-x3e767/spec.rb:337 # BeloteDeck hand #quarte? does not return true if there is no quarte
rspec /tmp/d20151112-27349-x3e767/spec.rb:369 # BeloteDeck hand #quint? does not return true if there is no quint
rspec /tmp/d20151112-27349-x3e767/spec.rb:429 # SixtySixDeck hand #twenty? returns true for king and queen not of the trump suit
rspec /tmp/d20151112-27349-x3e767/spec.rb:442 # SixtySixDeck hand #twenty? returns false for king and queen of the trump suit
rspec /tmp/d20151112-27349-x3e767/spec.rb:455 # SixtySixDeck hand #twenty? returns false for hands without a king and queen of the same suit

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

Мариян обнови решението на 11.11.2015 05:10 (преди около 9 години)

+class Card
+
+ attr_accessor :rank, :suit
+
+ def initialize(rank, suit)
+ @rank = rank
+ @suit = suit
+ end
+
+ def to_s
+ "#{@rank.to_s.capitalize} of #{@suit.to_s.capitalize}"
+ end
+
+ def ==(card)
+ @rank == card.rank and @suit == card.suit
+ end
+
+end
+
+class Hand
+
+ def initialize(cards)
+ @cards = cards.dup
+ end
+
+ def size
+ @cards.size
+ end
+
+ def has_queen_and_king?(suits)
+ suits.any? do |suit|
+ [:queen, :king].all? { |rank| @cards.include? Card.new(rank, suit) }
+ end
+ end
+
+end
+
+class WarHand < Hand
+
+ def play_card
+ @cards.delete_at(rand(@cards.length))
+ end
+
+ def allow_face_up?
+ @cards.size <= 3
+ end
+
+end
+
+class BeloteHand < Hand
+
+ def highest_of_suit(suit)
+ cards_of_suit = @cards.select { |card| card.suit == suit }
+ cards_of_suit.max_by { |card| BeloteDeck::RANKS.index(card.rank) }
+ end
+
+ def belote?
+ has_queen_and_king?(BeloteDeck::SUITS)
+ end
+
+ def tierce?
+ cards_in_a_row?(3)
+ end
+
+ def quarte?
+ cards_in_a_row?(4)
+ end
+
+ def quint?
+ cards_in_a_row?(5)
+ end
+
+ def carre_of_jacks?
+ carre?(:jack)
+ end
+
+ def carre_of_nines?
+ carre?(9)
+ end
+
+ def carre_of_aces?
+ carre?(:ace)
+ end
+
+ private
+
+ def cards_in_a_row?(count)
+ BeloteDeck::SUITS.any? do |suit|
+ cards_of_suit = @cards.select { |card| card.suit == suit }
+ cards_of_suit.map!(&:rank)
+ ranks_included = BeloteDeck::RANKS.map do |rank|
+ cards_of_suit.include?(rank)
+ end
+ chunks = ranks_included.chunk { |included| included }
+ consecutive_chunks = chunks.select { |chunk| chunk.first }
+ consecutive_chunks.max_by { |chunk| chunk.last.size }.last.size == 3
+ end
+ end
+
+ def carre?(rank)
+ @cards.count { |card| card.rank == rank } == 4
+ end
+
+end
+
+class SixtySixHand < Hand
+
+ def twenty?(trump_suit)
+ has_queen_and_king?(SixtySixDeck::SUITS - trump_suit)
+ end
+
+ def forty?(trump_suit)
+ has_queen_and_king?([trump_suit])
+ end
+
+end
+
+class Deck
+
+ include Enumerable
+
+ RANKS = [2, 3, 4, 5, 6, 7, 8, 9, 10, :jack, :queen, :king, :ace].freeze
+ SUITS = [:spades, :hearts, :diamonds, :clubs].freeze
+ DEAL_COUNT = 1
+
+ def initialize(cards = nil)
+ if cards == nil
+ @cards = self.class::RANKS.product(self.class::SUITS).map do |card|
+ Card.new(card[0], card[1])
+ end
+ else
+ @cards = cards.dup
+ end
+ end
+
+ def each(&block)
+ @cards.each &block
+ end
+
+ def size
+ @cards.size
+ end
+
+ def draw_top_card
+ @cards.shift
+ end
+
+ def draw_bottom_card
+ @cards.pop
+ end
+
+ def top_card
+ @cards[0]
+ end
+
+ def bottom_card
+ @cards[-1]
+ end
+
+ def shuffle
+ @cards.shuffle!
+ self
+ end
+
+ def sort
+ ranks = self.class::RANKS
+ suits = self.class::SUITS
+ @cards.sort! do |first_card, second_card|
+ if first_card.suit == second_card.suit
+ ranks.index(second_card.rank) <=> ranks.index(first_card.rank)
+ else
+ suits.index(first_card.suit) <=> suits.index(second_card.suit)
+ end
+ end
+ self
+ end
+
+ def to_s
+ @cards.join "\n"
+ end
+
+ def deal
+ self.class::DEAL_CLASS.new(@cards.slice!(0, self.class::DEAL_COUNT))
+ end
+
+end
+
+class WarDeck < Deck
+
+ DEAL_COUNT = 26
+ DEAL_CLASS = WarHand
+
+end
+
+class BeloteDeck < Deck
+
+ RANKS = [7, 8, 9, :jack, :queen, :king, 10, :ace].freeze
+ DEAL_COUNT = 8
+ DEAL_CLASS = BeloteHand
+
+end
+
+class SixtySixDeck < Deck
+
+ RANKS = [9, :jack, :queen, :king, 10, :ace].freeze
+ DEAL_COUNT = 6
+ DEAL_CLASS = SixtySixHand
+
+end

Мариян обнови решението на 11.11.2015 05:12 (преди около 9 години)

class Card
attr_accessor :rank, :suit
def initialize(rank, suit)
@rank = rank
@suit = suit
end
def to_s
"#{@rank.to_s.capitalize} of #{@suit.to_s.capitalize}"
end
def ==(card)
@rank == card.rank and @suit == card.suit
end
end
class Hand
def initialize(cards)
@cards = cards.dup
end
def size
@cards.size
end
def has_queen_and_king?(suits)
suits.any? do |suit|
[:queen, :king].all? { |rank| @cards.include? Card.new(rank, suit) }
end
end
end
class WarHand < Hand
def play_card
@cards.delete_at(rand(@cards.length))
end
def allow_face_up?
@cards.size <= 3
end
end
class BeloteHand < Hand
def highest_of_suit(suit)
cards_of_suit = @cards.select { |card| card.suit == suit }
cards_of_suit.max_by { |card| BeloteDeck::RANKS.index(card.rank) }
end
def belote?
has_queen_and_king?(BeloteDeck::SUITS)
end
def tierce?
cards_in_a_row?(3)
end
def quarte?
cards_in_a_row?(4)
end
def quint?
cards_in_a_row?(5)
end
def carre_of_jacks?
carre?(:jack)
end
def carre_of_nines?
carre?(9)
end
def carre_of_aces?
carre?(:ace)
end
private
def cards_in_a_row?(count)
BeloteDeck::SUITS.any? do |suit|
cards_of_suit = @cards.select { |card| card.suit == suit }
cards_of_suit.map!(&:rank)
ranks_included = BeloteDeck::RANKS.map do |rank|
cards_of_suit.include?(rank)
end
chunks = ranks_included.chunk { |included| included }
consecutive_chunks = chunks.select { |chunk| chunk.first }
- consecutive_chunks.max_by { |chunk| chunk.last.size }.last.size == 3
+ consecutive_chunks.max_by { |chunk| chunk.last.size }.last.size == count
end
end
def carre?(rank)
@cards.count { |card| card.rank == rank } == 4
end
end
class SixtySixHand < Hand
def twenty?(trump_suit)
has_queen_and_king?(SixtySixDeck::SUITS - trump_suit)
end
def forty?(trump_suit)
has_queen_and_king?([trump_suit])
end
end
class Deck
include Enumerable
RANKS = [2, 3, 4, 5, 6, 7, 8, 9, 10, :jack, :queen, :king, :ace].freeze
SUITS = [:spades, :hearts, :diamonds, :clubs].freeze
DEAL_COUNT = 1
def initialize(cards = nil)
if cards == nil
@cards = self.class::RANKS.product(self.class::SUITS).map do |card|
Card.new(card[0], card[1])
end
else
@cards = cards.dup
end
end
def each(&block)
@cards.each &block
end
def size
@cards.size
end
def draw_top_card
@cards.shift
end
def draw_bottom_card
@cards.pop
end
def top_card
@cards[0]
end
def bottom_card
@cards[-1]
end
def shuffle
@cards.shuffle!
self
end
def sort
ranks = self.class::RANKS
suits = self.class::SUITS
@cards.sort! do |first_card, second_card|
if first_card.suit == second_card.suit
ranks.index(second_card.rank) <=> ranks.index(first_card.rank)
else
suits.index(first_card.suit) <=> suits.index(second_card.suit)
end
end
self
end
def to_s
@cards.join "\n"
end
def deal
self.class::DEAL_CLASS.new(@cards.slice!(0, self.class::DEAL_COUNT))
end
end
class WarDeck < Deck
DEAL_COUNT = 26
DEAL_CLASS = WarHand
end
class BeloteDeck < Deck
RANKS = [7, 8, 9, :jack, :queen, :king, 10, :ace].freeze
DEAL_COUNT = 8
DEAL_CLASS = BeloteHand
end
class SixtySixDeck < Deck
RANKS = [9, :jack, :queen, :king, 10, :ace].freeze
DEAL_COUNT = 6
DEAL_CLASS = SixtySixHand
end
  • self.class::RANKS е ненужно, може да ползваш само RANKS
  • не оставяй празен ред след началото на дефиниция на клас и преди съответния затварящ end

Прегледай решенията на колеги и нашето примерно решение за алтернативни идеи.