Решение на Четвърта задача от Ивайло Чернев

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

Към профила на Ивайло Чернев

Резултати

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

Код

class Card
attr_reader :rank, :suit
def initialize(rank, suit)
@rank = rank
@suit = suit
end
def to_s
rank = (@rank.is_a? Symbol) ? @rank.capitalize : @rank
"#{rank} of #{@suit.capitalize}"
end
def ==(other)
@rank == other.rank && @suit == other.suit
end
end
class Deck
include Enumerable
def initialize(cards = nil)
@ranks = [2, 3, 4, 5, 6, 7, 8, 9, 10, :jack, :queen, :king, :ace]
@suits = [:spades, :hearts, :diamonds, :clubs]
if cards == nil
@cards = generate_deck
else
@cards = cards.dup
end
end
def each
@cards.each { |card| yield card }
end
def size
self.to_a.size
end
def draw_top_card
@cards.shift
end
def draw_bottom_card
@cards.delete_at -1
end
def top_card
@cards[0]
end
def bottom_card
@cards[-1]
end
def shuffle
@cards.shuffle!
end
def sort
@cards.sort! { |a, b| compare a, b }
end
def to_s
@cards.map(&:to_s).join("\n")
end
private
def generate_deck
product = @ranks.product @suits
product.map { |card| Card.new *card }
end
def compare(a, b)
a_rank, a_suit = @ranks.find_index(a.rank), @suits.find_index(a.suit)
b_rank, b_suit = @ranks.find_index(b.rank), @suits.find_index(b.suit)
if a_suit == b_suit
b_rank <=> a_rank
else
a_suit <=> b_suit
end
end
end
class Hand
def initialize(cards)
@cards = cards.dup
end
def size
@cards.size
end
end
class WarHand < Hand
def initialize(cards)
super
end
def play_card
@cards.delete_at 0
end
def allow_face_up?
@cards.size <= 3 ? true : false
end
end
class WarDeck < Deck
def initialize(cards = nil)
@hand_size = 26
super cards
end
def deal
hand = WarHand.new @cards[0 .. @hand_size - 1]
@cards = @cards.drop @hand_size
hand
end
end
class BeloteHand < Hand
def initialize(cards)
super
end
def highest_of_suit(suit)
deck = BeloteDeck.new @cards.select { |card| card.suit == suit }
deck.sort
deck.top_card
end
def belote?
groups = @cards.group_by { |card| card.suit }
filter = -> (card) { card.rank == :king || card.rank == :queen }
counts = groups.map { |g| g[1].select { |c| filter.call c }.size }
counts.any? { |g| g == 2 }
end
def tierce?
groups = @cards.group_by { |card| card.suit }
check = groups.map { |g| consecutive? g[1], 3 }
check.any? { |predicate| predicate == true }
end
def quarte?
groups = @cards.group_by { |card| card.suit }
check = groups.map { |g| consecutive? g[1], 4 }
check.any? { |predicate| predicate == true }
end
def quint?
groups = @cards.group_by { |card| card.suit }
check = groups.map { |g| consecutive? g[1], 5 }
check.any? { |predicate| predicate == true }
end
def carre_of_jacks?
amount_of_jacks = @cards.count { |card| card.rank == :jack }
amount_of_jacks == 4
end
def carre_of_nines?
amount_of_nines = @cards.count { |card| card.rank == 9 }
amount_of_nines == 4
end
def carre_of_aces?
amount_of_aces = @cards.count { |card| card.rank == :ace }
amount_of_aces == 4
end
private
def consecutive?(cards, count)
ranks = BeloteDeck.new.ranks
cards = cards.map { |c| ranks.find_index c.rank }.sort
last = cards[0]
groups = cards.slice_before do |e|
last, prev2 = e, last
prev2 + 1 != e
end
groups.to_a.any? { |group| group.size > 2 }
end
end
class BeloteDeck < Deck
attr_reader :ranks
def initialize(cards = nil)
@hand_size = 8
@ranks = [7, 8, 9, :jack, :queen, :king, 10, :ace]
@suits = [:spades, :hearts, :diamonds, :clubs]
if cards == nil
@cards = generate_deck
else
@cards = cards.dup
end
end
def deal
hand = BeloteHand.new @cards[0 .. @hand_size - 1]
@cards = @cards.drop @hand_size
hand
end
end
class SixtySixHand < Hand
def initialize(cards)
super
end
def twenty?(trump_suit)
groups = @cards.group_by { |card| card.suit }
filter = -> (card) do
(card.suit != trump_suit) and (card.rank == :king or card.rank == :queen)
end
counts = groups.map { |g| g[1].select { |c| filter.call c }.size }
counts.any? { |g| g == 2 }
end
def forty?(trump_suit)
groups = @cards.group_by { |card| card.suit }
filter = -> (card) do
(card.suit == trump_suit) and (card.rank == :king or card.rank == :queen)
end
counts = groups.map { |g| g[1].select { |c| filter.call c }.size }
counts.any? { |g| g == 2 }
end
end
class SixtySixDeck < Deck
def initialize(cards = nil)
@hand_size = 6
@ranks = [ 9, :jack, :queen, :king, 10, :ace]
@suits = [:spades, :hearts, :diamonds, :clubs]
if cards == nil
@cards = generate_deck
else
@cards = cards
end
end
def deal
hand = SixtySixHand.new @cards[0..@hand_size - 1]
@cards = @cards.drop @hand_size
hand
end
end

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

