Решение на Четвърта задача от Димитър Узунов

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

Към профила на Димитър Узунов

Резултати

  • 4 точки от тестове
  • 0 бонус точки
  • 4 точки общо
  • 39 успешни тест(а)
  • 18 неуспешни тест(а)

Код

class Card
attr_reader :rank, :suit
def initialize(rank, suit)
@rank, @suit = rank, suit
end
def to_s
rank.to_s.capitalize + ' of ' + suit.to_s.capitalize
end
def ==(other)
rank == other.rank and suit == other.suit
end
end
class Deck
include Enumerable
def initialize(cards = generate_deck)
@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.last
end
def shuffle
@cards.shuffle!
end
def sort
suits_order = {}
suits.each_with_index { |suit, index| suits_order[suit] = index }
ranks_order = {}
ranks.each_with_index { |rank, index| ranks_order[rank] = -index }
@cards.sort_by! { |card| [suits_order[card.suit], ranks_order[card.rank]] }
end
def to_s
@cards.map(&:to_s).join("\n")
end
def deal(cards_count)
cards_in_hand = @cards.shift(cards_count)
end
private
def suits
[:spades, :hearts, :diamonds, :clubs]
end
def ranks
[2, 3, 4, 5, 6, 7, 8, 9, 10, :jack, :queen, :king, :ace]
end
def generate_deck
ranks.product(suits).map { |rank, suit| Card.new(rank, suit) }
end
end
class WarDeck < Deck
def deal
WarHand.new(super(26))
end
end
class WarHand < WarDeck
def play_card
draw_bottom_card
end
def allow_face_up?
size <= 3
end
end
class BeloteDeck < Deck
def deal
BeloteHand.new(super(8))
end
private
def ranks
[7, 8, 9, :jack, :queen, :king, 10, :ace]
end
end
module CardMethods
def same_suit?(cards)
cards.all? { |card| card.suit == cards.first.suit }
end
def belote_pair?(pair)
pair.first.rank == :king and pair.last.rank == :queen and same_suit?(pair)
end
def sequential?(cards)
ranks_of_cards = cards.map(&:rank)
ranks.reverse.each_cons(cards.size).any? { |ranks| ranks == ranks_of_cards }
end
def n_sequential_cards?(n)
sort.each_cons(n).any? { |cards| sequential?(cards) and same_suit?(cards) }
end
def carre_of_rank?(rank)
@cards.count { |card| card.rank == rank } == 4
end
def card_of_trump_suit?(card, trump_suit)
card.suit == trump_suit
end
def twenty_pair?(pair, trump_suit)
belote_pair?(pair) and not card_of_trump_suit?(pair.first, trump_suit)
end
def forty_pair?(pair, trump_suit)
belote_pair?(pair) and card_of_trump_suit?(pair.first, trump_suit)
end
end
class BeloteHand < BeloteDeck
include CardMethods
def highest_of_suit(suit)
sort.detect { |card| card.suit == suit }
end
def belote?
sort.each_cons(2).any? { |pair| belote_pair?(pair) }
end
def tierce?
n_sequential_cards?(3)
end
def quarte?
n_sequential_cards?(4)
end
def quint?
n_sequential_cards?(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
class SixtySixDeck < Deck
def deal
SixtySixHand.new(super(6))
end
private
def ranks
[9, :jack, :queen, :king, 10, :ace]
end
end
class SixtySixHand < SixtySixDeck
include CardMethods
def twenty?(trump_suit)
sort.each_cons(2).any? { |pair| twenty_pair?(pair, trump_suit) }
end
def forty?(trump_suit)
sort.each_cons(2).any? { |pair| forty_pair?(pair, trump_suit) }
end
end

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

...FF.FFFF......FF.FFFF....................FF.FFFF.......

Failures:

  1) WarDeck behaves like a deck implements Enumerable
     Failure/Error: expect(small_deck).to respond_to(:each)
       expected #<WarDeck:0x007f7ac1955e78 @cards=[#<Card:0x007f7ac19560f8 @rank=:ace, @suit=:spades>, #<Card:0x007f7ac1956030 @rank=9, @suit=:clubs>]> to respond to :each
     Shared Example Group: "a deck" called from /tmp/d20151112-27349-lq0nur/spec.rb:140
     # /tmp/d20151112-27349-lq0nur/spec.rb:10:in `block (2 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) WarDeck behaves like a deck fills the deck if no initialize parameters are given
     Failure/Error: expect(deck.to_a).to match_array all_available_cards
     NoMethodError:
       undefined method `each' for #<WarDeck:0x007f7ac193d698>
     Shared Example Group: "a deck" called from /tmp/d20151112-27349-lq0nur/spec.rb:140
     # /tmp/d20151112-27349-lq0nur/spec.rb:18:in `to_a'
     # /tmp/d20151112-27349-lq0nur/spec.rb:18:in `block (2 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) WarDeck behaves like a deck #draw_top_card pops the top-most card
     Failure/Error: expect(small_deck.to_a).to eq [nine_of_clubs]
     NoMethodError:
       undefined method `each' for #<WarDeck:0x007f7ac27b1d50>
     Shared Example Group: "a deck" called from /tmp/d20151112-27349-lq0nur/spec.rb:140
     # /tmp/d20151112-27349-lq0nur/spec.rb:30:in `to_a'
     # /tmp/d20151112-27349-lq0nur/spec.rb:30: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)>'

  4) WarDeck behaves like a deck #draw_bottom_card pops the bottom-most card
     Failure/Error: expect(small_deck.to_a).to eq [ace_of_spades]
     NoMethodError:
       undefined method `each' for #<WarDeck:0x007f7ac2817920>
     Shared Example Group: "a deck" called from /tmp/d20151112-27349-lq0nur/spec.rb:140
     # /tmp/d20151112-27349-lq0nur/spec.rb:37:in `to_a'
     # /tmp/d20151112-27349-lq0nur/spec.rb:37: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)>'

  5) WarDeck behaves like a deck #top peeks at the top-most card
     Failure/Error: expect(small_deck.to_a).to eq [ace_of_spades, nine_of_clubs]
     NoMethodError:
       undefined method `each' for #<WarDeck:0x007f7ac27d7e88>
     Shared Example Group: "a deck" called from /tmp/d20151112-27349-lq0nur/spec.rb:140
     # /tmp/d20151112-27349-lq0nur/spec.rb:44:in `to_a'
     # /tmp/d20151112-27349-lq0nur/spec.rb:44: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)>'

  6) WarDeck behaves like a deck #bottom peeks at the bottom-most card
     Failure/Error: expect(small_deck.to_a).to eq [ace_of_spades, nine_of_clubs]
     NoMethodError:
       undefined method `each' for #<WarDeck:0x007f7ac27d55c0>
     Shared Example Group: "a deck" called from /tmp/d20151112-27349-lq0nur/spec.rb:140
     # /tmp/d20151112-27349-lq0nur/spec.rb:51:in `to_a'
     # /tmp/d20151112-27349-lq0nur/spec.rb:51: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)>'

  7) BeloteDeck behaves like a deck implements Enumerable
     Failure/Error: expect(small_deck).to respond_to(:each)
       expected #<BeloteDeck:0x007f7ac27ecdb0 @cards=[#<Card:0x007f7ac27ecf90 @rank=:ace, @suit=:spades>, #<Card:0x007f7ac27ecf40 @rank=9, @suit=:clubs>]> to respond to :each
     Shared Example Group: "a deck" called from /tmp/d20151112-27349-lq0nur/spec.rb:191
     # /tmp/d20151112-27349-lq0nur/spec.rb:10:in `block (2 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)>'

  8) BeloteDeck behaves like a deck fills the deck if no initialize parameters are given
     Failure/Error: expect(deck.to_a).to match_array all_available_cards
     NoMethodError:
       undefined method `each' for #<BeloteDeck:0x007f7ac27ae600>
     Shared Example Group: "a deck" called from /tmp/d20151112-27349-lq0nur/spec.rb:191
     # /tmp/d20151112-27349-lq0nur/spec.rb:18:in `to_a'
     # /tmp/d20151112-27349-lq0nur/spec.rb:18:in `block (2 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)>'

  9) BeloteDeck behaves like a deck #draw_top_card pops the top-most card
     Failure/Error: expect(small_deck.to_a).to eq [nine_of_clubs]
     NoMethodError:
       undefined method `each' for #<BeloteDeck:0x007f7ac27a00f0>
     Shared Example Group: "a deck" called from /tmp/d20151112-27349-lq0nur/spec.rb:191
     # /tmp/d20151112-27349-lq0nur/spec.rb:30:in `to_a'
     # /tmp/d20151112-27349-lq0nur/spec.rb:30: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)>'

  10) BeloteDeck behaves like a deck #draw_bottom_card pops the bottom-most card
     Failure/Error: expect(small_deck.to_a).to eq [ace_of_spades]
     NoMethodError:
       undefined method `each' for #<BeloteDeck:0x007f7ac27985a8>
     Shared Example Group: "a deck" called from /tmp/d20151112-27349-lq0nur/spec.rb:191
     # /tmp/d20151112-27349-lq0nur/spec.rb:37:in `to_a'
     # /tmp/d20151112-27349-lq0nur/spec.rb:37: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)>'

  11) BeloteDeck behaves like a deck #top peeks at the top-most card
     Failure/Error: expect(small_deck.to_a).to eq [ace_of_spades, nine_of_clubs]
     NoMethodError:
       undefined method `each' for #<BeloteDeck:0x007f7ac278dfb8>
     Shared Example Group: "a deck" called from /tmp/d20151112-27349-lq0nur/spec.rb:191
     # /tmp/d20151112-27349-lq0nur/spec.rb:44:in `to_a'
     # /tmp/d20151112-27349-lq0nur/spec.rb:44: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)>'

  12) BeloteDeck behaves like a deck #bottom peeks at the bottom-most card
     Failure/Error: expect(small_deck.to_a).to eq [ace_of_spades, nine_of_clubs]
     NoMethodError:
       undefined method `each' for #<BeloteDeck:0x007f7ac2785520>
     Shared Example Group: "a deck" called from /tmp/d20151112-27349-lq0nur/spec.rb:191
     # /tmp/d20151112-27349-lq0nur/spec.rb:51:in `to_a'
     # /tmp/d20151112-27349-lq0nur/spec.rb:51: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)>'

  13) SixtySixDeck behaves like a deck implements Enumerable
     Failure/Error: expect(small_deck).to respond_to(:each)
       expected #<SixtySixDeck:0x007f7ac25bf8a8 @cards=[#<Card:0x007f7ac25bf998 @rank=:ace, @suit=:spades>, #<Card:0x007f7ac25bf920 @rank=9, @suit=:clubs>]> to respond to :each
     Shared Example Group: "a deck" called from /tmp/d20151112-27349-lq0nur/spec.rb:400
     # /tmp/d20151112-27349-lq0nur/spec.rb:10:in `block (2 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)>'

  14) SixtySixDeck behaves like a deck fills the deck if no initialize parameters are given
     Failure/Error: expect(deck.to_a).to match_array all_available_cards
     NoMethodError:
       undefined method `each' for #<SixtySixDeck:0x007f7ac25bd800>
     Shared Example Group: "a deck" called from /tmp/d20151112-27349-lq0nur/spec.rb:400
     # /tmp/d20151112-27349-lq0nur/spec.rb:18:in `to_a'
     # /tmp/d20151112-27349-lq0nur/spec.rb:18:in `block (2 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)>'

  15) SixtySixDeck behaves like a deck #draw_top_card pops the top-most card
     Failure/Error: expect(small_deck.to_a).to eq [nine_of_clubs]
     NoMethodError:
       undefined method `each' for #<SixtySixDeck:0x007f7ac258be40>
     Shared Example Group: "a deck" called from /tmp/d20151112-27349-lq0nur/spec.rb:400
     # /tmp/d20151112-27349-lq0nur/spec.rb:30:in `to_a'
     # /tmp/d20151112-27349-lq0nur/spec.rb:30: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)>'

  16) SixtySixDeck behaves like a deck #draw_bottom_card pops the bottom-most card
     Failure/Error: expect(small_deck.to_a).to eq [ace_of_spades]
     NoMethodError:
       undefined method `each' for #<SixtySixDeck:0x007f7ac255eee0>
     Shared Example Group: "a deck" called from /tmp/d20151112-27349-lq0nur/spec.rb:400
     # /tmp/d20151112-27349-lq0nur/spec.rb:37:in `to_a'
     # /tmp/d20151112-27349-lq0nur/spec.rb:37: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)>'

  17) SixtySixDeck behaves like a deck #top peeks at the top-most card
     Failure/Error: expect(small_deck.to_a).to eq [ace_of_spades, nine_of_clubs]
     NoMethodError:
       undefined method `each' for #<SixtySixDeck:0x007f7ac255c730>
     Shared Example Group: "a deck" called from /tmp/d20151112-27349-lq0nur/spec.rb:400
     # /tmp/d20151112-27349-lq0nur/spec.rb:44:in `to_a'
     # /tmp/d20151112-27349-lq0nur/spec.rb:44: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)>'

  18) SixtySixDeck behaves like a deck #bottom peeks at the bottom-most card
     Failure/Error: expect(small_deck.to_a).to eq [ace_of_spades, nine_of_clubs]
     NoMethodError:
       undefined method `each' for #<SixtySixDeck:0x007f7ac2551240>
     Shared Example Group: "a deck" called from /tmp/d20151112-27349-lq0nur/spec.rb:400
     # /tmp/d20151112-27349-lq0nur/spec.rb:51:in `to_a'
     # /tmp/d20151112-27349-lq0nur/spec.rb:51: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.03814 seconds
