Решение на Четвърта задача от Теодор Климентов

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

Към профила на Теодор Климентов

Резултати

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

Код

# => A classic playing card that has a suit and a rank
class Card
SUITS = [:spades, :hearts, :diamonds, :clubs]
RANKS = [:ace, :king, :queen, :jack].concat 10.downto(2).to_a
attr_reader :rank, :suit
def initialize(rank, suit)
@rank = rank
@suit = suit
end
def ==(other)
@rank == other.rank && @suit == other.suit
end
def to_s
"#{@rank.to_s.capitalize} of #{suit.to_s.capitalize}"
end
end
# => A set of rules for sorting a deck of cards
module GameRules
def sort_cards(cards)
cards.sort! do |left, right|
compared_suits = suit_index(left) <=> suit_index(right)
compared_ranks = rank_index(left) <=> rank_index(right)
compared_suits == 0 ? compared_ranks : compared_suits
end
end
def suit_index(card)
suits.index(card.suit)
end
def rank_index(card)
ranks.index(card.rank)
end
def suits
Card::SUITS
end
def ranks
Card::RANKS
end
def total_cards
suits.count * ranks.count
end
end
# => A deck of playing cards
class Deck < Array
include GameRules
def initialize(cards = nil)
super(cards || default_cards)
end
def default_cards
suits.product(ranks).map { |suit, rank| Card.new(rank, suit) }
end
def to_s
@cards.join("\n")
end
alias_method :top_card, :first
alias_method :bottom_card, :last
alias_method :draw_top_card, :shift
alias_method :draw_bottom_card, :pop
alias_method :shuffle, :shuffle!
def sort
sort_cards self
end
end
# => Cards that a player holds in his/hers hand to play with
class Hand < Array
include GameRules
def initialize(cards)
super sort_cards cards
end
end
# THE GAME OF WAR
# => A deck of cards, that follows the rules of "War"
class WarDeck < Deck
include GameRules
def deal
WarHand.new slice! 0...(total_cards / 2)
end
end
# => A hand of cards, that follows the rules of "War"
class WarHand < Array
include GameRules
alias_method :play_card, :pop
def allow_face_up?
size < 4
end
end
# THE GAME OF BELOTE
# => The rules of a real game of cards, unlike "War"... :)
module RealCardGameRules
include GameRules
def carre_of_rank?(rank)
4 == count { |card| card.rank == rank }
end
def sequence_of_size?(size)
suits.any? do |suit|
not get_sequences(suit, size).empty?
end
end
def get_sequences(suit, size)
each_cons(size).select do |cards|
cards.all? { |card| card.suit == suit } &&
sequence_of_ranks?(cards)
end
end
def sequence_of_ranks?(cards)
ranks.each_cons(cards.size).include? cards.map(&:rank)
end
def queen_and_king_of_suit?(suit)
get_sequences(suit, 2).any? do |cards|
[:king, :queen] == cards.map(&:rank)
end
end
end
# => The rules of "Belote"
module BeloteRules
include RealCardGameRules
BELOTE_RANKS = [0, 4, 1, 2, 3, 5, 6, 7].map { |x| Card::RANKS[x] }
def ranks
BELOTE_RANKS
end
end
# => A deck of cards, that follows the rules of "Belote"
class BeloteDeck < Deck
include BeloteRules
def deal
BeloteHand.new slice! 0...(total_cards / 4)
end
end
# => A hand of cards, that follows the rules of "Belote"
class BeloteHand < Hand
include BeloteRules
def highest_of_suit(suit)
select { |card| card.suit == suit }.first
end
def belote?
suits.any? { |suit| queen_and_king_of_suit? suit }
end
def tierce?
sequence_of_size? 3
end
def quarte?
sequence_of_size? 4
end
def quint?
sequence_of_size? 5
end
def carre_of_jacks?
carre_of_rank? :jack
end
def carre_of_nines?
carre_of_rank? 9
end
def carre_of_aces?
carre_of_rank? :ace
end
end
# THE GAME OF SIXTY SIX
# => The rules of "Sixty-Six"
module SixtySixRules
include RealCardGameRules
SIXTY_SIX_RANKS = [0, 4, 1, 2, 3, 5].map { |x| Card::RANKS[x] }
def ranks
SIXTY_SIX_RANKS
end
end
# => A deck of cards, that follows the rules of "Sixty-Six"
class SixtySixDeck < Deck
include SixtySixRules
def deal
SixtySixHand.new slice! 0...(total_cards / 4)
end
end
# => A hand of cards, that follows the rules of "Sixty-Six"
class SixtySixHand < Hand
include SixtySixRules
def twenty?(trump_suit)
non_trump_suits = suits - [trump_suit]
non_trump_suits.any? { |suit| queen_and_king_of_suit? suit }
end
def forty?(trump_suit)
queen_and_king_of_suit? trump_suit
end
end

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