.........................................................

Finished in 0.04771 seconds
57 examples, 0 failures

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

Ивайло обнови решението на 11.11.2015 10:58 (преди около 9 години)

+class Card
+ attr_reader :rank, :suit
+ def initialize(rank, suit)
+ @rank = rank
+ @suit = suit
+ end
+ def to_s
+ rank = (@rank.is_a? Symbol) ? @rank.capitalize : @rank
+ "#{rank} of #{@suit.capitalize}"
+ end
+ def ==(other)
+ @rank == other.rank && @suit == other.suit
+ end
+end
+
+class Deck
+ include Enumerable
+
+ attr_reader :cards # TODO: REMOVE
+ def initialize(cards = nil)
+ @ranks = [2, 3, 4, 5, 6, 7, 8, 9, 10, :jack, :queen, :king, :ace]
+ @suits = [:spades, :hearts, :diamonds, :clubs]
+
+ if cards == nil
+ @cards = generate_deck
+ else
+ @cards = cards
+ end
+ end
+
+ def each
+ @cards.each { |card| yield card }
+ end
+
+ def size
+ self.to_a.size
+ end
+
+ def draw_top_card
+ @cards.shift
+ end
+
+ def draw_bottom_card
+ @cards.delete_at 1
+ end
+
+ def top_card
+ @cards[0]
+ end
+
+ def bottom_card
+ @cards[-1]
+ end
+
+ def shuffle
+ @cards.shuffle!
+ end
+
+ def sort
+ @cards.sort! { |a, b| compare a, b }
+ end
+
+ def to_s
+ @cards.map(&:to_s).join("\n")
+ end
+
+ private
+ def generate_deck
+ product = @ranks.product @suits
+ product.map { |card| Card.new *card }
+ end
+
+ def compare(a, b)
+ a_rank, a_suit = @ranks.find_index(a.rank), @suits.find_index(a.suit)
+ b_rank, b_suit = @ranks.find_index(b.rank), @suits.find_index(b.suit)
+ if a_suit == b_suit
+ b_rank <=> a_rank
+ else
+ a_suit <=> b_suit
+ end
+ end
+end
+
+class Hand
+ attr_accessor :cards
+ def initialize(cards)
+ @cards = cards
+ end
+
+ def size
+ @cards.size
+ end
+end
+
+class WarHand < Hand
+ def initialize(cards)
+ super
+ end
+
+ def play_card
+ @cards.delete_at 0
+ end
+
+ def allow_face_up?
+ @cards.size <= 3 ? true : false
+ end
+end
+
+class WarDeck < Deck
+ def initialize(cards = nil)
+ @hand_size = 26
+ super cards
+ end
+
+ def deal
+ WarHand.new @cards[0 .. @hand_size - 1]
+ end
+end
+
+class BeloteHand < Hand
+ def initialize(cards)
+ super
+ end
+
+ def highest_of_suit(suit)
+ deck = BeloteDeck.new @cards.select { |card| card.suit == suit }
+ deck.sort
+ deck.top_card
+ end
+
+ def belote?
+ groups = @cards.group_by { |card| card.suit }
+ filter = -> (card) { card.rank == :king || card.rank == :queen }
+ counts = groups.map { |g| g[1].select { |c| filter.call c }.size }
+ counts.any? { |g| g == 2 }
+ end
+
+ def tierce?
+ groups = @cards.group_by { |card| card.suit }
+ check = groups.map { |g| consecutive? g[1], 3 }
+ check.any? { |predicate| predicate == true }
+ end
+
+ def quarte?
+ groups = @cards.group_by { |card| card.suit }
+ check = groups.map { |g| consecutive? g[1], 4 }
+ check.any? { |predicate| predicate == true }
+ end
+
+ def quint?
+ groups = @cards.group_by { |card| card.suit }
+ check = groups.map { |g| consecutive? g[1], 5 }
+ check.any? { |predicate| predicate == true }
+ end
+
+ def carre_of_jacks?
+ amount_of_jacks = @cards.count { |card| card.rank == :jack }
+ amount_of_jacks == 4
+ end
+
+ def carre_of_nines?
+ amount_of_nines = @cards.count { |card| card.rank == 9 }
+ amount_of_nines == 4
+ end
+
+ def carre_of_aces?
+ amount_of_aces = @cards.count { |card| card.rank == :ace }
+ amount_of_aces == 4
+ end
+
+ private
+
+ def consecutive?(cards, count)
+ ranks = BeloteDeck.new.ranks
+ cards = cards.map { |c| ranks.find_index c.rank }.sort
+ last = cards[0]
+ groups = cards.slice_before do |e|
+ last, prev2 = e, last
+ prev2 + 1 != e
+ end
+ groups.to_a.any? { |group| group.size > 2 }
+ end
+end
+
+class BeloteDeck < Deck
+ attr_reader :ranks
+ def initialize(cards = nil)
+ @hand_size = 8
+ @ranks = [7, 8, 9, :jack, :queen, :king, 10, :ace]
+ @suits = [:spades, :hearts, :diamonds, :clubs]
+
+ if cards == nil
+ @cards = generate_deck
+ else
+ @cards = cards
+ end
+ end
+
+ def deal
+ BeloteHand.new @cards[0 .. @hand_size - 1]
+ end
+end
+
+class SixtySixHand < Hand
+ def initialize(cards)
+ super
+ end
+
+ def twenty?(trump_suit)
+ groups = @cards.group_by { |card| card.suit }
+ filter = -> (card) do
+ (card.suit != trump_suit) and (card.rank == :king or card.rank == :queen)
+ end
+ counts = groups.map { |g| g[1].select { |c| filter.call c }.size }
+ counts.any? { |g| g == 2 }
+ end
+
+ def forty?(trump_suit)
+ groups = @cards.group_by { |card| card.suit }
+ filter = -> (card) do
+ (card.suit == trump_suit) and (card.rank == :king or card.rank == :queen)
+ end
+ counts = groups.map { |g| g[1].select { |c| filter.call c }.size }
+ counts.any? { |g| g == 2 }
+ end
+end
+
+class SixtySixDeck < Deck
+ def initialize(cards = nil)
+ @hand_size = 6
+ @ranks = [ 9, :jack, :queen, :king, 10, :ace]
+ @suits = [:spades, :hearts, :diamonds, :clubs]
+
+ if cards == nil
+ @cards = generate_deck
+ else
+ @cards = cards
+ end
+ end
+
+ def deal
+ SixtySixHand.new @cards[0..@hand_size - 1]
+ end
+end

