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

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

Към профила на Андрея Костов

Резултати

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

Код

SUITS = [:spades, :hearts, :diamonds, :clubs]
RANKS = [:ace, :king, :queen, :jack, 10, 9, 8, 7, 6, 5, 4, 3, 2]
BELOTE_AND_SIXTY_SIX_RANKS = [:ace, 10, :king, :queen, :jack, 9, 8, 7]
class Card
include Comparable
attr_reader :rank, :suit
def <=>(other)
suits = SUITS.index(@suit) <=> SUITS.index(other.suit)
ranks = RANKS.index(@rank) <=> RANKS.index(other.rank)
result = 0
if suits == 0 && ranks != 0
result = ranks
elsif suits != 0
result = suits
end
result
end
def initialize(rank, suit)
@rank = rank
@suit = suit
end
def to_s
"#{@rank.to_s.capitalize} of #{@suit.to_s.capitalize}"
end
end
class Hand
def initialize(dealt_cards)
@hand = dealt_cards
end
def size
@hand.size
end
def to_s
@hand.join("\n")
end
end
class Deck
include Enumerable
def initialize(cards = default_deck)
@cards = cards
end
def each(&block)
@cards.each(&block)
end
def size
@cards.size
end
def draw_top_card
@cards.slice!(0)
end
def draw_bottom_card
@cards.slice!(@cards.size - 1)
end
def top_card
@cards.first
end
def bottom_card
@cards.last
end
def shuffle
@cards.shuffle!(random: rand)
self
end
def to_s
@cards.join("\n")
end
def sort
@cards.sort! { |first, second| compare(first, second) }
self
end
private
def compare(first, second)
first <=> second
end
def compare_suits_and_ranks(suits, ranks)
# Pretty sure there is a better way...
result = 0
if suits == 0 && ranks != 0
result = ranks
elsif suits != 0
result = suits
end
result
end
def default_deck
RANKS.product(SUITS).collect { |rank, suit| Card.new(rank, suit) }
end
end
class WarDeck < Deck
def deal
WarHand.new(@cards.slice!(0, 26))
end
end
class WarHand < Hand
def play_card
@hand.slice!(rand(0..(@hand.size - 1)))
end
def allow_face_up?
@hand.size <= 3
end
end
class BeloteDeck < Deck
def default_deck
RANKS.take(8).product(SUITS).collect { |rank, suit| Card.new(rank, suit) }
end
def deal
BeloteHand.new(@cards.slice!(0, 8))
end
private
def compare(first, second)
suits = SUITS.index(first.suit) <=> SUITS.index(second.suit)
ranks = BELOTE_AND_SIXTY_SIX_RANKS.index(first.rank) <=>
BELOTE_AND_SIXTY_SIX_RANKS.index(second.rank)
compare_suits_and_ranks(suits, ranks)
end
end
class BeloteHand < Hand
def highest_of_suit(suit)
@hand.select { |card| card.suit == suit }.sort.fetch(0, nil)
end
def belote?
@hand.select { |card| card.rank == :king || card.rank == :queen }
.group_by(&:suit)
.any? { |_, cards_of_suit| cards_of_suit.size == 2 }
end
def carre_of_jacks?
carre_of(:jack)
end
def carre_of_nines?
carre_of(9)
end
def carre_of_aces?
carre_of(:ace)
end
private
def carre_of(rank)
@hand.count { |card| card.rank == rank } == 4
end
end
class SixtySixDeck < Deck
def default_deck
RANKS.take(6).product(SUITS).collect { |rank, suit| Card.new(rank, suit) }
end
def deal
SixtySixHand.new(@cards.slice!(0, 6))
end
private
def compare(first, second)
suits = SUITS.index(first.suit) <=> SUITS.index(second.suit)
ranks = BELOTE_AND_SIXTY_SIX_RANKS.index(first.rank) <=>
BELOTE_AND_SIXTY_SIX_RANKS.index(second.rank)
compare_suits_and_ranks(suits, ranks)
end
end
class SixtySixHand < Hand
def twenty?(trump_suit)
@hand.select { |card| card.rank == :king || card.rank == :queen }
.reject { |card| card.suit == trump_suit }
.group_by(&:suit)
.any? { |_, cards_of_suit| cards_of_suit.size == 2 }
end
def forty?(trump_suit)
@hand.select { |card| card.rank == :king || card.rank == :queen }
.count { |card| card.suit == trump_suit } == 2
end
end

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