...........F............F..........................F.....

Failures:

  1) 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 `join' for nil:NilClass
     Shared Example Group: "a deck" called from /tmp/d20151112-27349-7nsso3/spec.rb:140
     # /tmp/d20151112-27349-7nsso3/solution.rb:66:in `to_s'
     # /tmp/d20151112-27349-7nsso3/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)>'

  2) 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 `join' for nil:NilClass
     Shared Example Group: "a deck" called from /tmp/d20151112-27349-7nsso3/spec.rb:191
     # /tmp/d20151112-27349-7nsso3/solution.rb:66:in `to_s'
     # /tmp/d20151112-27349-7nsso3/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) 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 `join' for nil:NilClass
     Shared Example Group: "a deck" called from /tmp/d20151112-27349-7nsso3/spec.rb:400
     # /tmp/d20151112-27349-7nsso3/solution.rb:66:in `to_s'
     # /tmp/d20151112-27349-7nsso3/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)>'

Finished in 0.03951 seconds
57 examples, 3 failures

Failed examples:

rspec /tmp/d20151112-27349-7nsso3/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-7nsso3/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-7nsso3/spec.rb:67 # SixtySixDeck behaves like a deck #to_s returns the names of the cards, each on its own line

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

Теодор обнови решението на 09.11.2015 07:30 (преди над 8 години)

