Мартин обнови решението на 09.11.2015 17:40 (преди около 9 години)
+class Card
+ def initialize(rank, suit, *points)
+ @rank = rank
+ @suit = suit
+ @points = points
+ end
+
+ def rank
+ @rank
+ end
+
+ def suit
+ @suit
+ end
+
+ def to_s
+ @rank.to_s.capitalize + " of " + @suit.to_s.capitalize
+ end
+
+ def ==(card)
+ self.to_s == card.to_s
+ end
+
+ def points
+ @points
+ end
+
+ def assign_points(value)
+ @points = value
+ self
+ end
+end
+
+class Deck
+ include Enumerable
+
+ def initialize(
+ cards = generate_deck(
+ [2, 3, 4, 5, 6, 7, 8, 9, 10, :jack, :queen, :king, :ace]))
+ @cards = cards
+ end
+
+ def size
+ @cards.size
+ end
+
+ def draw_top_card
+ @cards.shift
+ end
+
+ def draw_bottom_card
+ @cards.pop
+ end
+
+ def top_card
+ @cards.first
+ end
+
+ def bottom_card
+ @cards.top
+ end
+
+ def shuffle
+ @cards.shuffle!
+ self
+ end
+
+ def sort
+ suits = {:spades => 1, :hearts => 2, :diamonds => 3, :clubs => 4}
+ @cards.sort! do |first_card, second_card|
+ if suits[first_card.suit] > suits[second_card.suit] then 1
+ elsif suits[first_card.suit] == suits[second_card.suit]
+ check_equal_points(first_card, second_card)
+ else -1 end
+ end
+ self
+ end
+
+ def to_s
+ @cards.each { |card| puts card }
+ end
+
+ def deal(size)
+ @cards.slice!(0, size)
+ end
+
+ def each(&block)
+ @cards.each(&block)
+ end
+
+ private
+ def generate_deck(ranks)
+ suits = [:spades, :hearts, :diamonds, :clubs]
+ stack_of_cards = []
+ suits.each do |suit|
+ ranks.size.times do |i|
+ stack_of_cards << Card.new(ranks[i], suit, i + 1)
+ end
+ end
+ stack_of_cards
+ end
+
+ def check_equal_points(first_card, second_card)
+ if first_card.points > second_card.points
+ -1
+ elsif first_card.points == second_card.points
+ 0
+ else
+ 1
+ end
+ end
+
+ def assign_deck_points(cards, points)
+ points = Hash[*(points.zip([*1..13]).flatten)]
+ cards.each { |card| card.assign_points(points[card.rank])}
+ cards
+ end
+end
+
+class Hand
+ def initialize (hand)
+ @cards_in_hand = hand
+ end
+
+ def size
+ @cards_in_hand.size
+ end
+end
+
+class WarDeck < Deck
+ def initialize(
+ cards = generate_deck(
+ [2, 3, 4, 5, 6, 7, 8, 9, 10, :jack, :queen, :king, :ace]))
+ @cards = assign_deck_points(
+ cards, [2, 3, 4, 5, 6, 7, 8, 9, 10, :jack, :queen, :king, :ace])
+ end
+
+ def deal
+ hand = super(26)
+ WarHand.new(hand)
+ end
+end
+
+class WarHand < Hand
+ def play_card
+ @cards_in_hand.shift
+ end
+
+ def allow_face_up?
+ @cards_in_hand.size <= 3 ? true : false
+ end
+end
+
+class BeloteDeck < Deck
+ def initialize(
+ cards = generate_deck(
+ [7, 8, 9, :jack, :queen, :king, 10, :ace]))
+ @cards = assign_deck_points(
+ cards, [7, 8, 9, :jack, :queen, :king, 10, :ace])
+ end
+
+ def deal
+ hand = super(8)
+ BeloteHand.new(hand)
+ end
+end
+
+class BeloteHand < Hand
+
+ def highest_of_suit(suit)
+ select_suited(suit).max_by { |card| card.points}
+ end
+
+ def belote?
+ suits = [:spades, :hearts, :diamonds, :clubs]
+ suits.each do |suit|
+ if count_queen_king(@cards, suit) == 2
+ then return true else false end
+ end
+ end
+
+ def count_queen_king(cards, suit)
+ cards.each do |card|
+ if (card.suit == suit and
+ card.rank = :queen or card.rank == :king)
+ i += 1
+ end
+ end
+ i
+ end
+
+ def tierce?
+ check_suits(3)
+ end
+
+ def quarte?
+ check_suits(4)
+ end
+
+ def quint?
+ check_suits(5)
+ end
+
+ def carre_of_jacks?
+ check_for_carre?(11)
+ end
+
+ def carre_of_nines?
+ check_for_carre?(9)
+ end
+
+ def carre_of_aces?
+ check_for_carre?(14)
+ end
+
+ def array
+ @cards_in_hand
+ end
+
+ private
+ def check_suits(count)
+ suits = [:spades, :hearts, :diamonds, :clubs]
+ suits.each do |suit|
+ includes_following_ranks?(
+ select_suited(suit), count) ? (return true) : false
+ end
+ false
+ end
+ def select_suited(suit)
+ @cards_in_hand.select { |card| card.suit == suit }
+ end
+
+ def includes_following_ranks?(array, count)
+ sorted_array = array.map { |card| card.points }.sort
+ consecutive = 1
+ array.size.times do |i|
+ if sorted_array[i] == nums[i - 1] + 1
+ consecutive += 1
+ else
+ consecutive = 1
+ end
+ if consecutive == count then return true end
+ end
+ end
+
+ def check_for_carre?(points)
+ @cards_in_hand.map { |card| card.points }.count(points) == 4 ? true : false
+ end
+end
+
+class SixtySixDeck < Deck
+ def initialize(cards = generate_deck([9, :jack, :queen, :king, 10, :ace]))
+ @cards = assign_deck_points(cards, [9, :jack, :queen, :king, 10, :ace])
+ end
+
+ def deal
+ hand = super(6)
+ SixtySixHand.new(hand)
+ end
+end
+
+class SixtySixHand < Hand
+ def twenty?(trump_suit)
+ suits = [:spades, :hearts, :diamonds, :clubs] - [trump_suit]
+ suits.each { |suit| if queen_king_suit?(suit) then return true end }
+ false
+ end
+
+ def forty?(trump_suit)
+ queen_king_suit?(trump_suit)
+ end
+
+ private
+ def queen_king_suit?(suit)
+ ranks = @cards_in_hand.select {
+ |card| card.suit == suit }.map { |card| card.rank }
+
+ ranks.include?(:queen) && ranks.include?(:king)
+ end
+end