Ивайло обнови решението на 11.11.2015 16:56 (преди около 9 години)

class Card
attr_reader :rank, :suit
def initialize(rank, suit)
@rank = rank
@suit = suit
end
def to_s
rank = (@rank.is_a? Symbol) ? @rank.capitalize : @rank
"#{rank} of #{@suit.capitalize}"
end
def ==(other)
@rank == other.rank && @suit == other.suit
end
end
class Deck
include Enumerable
- attr_reader :cards # TODO: REMOVE
def initialize(cards = nil)
@ranks = [2, 3, 4, 5, 6, 7, 8, 9, 10, :jack, :queen, :king, :ace]
@suits = [:spades, :hearts, :diamonds, :clubs]
if cards == nil
@cards = generate_deck
else
- @cards = cards
+ @cards = cards.dup
end
end
def each
@cards.each { |card| yield card }
end
def size
self.to_a.size
end
def draw_top_card
@cards.shift
end
def draw_bottom_card
- @cards.delete_at 1
+ @cards.delete_at -1
end
def top_card
@cards[0]
end
def bottom_card
@cards[-1]
end
def shuffle
@cards.shuffle!
end
def sort
@cards.sort! { |a, b| compare a, b }
end
def to_s
@cards.map(&:to_s).join("\n")
end
private
def generate_deck
product = @ranks.product @suits
product.map { |card| Card.new *card }
end
def compare(a, b)
a_rank, a_suit = @ranks.find_index(a.rank), @suits.find_index(a.suit)
b_rank, b_suit = @ranks.find_index(b.rank), @suits.find_index(b.suit)
if a_suit == b_suit
b_rank <=> a_rank
else
a_suit <=> b_suit
end
end
end
class Hand
- attr_accessor :cards
def initialize(cards)
- @cards = cards
+ @cards = cards.dup
end
def size
@cards.size
end
end
class WarHand < Hand
def initialize(cards)
super
end
def play_card
@cards.delete_at 0
end
def allow_face_up?
@cards.size <= 3 ? true : false
end
end
class WarDeck < Deck
def initialize(cards = nil)
@hand_size = 26
super cards
end
def deal
- WarHand.new @cards[0 .. @hand_size - 1]
+ hand = WarHand.new @cards[0 .. @hand_size - 1]
+ @cards = @cards.drop @hand_size
+ hand
end
end
class BeloteHand < Hand
def initialize(cards)
super
end
def highest_of_suit(suit)
deck = BeloteDeck.new @cards.select { |card| card.suit == suit }
deck.sort
deck.top_card
end
def belote?
groups = @cards.group_by { |card| card.suit }
filter = -> (card) { card.rank == :king || card.rank == :queen }
counts = groups.map { |g| g[1].select { |c| filter.call c }.size }
counts.any? { |g| g == 2 }
end
def tierce?
groups = @cards.group_by { |card| card.suit }
check = groups.map { |g| consecutive? g[1], 3 }
check.any? { |predicate| predicate == true }
end
def quarte?
groups = @cards.group_by { |card| card.suit }
check = groups.map { |g| consecutive? g[1], 4 }
check.any? { |predicate| predicate == true }
end
def quint?
groups = @cards.group_by { |card| card.suit }
check = groups.map { |g| consecutive? g[1], 5 }
check.any? { |predicate| predicate == true }
end
def carre_of_jacks?
amount_of_jacks = @cards.count { |card| card.rank == :jack }
amount_of_jacks == 4
end
def carre_of_nines?
amount_of_nines = @cards.count { |card| card.rank == 9 }
amount_of_nines == 4
end
def carre_of_aces?
amount_of_aces = @cards.count { |card| card.rank == :ace }
amount_of_aces == 4
end
private
def consecutive?(cards, count)
ranks = BeloteDeck.new.ranks
cards = cards.map { |c| ranks.find_index c.rank }.sort
last = cards[0]
groups = cards.slice_before do |e|
last, prev2 = e, last
prev2 + 1 != e
end
groups.to_a.any? { |group| group.size > 2 }
end
end
class BeloteDeck < Deck
attr_reader :ranks
def initialize(cards = nil)
@hand_size = 8
@ranks = [7, 8, 9, :jack, :queen, :king, 10, :ace]
@suits = [:spades, :hearts, :diamonds, :clubs]
if cards == nil
@cards = generate_deck
else
- @cards = cards
+ @cards = cards.dup
end
end
def deal
- BeloteHand.new @cards[0 .. @hand_size - 1]
+ hand = BeloteHand.new @cards[0 .. @hand_size - 1]
+ @cards = @cards.drop @hand_size
+ hand
end
end
class SixtySixHand < Hand
def initialize(cards)
super
end
def twenty?(trump_suit)
groups = @cards.group_by { |card| card.suit }
filter = -> (card) do
(card.suit != trump_suit) and (card.rank == :king or card.rank == :queen)
end
counts = groups.map { |g| g[1].select { |c| filter.call c }.size }
counts.any? { |g| g == 2 }
end
def forty?(trump_suit)
groups = @cards.group_by { |card| card.suit }
filter = -> (card) do
(card.suit == trump_suit) and (card.rank == :king or card.rank == :queen)
end
counts = groups.map { |g| g[1].select { |c| filter.call c }.size }
counts.any? { |g| g == 2 }
end
end
class SixtySixDeck < Deck
def initialize(cards = nil)
@hand_size = 6
@ranks = [ 9, :jack, :queen, :king, 10, :ace]
@suits = [:spades, :hearts, :diamonds, :clubs]
if cards == nil
@cards = generate_deck
else
@cards = cards
end
end
def deal
- SixtySixHand.new @cards[0..@hand_size - 1]
+ hand = SixtySixHand.new @cards[0..@hand_size - 1]
+ @cards = @cards.drop @hand_size
+ hand
end
end
  • виж какво прави @cards ||= generate_deck
  • сравненията вече връщат boolean, няма нужда от тернарен оператор
  • не ми харесват имената на променливите и алгоритмите на места

Стилът в решението може да се подобри.

Имаш и проблеми със спазването на конвенциите на места, направи справка с ръководството за стил. На ръба си да ти отнема точка за това. Постарай се повече за бъдещи решения.

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