+# => A classic playing card that has a suit and a rank
+class Card
+ SUITS = [:spades, :hearts, :diamonds, :clubs]
+ RANKS = [:ace, :king, :queen, :jack].concat 10.downto(2).to_a
+
+ attr_reader :rank, :suit
+
+ def initialize(rank, suit)
+ @rank = rank
+ @suit = suit
+ end
+
+ def ==(other)
+ @rank == other.rank && @suit == other.suit
+ end
+
+ def to_s
+ "#{@rank.to_s.capitalize} of #{suit.to_s.capitalize}"
+ end
+end
+
+# => A set of rules for sorting a deck of cards
+module GameRules
+ def sort_cards(cards)
+ cards.sort! do |left, right|
+ compared_suits = suit_index(left) <=> suit_index(right)
+ compared_ranks = rank_index(left) <=> rank_index(right)
+ compared_suits == 0 ? compared_ranks : compared_suits
+ end
+ end
+
+ def suit_index(card)
+ suits.index(card.suit)
+ end
+
+ def rank_index(card)
+ ranks.index(card.rank)
+ end
+
+ def suits
+ Card::SUITS
+ end
+
+ def ranks
+ Card::RANKS
+ end
+
+ def total_cards
+ suits.count * ranks.count
+ end
+end
+
+# => A deck of playing cards
+class Deck < Array
+ include GameRules
+
+ def initialize(cards = nil)
+ super(cards || default_cards)
+ end
+
+ def default_cards
+ suits.product(ranks).map { |suit, rank| Card.new(rank, suit) }
+ end
+
+ def to_s
+ @cards.join("\n")
+ end
+
+ alias_method :top_card, :first
+ alias_method :bottom_card, :last
+
+ alias_method :draw_top_card, :shift
+ alias_method :draw_bottom_card, :pop
+
+ alias_method :shuffle, :shuffle!
+
+ def sort
+ sort_cards self
+ end
+end
+
+# => Cards that a player holds in his/hers hand to play with
+class Hand < Array
+ include GameRules
+
+ def initialize(cards)
+ super sort_cards cards
+ end
+end
+
+# THE GAME OF WAR
+
+# => A deck of cards, that follows the rules of "War"
+class WarDeck < Deck
+ include GameRules
+
+ def deal
+ WarHand.new slice! 0...(total_cards / 2)
+ end
+end
+
+# => A hand of cards, that follows the rules of "War"
+class WarHand < Array
+ include GameRules
+
+ alias_method :play_card, :pop
+
+ def allow_face_up?
+ size < 4
+ end
+end
+
+# THE GAME OF BELOTE
+
+# => The rules of a real game of cards, unlike "War"... :)
+module RealCardGameRules
+ include GameRules
+
+ def carre_of_rank?(rank)
+ 4 == count { |card| card.rank == rank }
+ end
+
+ def sequence_of_size?(size)
+ suits.any? do |suit|
+ not get_sequences(suit, size).empty?
+ end
+ end
+
+ def get_sequences(suit, size)
+ each_cons(size).select do |cards|
+ cards.all? { |card| card.suit == suit } &&
+ sequence_of_ranks?(cards)
+ end
+ end
+
+ def sequence_of_ranks?(cards)
+ ranks.each_cons(cards.size).include? cards.map(&:rank)
+ end
+
+ def queen_and_king_of_suit?(suit)
+ get_sequences(suit, 2).any? do |cards|
+ [:king, :queen] == cards.map(&:rank)
+ end
+ end
+end
+
+# => The rules of "Belote"
+module BeloteRules
+ include RealCardGameRules
+
+ BELOTE_RANKS = [0, 4, 1, 2, 3, 5, 6, 7].map { |x| Card::RANKS[x] }
+
+ def ranks
+ BELOTE_RANKS
+ end
+end
+
+# => A deck of cards, that follows the rules of "Belote"
+class BeloteDeck < Deck
+ include BeloteRules
+
+ def deal
+ BeloteHand.new slice! 0...(total_cards / 4)
+ end
+end
+
+# => A hand of cards, that follows the rules of "Belote"
+class BeloteHand < Hand
+ include BeloteRules
+
+ def highest_of_suit(suit)
+ sort_cards(select { |card| card.suit == suit }).last
+ end
+
+ def belote?
+ suits.any? { |suit| queen_and_king_of_suit? suit }
+ end
+
+ def tierce?
+ sequence_of_size? 3
+ end
+
+ def quarte?
+ sequence_of_size? 4
+ end
+
+ def quint?
+ sequence_of_size? 5
+ end
+
+ def carre_of_jacks?
+ carre_of_rank? :jack
+ end
+
+ def carre_of_nines?
+ carre_of_rank? 9
+ end
+
+ def carre_of_aces?
+ carre_of_rank? :ace
+ end
+end
+
+# THE GAME OF SIXTY SIX
+
+# => The rules of "Sixty-Six"
+module SixtySixRules
+ include RealCardGameRules
+
+ SIXTY_SIX_RANKS = [0, 4, 1, 2, 3, 5].map { |x| Card::RANKS[x] }
+
+ def ranks
+ SIXTY_SIX_RANKS
+ end
+end
+
+# => A deck of cards, that follows the rules of "Sixty-Six"
+class SixtySixDeck < Deck
+ include SixtySixRules
+
+ def deal
+ SixtySixHand.new slice! 0...(total_cards / 4)
+ end
+end
+
+# => A hand of cards, that follows the rules of "Sixty-Six"
+class SixtySixHand < Hand
+ include SixtySixRules
+
+ def twenty?(trump_suit)
+ non_trump_suits = suits - [trump_suit]
+ non_trump_suits.any? { |suit| queen_and_king_of_suit? suit }
+ end
+
+ def forty?(trump_suit)
+ queen_and_king_of_suit? trump_suit
+ end
+end

Теодор обнови решението на 11.11.2015 15:04 (преди над 8 години)