..............................FFFFFFF....................

Failures:

  1) BeloteDeck hand #tierce? with tierce returns true for cards with names
     Failure/Error: expect(hand.tierce?).to be true
     NoMethodError:
       undefined method `tierce?' for #<BeloteHand:0x007fde931e0ec8>
     # /tmp/d20151112-27349-j46se0/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 #tierce? with tierce returns true for cards with numbers
     Failure/Error: expect(hand.tierce?).to be true
     NoMethodError:
       undefined method `tierce?' for #<BeloteHand:0x007fde93092e68>
     # /tmp/d20151112-27349-j46se0/spec.rb:299: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)>'

  3) BeloteDeck hand #tierce? without tierce does not confuse cards with different suits
     Failure/Error: expect(hand.tierce?).to be false
     NoMethodError:
       undefined method `tierce?' for #<BeloteHand:0x007fde930903e8>
     # /tmp/d20151112-27349-j46se0/spec.rb:316: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)>'

  4) BeloteDeck hand #quarte? detects four cards with increasing ranks
     Failure/Error: expect(hand.quarte?).to be true
     NoMethodError:
       undefined method `quarte?' for #<BeloteHand:0x007fde93080650>
     # /tmp/d20151112-27349-j46se0/spec.rb:334: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) BeloteDeck hand #quarte? does not return true if there is no quarte
     Failure/Error: expect(hand.quarte?).to be false
     NoMethodError:
       undefined method `quarte?' for #<BeloteHand:0x007fde93078518>
     # /tmp/d20151112-27349-j46se0/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)>'

  6) BeloteDeck hand #quint? detects five cards with increasing ranks
     Failure/Error: expect(hand.quint?).to be true
     NoMethodError:
       undefined method `quint?' for #<BeloteHand:0x007fde9306cbf0>
     # /tmp/d20151112-27349-j46se0/spec.rb:366: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 #quint? does not return true if there is no quint
     Failure/Error: expect(hand.quint?).to be false
     NoMethodError:
       undefined method `quint?' for #<BeloteHand:0x007fde9303e728>
     # /tmp/d20151112-27349-j46se0/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)>'

Finished in 0.04353 seconds
57 examples, 7 failures

Failed examples:

rspec /tmp/d20151112-27349-j46se0/spec.rb:272 # BeloteDeck hand #tierce? with tierce returns true for cards with names
rspec /tmp/d20151112-27349-j46se0/spec.rb:287 # BeloteDeck hand #tierce? with tierce returns true for cards with numbers
rspec /tmp/d20151112-27349-j46se0/spec.rb:304 # BeloteDeck hand #tierce? without tierce does not confuse cards with different suits
rspec /tmp/d20151112-27349-j46se0/spec.rb:322 # BeloteDeck hand #quarte? detects four cards with increasing ranks
rspec /tmp/d20151112-27349-j46se0/spec.rb:337 # BeloteDeck hand #quarte? does not return true if there is no quarte
rspec /tmp/d20151112-27349-j46se0/spec.rb:354 # BeloteDeck hand #quint? detects five cards with increasing ranks
rspec /tmp/d20151112-27349-j46se0/spec.rb:369 # BeloteDeck hand #quint? does not return true if there is no quint

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

Андрея обнови решението на 11.11.2015 16:09 (преди над 8 години)

+SUITS = [:spades, :hearts, :diamonds, :clubs]
+RANKS = [:ace, :king, :queen, :jack, 10, 9, 8, 7, 6, 5, 4, 3, 2]
+BELOTE_AND_SIXTY_SIX_RANKS = [:ace, 10, :king, :queen, :jack, 9, 8, 7]
+
+class Card
+ include Comparable
+
+ attr_reader :rank, :suit
+
+ def <=>(other)
+ suits = SUITS.index(@suit) <=> SUITS.index(other.suit)
+ ranks = RANKS.index(@rank) <=> RANKS.index(other.rank)
+
+ result = 0
+ if suits == 0 && ranks != 0
+ result = ranks
+ elsif suits != 0
+ result = suits
+ end
+
+ result
+ end
+
+ def initialize(rank, suit)
+ @rank = rank
+ @suit = suit
+ end
+
+ def to_s
+ "#{@rank.to_s.capitalize} of #{@suit.to_s.capitalize}"
+ end
+end
+
+class Hand
+ def initialize(dealt_cards)
+ @hand = dealt_cards
+ end
+
+ def size
+ @hand.size
+ end
+
+ def to_s
+ @hand.join("\n")
+ end
+end
+
+class Deck
+ include Enumerable
+
+ def initialize(cards = default_deck)
+ @cards = cards
+ end
+
+ def each(&block)
+ @cards.each(&block)
+ end
+
+ def size
+ @cards.size
+ end
+
+ def draw_top_card
+ @cards.slice!(0)
+ end
+
+ def draw_bottom_card
+ @cards.slice!(@cards.size - 1)
+ end
+
+ def top_card
+ @cards.first
+ end
+
+ def bottom_card
+ @cards.last
+ end
+
+ def shuffle
+ @cards.shuffle!(random: rand)
+ self
+ end
+
+ def to_s
+ @cards.join("\n")
+ end
+
+ def sort
+ @cards.sort! { |first, second| compare(first, second) }
+ self
+ end
+
+ private
+
+ def compare(first, second)
+ first <=> second
+ end
+
+ def compare_suits_and_ranks(suits, ranks)
+ # Pretty sure there is a better way...
+ result = 0
+ if suits == 0 && ranks != 0
+ result = ranks
+ elsif suits != 0
+ result = suits
+ end
+
+ result
+ end
+
+ def default_deck
+ RANKS.product(SUITS).collect { |rank, suit| Card.new(rank, suit) }
+ end
+end
+
+class WarDeck < Deck
+ def deal
+ WarHand.new(@cards.slice!(0, 26))
+ end
+end
+
+class WarHand < Hand
+ def play_card
+ @hand.slice!(rand(0..(@hand.size - 1)))
+ end
+
+ def allow_face_up?
+ @hand.size <= 3
+ end
+end
+
+class BeloteDeck < Deck
+ def default_deck
+ RANKS.take(8).product(SUITS).collect { |rank, suit| Card.new(rank, suit) }
+ end
+
+ def deal
+ BeloteHand.new(@cards.slice!(0, 8))
+ end
+
+ private
+
+ def compare(first, second)
+ suits = SUITS.index(first.suit) <=> SUITS.index(second.suit)
+ ranks = BELOTE_AND_SIXTY_SIX_RANKS.index(first.rank) <=>
+ BELOTE_AND_SIXTY_SIX_RANKS.index(second.rank)
+ compare_suits_and_ranks(suits, ranks)
+ end
+end
+
+class BeloteHand < Hand
+ def highest_of_suit(suit)
+ @hand.select { |card| card.suit == suit }.sort.fetch(0, nil)
+ end
+
+ def belote?
+ @hand.select { |card| card.rank == :king || card.rank == :queen }
+ .group_by(&:suit)
+ .any? { |_, cards_of_suit| cards_of_suit.size == 2 }
+ end
+
+ def carre_of_jacks?
+ carre_of(:jack)
+ end
+
+ def carre_of_nines?
+ carre_of(9)
+ end
+
+ def carre_of_aces?
+ carre_of(:ace)
+ end
+
+ private
+
+ def carre_of(rank)
+ @hand.count { |card| card.rank == rank } == 4
+ end
+end
+
+class SixtySixDeck < Deck
+ def default_deck
+ RANKS.take(6).product(SUITS).collect { |rank, suit| Card.new(rank, suit) }
+ end
+
+ def deal
+ SixtySixHand.new(@cards.slice!(0, 6))
+ end
+
+ private
+
+ def compare(first, second)
+ suits = SUITS.index(first.suit) <=> SUITS.index(second.suit)
+ ranks = BELOTE_AND_SIXTY_SIX_RANKS.index(first.rank) <=>
+ BELOTE_AND_SIXTY_SIX_RANKS.index(second.rank)
+ compare_suits_and_ranks(suits, ranks)
+ end
+end
+
+class SixtySixHand < Hand
+ def twenty?(trump_suit)
+ @hand.select { |card| card.rank == :king || card.rank == :queen }
+ .reject { |card| card.suit == trump_suit }
+ .group_by(&:suit)
+ .any? { |_, cards_of_suit| cards_of_suit.size == 2 }
+ end
+
+ def forty?(trump_suit)
+ @hand.select { |card| card.rank == :king || card.rank == :queen }
+ .count { |card| card.suit == trump_suit } == 2
+ end
+end