Андрея обнови решението на 11.11.2015 16:09 (преди около 9 години)
+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
Като цяло ми допада.
Прегледай решенията на колеги и нашето примерно решение за алтернативни идеи къде може да стане по-добре.