# => A classic playing card that has a suit and a rank
class Card
SUITS = [:spades, :hearts, :diamonds, :clubs]
RANKS = [:ace, :king, :queen, :jack].concat 10.downto(2).to_a
attr_reader :rank, :suit
def initialize(rank, suit)
@rank = rank
@suit = suit
end
def ==(other)
@rank == other.rank && @suit == other.suit
end
def to_s
"#{@rank.to_s.capitalize} of #{suit.to_s.capitalize}"
end
end
# => A set of rules for sorting a deck of cards
module GameRules
def sort_cards(cards)
cards.sort! do |left, right|
compared_suits = suit_index(left) <=> suit_index(right)
compared_ranks = rank_index(left) <=> rank_index(right)
compared_suits == 0 ? compared_ranks : compared_suits
end
end
def suit_index(card)
suits.index(card.suit)
end
def rank_index(card)
ranks.index(card.rank)
end
def suits
Card::SUITS
end
def ranks
Card::RANKS
end
def total_cards
suits.count * ranks.count
end
end
# => A deck of playing cards
class Deck < Array
include GameRules
def initialize(cards = nil)
super(cards || default_cards)
end
def default_cards
suits.product(ranks).map { |suit, rank| Card.new(rank, suit) }
end
def to_s
@cards.join("\n")
end
alias_method :top_card, :first
alias_method :bottom_card, :last
alias_method :draw_top_card, :shift
alias_method :draw_bottom_card, :pop
alias_method :shuffle, :shuffle!
def sort
sort_cards self
end
end
# => Cards that a player holds in his/hers hand to play with
class Hand < Array
include GameRules
def initialize(cards)
super sort_cards cards
end
end
# THE GAME OF WAR
# => A deck of cards, that follows the rules of "War"
class WarDeck < Deck
include GameRules
def deal
WarHand.new slice! 0...(total_cards / 2)
end
end
# => A hand of cards, that follows the rules of "War"
class WarHand < Array
include GameRules
alias_method :play_card, :pop
def allow_face_up?
size < 4
end
end
# THE GAME OF BELOTE
# => The rules of a real game of cards, unlike "War"... :)
module RealCardGameRules
include GameRules
def carre_of_rank?(rank)
4 == count { |card| card.rank == rank }
end
def sequence_of_size?(size)
suits.any? do |suit|
not get_sequences(suit, size).empty?
end
end
def get_sequences(suit, size)
each_cons(size).select do |cards|
cards.all? { |card| card.suit == suit } &&
sequence_of_ranks?(cards)
end
end
def sequence_of_ranks?(cards)
ranks.each_cons(cards.size).include? cards.map(&:rank)
end
def queen_and_king_of_suit?(suit)
get_sequences(suit, 2).any? do |cards|
[:king, :queen] == cards.map(&:rank)
end
end
end
# => The rules of "Belote"
module BeloteRules
include RealCardGameRules
BELOTE_RANKS = [0, 4, 1, 2, 3, 5, 6, 7].map { |x| Card::RANKS[x] }
def ranks
BELOTE_RANKS
end
end
# => A deck of cards, that follows the rules of "Belote"
class BeloteDeck < Deck
include BeloteRules
def deal
BeloteHand.new slice! 0...(total_cards / 4)
end
end
# => A hand of cards, that follows the rules of "Belote"
class BeloteHand < Hand
include BeloteRules
def highest_of_suit(suit)
- sort_cards(select { |card| card.suit == suit }).last
+ select { |card| card.suit == suit }.first
end
def belote?
suits.any? { |suit| queen_and_king_of_suit? suit }
end
def tierce?
sequence_of_size? 3
end
def quarte?
sequence_of_size? 4
end
def quint?
sequence_of_size? 5
end
def carre_of_jacks?
carre_of_rank? :jack
end
def carre_of_nines?
carre_of_rank? 9
end
def carre_of_aces?
carre_of_rank? :ace
end
end
# THE GAME OF SIXTY SIX
# => The rules of "Sixty-Six"
module SixtySixRules
include RealCardGameRules
SIXTY_SIX_RANKS = [0, 4, 1, 2, 3, 5].map { |x| Card::RANKS[x] }
def ranks
SIXTY_SIX_RANKS
end
end
# => A deck of cards, that follows the rules of "Sixty-Six"
class SixtySixDeck < Deck
include SixtySixRules
def deal
SixtySixHand.new slice! 0...(total_cards / 4)
end
end
# => A hand of cards, that follows the rules of "Sixty-Six"
class SixtySixHand < Hand
include SixtySixRules
def twenty?(trump_suit)
non_trump_suits = suits - [trump_suit]
non_trump_suits.any? { |suit| queen_and_king_of_suit? suit }
end
def forty?(trump_suit)
queen_and_king_of_suit? trump_suit
end
-end
+end

Този ред:

WarHand.new slice! 0...(total_cards / 2)

Е добре да се запише (поне) така:

WarHand.new slice!(0...(total_cards / 2))

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

От коментарите ти в кода няма никакъв смисъл, занапред не оставяй такива. Коментарът е code smell и трябва да се ползва много, много рядко - когато от самия код няма как да стане ясно защо е там този код.

Интересно, разбирам.

И все пак, тук не ползваме Rubocop, не оставяй такива коментари в задачите, които предаваш. Ако ти си ползваш инструмента Х у вас, това е чудесно, но не оставяй следи в кода, който "публикуваш".