57 examples, 18 failures

Failed examples:

rspec /tmp/d20151112-27349-lq0nur/spec.rb:8 # WarDeck behaves like a deck implements Enumerable
rspec /tmp/d20151112-27349-lq0nur/spec.rb:14 # WarDeck behaves like a deck fills the deck if no initialize parameters are given
rspec /tmp/d20151112-27349-lq0nur/spec.rb:28 # WarDeck behaves like a deck #draw_top_card pops the top-most card
rspec /tmp/d20151112-27349-lq0nur/spec.rb:35 # WarDeck behaves like a deck #draw_bottom_card pops the bottom-most card
rspec /tmp/d20151112-27349-lq0nur/spec.rb:42 # WarDeck behaves like a deck #top peeks at the top-most card
rspec /tmp/d20151112-27349-lq0nur/spec.rb:49 # WarDeck behaves like a deck #bottom peeks at the bottom-most card
rspec /tmp/d20151112-27349-lq0nur/spec.rb:8 # BeloteDeck behaves like a deck implements Enumerable
rspec /tmp/d20151112-27349-lq0nur/spec.rb:14 # BeloteDeck behaves like a deck fills the deck if no initialize parameters are given
rspec /tmp/d20151112-27349-lq0nur/spec.rb:28 # BeloteDeck behaves like a deck #draw_top_card pops the top-most card
rspec /tmp/d20151112-27349-lq0nur/spec.rb:35 # BeloteDeck behaves like a deck #draw_bottom_card pops the bottom-most card
rspec /tmp/d20151112-27349-lq0nur/spec.rb:42 # BeloteDeck behaves like a deck #top peeks at the top-most card
rspec /tmp/d20151112-27349-lq0nur/spec.rb:49 # BeloteDeck behaves like a deck #bottom peeks at the bottom-most card
rspec /tmp/d20151112-27349-lq0nur/spec.rb:8 # SixtySixDeck behaves like a deck implements Enumerable
rspec /tmp/d20151112-27349-lq0nur/spec.rb:14 # SixtySixDeck behaves like a deck fills the deck if no initialize parameters are given
rspec /tmp/d20151112-27349-lq0nur/spec.rb:28 # SixtySixDeck behaves like a deck #draw_top_card pops the top-most card
rspec /tmp/d20151112-27349-lq0nur/spec.rb:35 # SixtySixDeck behaves like a deck #draw_bottom_card pops the bottom-most card
rspec /tmp/d20151112-27349-lq0nur/spec.rb:42 # SixtySixDeck behaves like a deck #top peeks at the top-most card
rspec /tmp/d20151112-27349-lq0nur/spec.rb:49 # SixtySixDeck behaves like a deck #bottom peeks at the bottom-most card

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

Димитър обнови решението на 09.11.2015 23:10 (преди около 9 години)

+class Card
+ attr_reader :rank, :suit
+
+ def initialize(rank, suit)
+ @rank, @suit = rank, suit
+ end
+
+ def to_s
+ rank.to_s.capitalize + ' of ' + suit.to_s.capitalize
+ end
+
+ def ==(other)
+ rank == other.rank and suit == other.suit
+ end
+end
+
+class Deck
+ include Enumerable
+
+ def initialize(cards = generate_deck)
+ @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.last
+ end
+
+ def shuffle
+ @cards.shuffle!
+ end
+
+ def sort
+ suits_order = {}
+ suits.each_with_index { |suit, index| suits_order[suit] = index }
+
+ ranks_order = {}
+ ranks.each_with_index { |rank, index| ranks_order[rank] = - index }
+
+ @cards.sort_by! { |card| [suits_order[card.suit], ranks_order[card.rank]] }
+ end
+
+ def to_s
+ @cards.map(&:to_s).join("\n")
+ end
+
+ def deal(cards_count)
+ cards_in_hand = @cards.shift(cards_count)
+ end
+
+ private
+
+ def suits
+ [:spades, :hearts, :diamonds, :clubs]
+ end
+
+ def ranks
+ [2, 3, 4, 5, 6, 7, 8, 9, 10, :jack, :queen, :king, :ace]
+ end
+
+ def generate_deck
+ ranks.product(suits).map { |rank, suit| Card.new(rank, suit) }
+ end
+end
+
+class WarDeck < Deck
+ def deal
+ WarHand.new(super(26))
+ end
+end
+
+class WarHand < WarDeck
+ def play_card
+ draw_bottom_card
+ end
+
+ def allow_face_up?
+ size <= 3
+ end
+end
+
+class BeloteDeck < Deck
+ def deal
+ BeloteHand.new(super(8))
+ end
+
+ private
+
+ def ranks
+ [7, 8, 9, :jack, :queen, :king, 10, :ace]
+ end
+end
+
+module CardMethods
+ def same_suit?(cards)
+ cards.all? { |card| card.suit == cards.first.suit }
+ end
+
+ def belote_pair?(pair)
+ pair.first.rank == :king and pair.last.rank == :queen and same_suit?(pair)
+ end
+
+ def sequential?(cards)
+ ranks_of_cards = cards.map(&:rank)
+ ranks.reverse.each_cons(cards.size).any? { |ranks| ranks == ranks_of_cards }
+ end
+
+ def n_sequential_cards?(n)
+ sort.each_cons(n).any? { |cards| sequential?(cards) and same_suit?(cards) }
+ end
+
+ def carre_of_rank?(rank)
+ @cards.count { |card| card.rank == rank } == 4
+ end
+
+ def card_of_trump_suit?(card, trump_suit)
+ card.suit == trump_suit
+ end
+
+ def twenty_pair?(pair, trump_suit)
+ belote_pair?(pair) and not card_of_trump_suit?(pair.first, trump_suit)
+ end
+
+ def forty_pair?(pair, trump_suit)
+ belote_pair?(pair) and card_of_trump_suit?(pair.first, trump_suit)
+ end
+end
+
+class BeloteHand < BeloteDeck
+ include CardMethods
+
+ def highest_of_suit(suit)
+ sort.detect { |card| card.suit == suit }
+ end
+
+ def belote?
+ sort.each_cons(2).any? { |pair| belote_pair?(pair) }
+ end
+
+ def tierce?
+ n_sequential_cards?(3)
+ end
+
+ def quarte?
+ n_sequential_cards?(4)
+ end
+
+ def quint?
+ n_sequential_cards?(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
+
+class SixtySixDeck < Deck
+ def deal
+ SixtySixHand.new(super(6))
+ end
+
+ private
+
+ def ranks
+ [9, :jack, :queen, :king, 10, :ace]
+ end
+end
+
+class SixtySixHand < SixtySixDeck
+ include CardMethods
+
+ def twenty?(trump_suit)
+ sort.each_cons(2).any? { |pair| twenty_pair?(pair, trump_suit) }
+ end
+
+ def forty?(trump_suit)
+ sort.each_cons(2).any? { |pair| forty_pair?(pair, trump_suit) }
+ end
+end

Димитър обнови решението на 10.11.2015 20:22 (преди около 9 години)

class Card
attr_reader :rank, :suit
def initialize(rank, suit)
@rank, @suit = rank, suit
end
def to_s
rank.to_s.capitalize + ' of ' + suit.to_s.capitalize
end
def ==(other)
rank == other.rank and suit == other.suit
end
end
class Deck
include Enumerable
def initialize(cards = generate_deck)
@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.last
end
def shuffle
@cards.shuffle!
end
def sort
suits_order = {}
suits.each_with_index { |suit, index| suits_order[suit] = index }
ranks_order = {}
- ranks.each_with_index { |rank, index| ranks_order[rank] = - index }
+ ranks.each_with_index { |rank, index| ranks_order[rank] = -index }
@cards.sort_by! { |card| [suits_order[card.suit], ranks_order[card.rank]] }
end
def to_s
@cards.map(&:to_s).join("\n")
end
def deal(cards_count)
cards_in_hand = @cards.shift(cards_count)
end
private
def suits
[:spades, :hearts, :diamonds, :clubs]
end
def ranks
[2, 3, 4, 5, 6, 7, 8, 9, 10, :jack, :queen, :king, :ace]
end
def generate_deck
ranks.product(suits).map { |rank, suit| Card.new(rank, suit) }
end
end
class WarDeck < Deck
def deal
WarHand.new(super(26))
end
end
class WarHand < WarDeck
def play_card
draw_bottom_card
end
def allow_face_up?
size <= 3
end
end
class BeloteDeck < Deck
def deal
BeloteHand.new(super(8))
end
private
def ranks
[7, 8, 9, :jack, :queen, :king, 10, :ace]
end
end
module CardMethods
def same_suit?(cards)
cards.all? { |card| card.suit == cards.first.suit }
end
def belote_pair?(pair)
pair.first.rank == :king and pair.last.rank == :queen and same_suit?(pair)
end
def sequential?(cards)
ranks_of_cards = cards.map(&:rank)
ranks.reverse.each_cons(cards.size).any? { |ranks| ranks == ranks_of_cards }
end
def n_sequential_cards?(n)
sort.each_cons(n).any? { |cards| sequential?(cards) and same_suit?(cards) }
end
def carre_of_rank?(rank)
@cards.count { |card| card.rank == rank } == 4
end
def card_of_trump_suit?(card, trump_suit)
card.suit == trump_suit
end
def twenty_pair?(pair, trump_suit)
belote_pair?(pair) and not card_of_trump_suit?(pair.first, trump_suit)
end
def forty_pair?(pair, trump_suit)
belote_pair?(pair) and card_of_trump_suit?(pair.first, trump_suit)
end
end
class BeloteHand < BeloteDeck
include CardMethods
def highest_of_suit(suit)
sort.detect { |card| card.suit == suit }
end
def belote?
sort.each_cons(2).any? { |pair| belote_pair?(pair) }
end
def tierce?
n_sequential_cards?(3)
end
def quarte?
n_sequential_cards?(4)
end
def quint?
n_sequential_cards?(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
class SixtySixDeck < Deck
def deal
SixtySixHand.new(super(6))
end
private
def ranks
[9, :jack, :queen, :king, 10, :ace]
end
end
class SixtySixHand < SixtySixDeck
include CardMethods
def twenty?(trump_suit)
sort.each_cons(2).any? { |pair| twenty_pair?(pair, trump_suit) }
end
def forty?(trump_suit)
sort.each_cons(2).any? { |pair| forty_pair?(pair, trump_suit) }
end
end