Решение на Четвърта задача от Александър Дражев

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

Към профила на Александър Дражев

Резултати

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

Код

WAR_RANK_ORDER = [2, 3, 4, 5, 6, 7, 8, 9, 10, :jack, :queen, :king, :ace]
BELOTE_RANK_ORDER = [7, 8, 9, :jack, :queen, :king, 10, :ace]
SIXTY_SIX_RANK_ORDER = [9, :jack, :queen, :king, 10, :ace]
WAR_HAND_SIZE = 26
BELOTE_HAND_SIZE = 8
SIXTY_SIX_HAND_SIZE = 6
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)
other.class == self.class && other.state == self.state
end
protected
def state
[@rank, @suit]
end
end
class CardsHeap
def initialize(cards)
@cards = cards.dup
end
def size
@cards.size
end
private
def ordered_ranks
[]
end
def ordered_suits
[:spades, :hearts, :diamonds, :clubs]
end
def n_consecutive?(n, allowed_ranks: nil, allowed_suits: nil)
@cards.combination(n).select do |c|
c.all? do |e|
correct_ranks = allowed_ranks.nil? || allowed_ranks.include?(e.rank)
correct_suits = allowed_suits.nil? || allowed_suits.include?(e.suit)
e.suit == c.first.suit and correct_suits and correct_ranks
end
end.any? do |c|
rank_orders = c.map { |e| ordered_ranks.index(e.rank) }
(rank_orders.max - rank_orders.min + 1) == n
end
end
end
class WarHand < CardsHeap
def play_card
@cards.pop
end
def allow_face_up?
size <= 3
end
end
class BeloteHand < CardsHeap
def highest_of_suit(suit)
@cards.select { |c| c.suit == suit }.max do |a, b|
ordered_ranks.index(a.rank) <=> ordered_ranks.index(b.rank)
end
end
def belote?
n_consecutive?(2, allowed_ranks: [:queen, :king])
end
def tierce?
n_consecutive?(3)
end
def quarte?
n_consecutive?(4)
end
def quint?
n_consecutive?(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
private
def ordered_ranks
BELOTE_RANK_ORDER
end
def carre_of_rank?(rank)
@cards.count { |c| c.rank == rank } >= 4
end
end
class SixtySixHand < CardsHeap
def twenty?(trump_suit)
ranks = [:queen, :king]
suits = ordered_suits - [trump_suit]
n_consecutive?(2, allowed_ranks: ranks, allowed_suits: suits)
end
def forty?(trump_suit)
ranks = [:queen, :king]
suits = [trump_suit]
n_consecutive?(2, allowed_ranks: ranks, allowed_suits: suits)
end
def ordered_ranks
SIXTY_SIX_RANK_ORDER
end
end
class Deck < CardsHeap
include Enumerable
def initialize(cards = nil)
@cards = cards ? cards.dup : preferred_cards
end
def each
@cards.each { |e| yield e }
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
@cards.sort! do |a, b|
rank_order_a = ordered_ranks.index(a.rank)
rank_order_b = ordered_ranks.index(b.rank)
suit_order_a = ordered_suits.index(a.suit)
suit_order_b = ordered_suits.index(b.suit)
[suit_order_a, rank_order_b] <=> [suit_order_b, rank_order_a]
end
end
def to_s
@cards.join("\n")
end
def deal
hand_class.new(@cards.slice!(0, hand_size))
end
private
def preferred_cards
ordered_ranks.product(ordered_suits).map { |p| Card.new(p[0], p[1]) }
end
def hand_class
CardsHeap
end
def hand_size
0
end
end
class WarDeck < Deck
private
def ordered_ranks
WAR_RANK_ORDER
end
def hand_class
WarHand
end
def hand_size
WAR_HAND_SIZE
end
end
class BeloteDeck < Deck
private
def ordered_ranks
BELOTE_RANK_ORDER
end
def hand_class
BeloteHand
end
def hand_size
BELOTE_HAND_SIZE
end
end
class SixtySixDeck < Deck
private
def ordered_ranks
SIXTY_SIX_RANK_ORDER
end
def hand_class
SixtySixHand
end
def hand_size
SIXTY_SIX_HAND_SIZE
end
end

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

.......................................FFFF..............

Failures:

  1) BeloteDeck hand #carre_of_nines? behaves like carre-checking method returns true when there is a carre
     Failure/Error: expect(hand.public_send(method)).to be true
     NoMethodError:
       undefined method `carre_of_rank' for #<BeloteHand:0x007f5d00fd29d8>
     Shared Example Group: "carre-checking method" called from /tmp/d20151112-27349-1px5hna/spec.rb:390
     # /tmp/d20151112-27349-1px5hna/solution.rb:102:in `carre_of_nines?'
     # /tmp/d20151112-27349-1px5hna/spec.rb:86:in `public_send'
     # /tmp/d20151112-27349-1px5hna/spec.rb:86: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) BeloteDeck hand #carre_of_nines? behaves like carre-checking method returns false when there is no carre
     Failure/Error: expect(hand.public_send(method)).to be false
     NoMethodError:
       undefined method `carre_of_rank' for #<BeloteHand:0x007f5d00fca6c0>
     Shared Example Group: "carre-checking method" called from /tmp/d20151112-27349-1px5hna/spec.rb:390
     # /tmp/d20151112-27349-1px5hna/solution.rb:102:in `carre_of_nines?'
     # /tmp/d20151112-27349-1px5hna/spec.rb:101:in `public_send'
     # /tmp/d20151112-27349-1px5hna/spec.rb:101: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) BeloteDeck hand #carre_of_aces? behaves like carre-checking method returns true when there is a carre
     Failure/Error: expect(hand.public_send(method)).to be true
     NoMethodError:
       undefined method `carre_of_rank' for #<BeloteHand:0x007f5d00fbb120>
     Shared Example Group: "carre-checking method" called from /tmp/d20151112-27349-1px5hna/spec.rb:394
     # /tmp/d20151112-27349-1px5hna/solution.rb:106:in `carre_of_aces?'
     # /tmp/d20151112-27349-1px5hna/spec.rb:86:in `public_send'
     # /tmp/d20151112-27349-1px5hna/spec.rb:86: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)>'

  4) BeloteDeck hand #carre_of_aces? behaves like carre-checking method returns false when there is no carre
     Failure/Error: expect(hand.public_send(method)).to be false
     NoMethodError:
       undefined method `carre_of_rank' for #<BeloteHand:0x007f5d00faf0f0>
     Shared Example Group: "carre-checking method" called from /tmp/d20151112-27349-1px5hna/spec.rb:394
     # /tmp/d20151112-27349-1px5hna/solution.rb:106:in `carre_of_aces?'
     # /tmp/d20151112-27349-1px5hna/spec.rb:101:in `public_send'
     # /tmp/d20151112-27349-1px5hna/spec.rb:101: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)>'

Finished in 0.04694 seconds
57 examples, 4 failures

Failed examples:

rspec /tmp/d20151112-27349-1px5hna/spec.rb:74 # BeloteDeck hand #carre_of_nines? behaves like carre-checking method returns true when there is a carre
rspec /tmp/d20151112-27349-1px5hna/spec.rb:89 # BeloteDeck hand #carre_of_nines? behaves like carre-checking method returns false when there is no carre
rspec /tmp/d20151112-27349-1px5hna/spec.rb:74 # BeloteDeck hand #carre_of_aces? behaves like carre-checking method returns true when there is a carre
rspec /tmp/d20151112-27349-1px5hna/spec.rb:89 # BeloteDeck hand #carre_of_aces? behaves like carre-checking method returns false when there is no carre

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

Александър обнови решението на 11.11.2015 07:53 (преди около 9 години)

+WAR_RANK_ORDER = [2, 3, 4, 5, 6, 7, 8, 9, 10, :jack, :queen, :king, :ace]
+BELOTE_RANK_ORDER = [7, 8, 9, :jack, :queen, :king, 10, :ace]
+SIXTY_SIX_RANK_ORDER = [9, :jack, :queen, :king, 10, :ace]
+
+WAR_HAND_SIZE = 26
+BELOTE_HAND_SIZE = 8
+SIXTY_SIX_HAND_SIZE = 6
+
+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)
+ other.class == self.class && other.state == self.state
+ end
+
+ protected
+
+ def state
+ [@rank, @suit]
+ end
+end
+
+class CardsHeap
+ def initialize(cards)
+ @cards = cards.dup
+ end
+
+ def size
+ @cards.size
+ end
+
+ private
+
+ def ordered_ranks
+ []
+ end
+
+ def ordered_suits
+ [:spades, :hearts, :diamonds, :clubs]
+ end
+
+ def n_consecutive?(n, allowed_ranks: nil, allowed_suits: nil)
+ @cards.combination(n).select do |c|
+ c.all? do |e|
+ correct_ranks = allowed_ranks.nil? || allowed_ranks.include?(e.rank)
+ correct_suits = allowed_suits.nil? || allowed_suits.include?(e.suit)
+ e.suit == c.first.suit and correct_suits and correct_ranks
+ end
+ end.any? do |c|
+ rank_orders = c.map { |e| ordered_ranks.index(e.rank) }
+ (rank_orders.max - rank_orders.min + 1) == n
+ end
+ end
+end
+
+class WarHand < CardsHeap
+ def play_card
+ @cards.pop
+ end
+
+ def allow_face_up?
+ size <= 3
+ end
+end
+
+class BeloteHand < CardsHeap
+ def highest_of_suit(suit)
+ rank_order = BELOTE_RANK_ORDER
+ @cards.select { |c| c.suit == suit }.max do |a, b|
+ rank_order.index(a.rank) <=> rank_order.index(b.rank)
+ end
+ end
+
+ def belote?
+ n_consecutive?(2, allowed_ranks: [:queen, :king])
+ end
+
+ def tierce?
+ n_consecutive?(3)
+ end
+
+ def quarte?
+ n_consecutive?(4)
+ end
+
+ def quint?
+ n_consecutive?(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
+
+ private
+
+ def ordered_ranks
+ BELOTE_RANK_ORDER
+ end
+
+ def carre_of_rank?(rank)
+ @cards.count { |c| c.rank == rank } >= 4
+ end
+end
+
+class SixtySixHand < CardsHeap
+ def twenty?(trump_suit)
+ allowed_ranks = [:queen, :king]
+ allowed_suits = ordered_suits - trump_suit
+ n_consecutive(2, allowed_ranks: allowed_ranks, allowed_suits: allowed_suits)
+ end
+
+ def forty?(trump_suit)
+ n_consecutive(2, allowed_ranks: [:queen, :king], allowed_suits: trump_suit)
+ end
+
+ def ordered_ranks
+ BELOTE_RANK_ORDER
+ end
+end
+
+class Deck < CardsHeap
+ include Enumerable
+
+ def initialize(cards = nil)
+ @cards = cards ? cards.dup : preferred_cards
+ end
+
+ def each
+ @cards.each { |e| yield e }
+ 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
+ @cards.sort! do |a, b|
+ rank_order_a = ordered_ranks.index(a.rank)
+ rank_order_b = ordered_ranks.index(b.rank)
+ suit_order_a = ordered_suits.index(a.suit)
+ suit_order_b = ordered_suits.index(b.suit)
+ [suit_order_a, rank_order_b] <=> [suit_order_b, rank_order_a]
+ end
+ end
+
+ def to_s
+ @cards.join("\n")
+ end
+
+ def deal
+ hand_class.new(@cards.first(hand_size))
+ end
+
+ private
+
+ def preferred_cards
+ ordered_ranks.product(ordered_suits).map { |p| Card.new(p[0], p[1]) }
+ end
+
+ def hand_class
+ CardsHeap
+ end
+
+ def hand_size
+ 0
+ end
+end
+
+class WarDeck < Deck
+ private
+
+ def ordered_ranks
+ WAR_RANK_ORDER
+ end
+
+ def hand_class
+ WarHand
+ end
+
+ def hand_size
+ WAR_HAND_SIZE
+ end
+end
+
+class BeloteDeck < Deck
+ private
+
+ def ordered_ranks
+ BELOTE_RANK_ORDER
+ end
+
+ def hand_class
+ BeloteHand
+ end
+
+ def hand_size
+ BELOTE_HAND_SIZE
+ end
+end
+
+class SixtySixDeck < Deck
+ private
+
+ def ordered_ranks
+ SIXTY_SIX_RANK_ORDER
+ end
+
+ def hand_class
+ SixtySixHand
+ end
+
+ def hand_size
+ SIXTY_SIX_HAND_SIZE
+ end
+end

Александър обнови решението на 11.11.2015 07:59 (преди около 9 години)

WAR_RANK_ORDER = [2, 3, 4, 5, 6, 7, 8, 9, 10, :jack, :queen, :king, :ace]
BELOTE_RANK_ORDER = [7, 8, 9, :jack, :queen, :king, 10, :ace]
SIXTY_SIX_RANK_ORDER = [9, :jack, :queen, :king, 10, :ace]
WAR_HAND_SIZE = 26
BELOTE_HAND_SIZE = 8
SIXTY_SIX_HAND_SIZE = 6
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)
other.class == self.class && other.state == self.state
end
protected
def state
[@rank, @suit]
end
end
class CardsHeap
def initialize(cards)
@cards = cards.dup
end
def size
@cards.size
end
private
def ordered_ranks
[]
end
def ordered_suits
[:spades, :hearts, :diamonds, :clubs]
end
def n_consecutive?(n, allowed_ranks: nil, allowed_suits: nil)
@cards.combination(n).select do |c|
c.all? do |e|
correct_ranks = allowed_ranks.nil? || allowed_ranks.include?(e.rank)
correct_suits = allowed_suits.nil? || allowed_suits.include?(e.suit)
e.suit == c.first.suit and correct_suits and correct_ranks
end
end.any? do |c|
rank_orders = c.map { |e| ordered_ranks.index(e.rank) }
(rank_orders.max - rank_orders.min + 1) == n
end
end
end
class WarHand < CardsHeap
def play_card
@cards.pop
end
def allow_face_up?
size <= 3
end
end
class BeloteHand < CardsHeap
def highest_of_suit(suit)
rank_order = BELOTE_RANK_ORDER
@cards.select { |c| c.suit == suit }.max do |a, b|
rank_order.index(a.rank) <=> rank_order.index(b.rank)
end
end
def belote?
n_consecutive?(2, allowed_ranks: [:queen, :king])
end
def tierce?
n_consecutive?(3)
end
def quarte?
n_consecutive?(4)
end
def quint?
n_consecutive?(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
private
def ordered_ranks
BELOTE_RANK_ORDER
end
def carre_of_rank?(rank)
@cards.count { |c| c.rank == rank } >= 4
end
end
class SixtySixHand < CardsHeap
def twenty?(trump_suit)
allowed_ranks = [:queen, :king]
allowed_suits = ordered_suits - trump_suit
n_consecutive(2, allowed_ranks: allowed_ranks, allowed_suits: allowed_suits)
end
def forty?(trump_suit)
n_consecutive(2, allowed_ranks: [:queen, :king], allowed_suits: trump_suit)
end
def ordered_ranks
- BELOTE_RANK_ORDER
+ SIXTY_SIX_RANK_ORDER
end
end
class Deck < CardsHeap
include Enumerable
def initialize(cards = nil)
@cards = cards ? cards.dup : preferred_cards
end
def each
@cards.each { |e| yield e }
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
@cards.sort! do |a, b|
rank_order_a = ordered_ranks.index(a.rank)
rank_order_b = ordered_ranks.index(b.rank)
suit_order_a = ordered_suits.index(a.suit)
suit_order_b = ordered_suits.index(b.suit)
[suit_order_a, rank_order_b] <=> [suit_order_b, rank_order_a]
end
end
def to_s
@cards.join("\n")
end
def deal
hand_class.new(@cards.first(hand_size))
end
private
def preferred_cards
ordered_ranks.product(ordered_suits).map { |p| Card.new(p[0], p[1]) }
end
def hand_class
CardsHeap
end
def hand_size
0
end
end
class WarDeck < Deck
private
def ordered_ranks
WAR_RANK_ORDER
end
def hand_class
WarHand
end
def hand_size
WAR_HAND_SIZE
end
end
class BeloteDeck < Deck
private
def ordered_ranks
BELOTE_RANK_ORDER
end
def hand_class
BeloteHand
end
def hand_size
BELOTE_HAND_SIZE
end
end
class SixtySixDeck < Deck
private
def ordered_ranks
SIXTY_SIX_RANK_ORDER
end
def hand_class
SixtySixHand
end
def hand_size
SIXTY_SIX_HAND_SIZE
end
end

Александър обнови решението на 11.11.2015 08:06 (преди около 9 години)

WAR_RANK_ORDER = [2, 3, 4, 5, 6, 7, 8, 9, 10, :jack, :queen, :king, :ace]
BELOTE_RANK_ORDER = [7, 8, 9, :jack, :queen, :king, 10, :ace]
SIXTY_SIX_RANK_ORDER = [9, :jack, :queen, :king, 10, :ace]
WAR_HAND_SIZE = 26
BELOTE_HAND_SIZE = 8
SIXTY_SIX_HAND_SIZE = 6
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)
other.class == self.class && other.state == self.state
end
protected
def state
[@rank, @suit]
end
end
class CardsHeap
def initialize(cards)
@cards = cards.dup
end
def size
@cards.size
end
private
def ordered_ranks
[]
end
def ordered_suits
[:spades, :hearts, :diamonds, :clubs]
end
def n_consecutive?(n, allowed_ranks: nil, allowed_suits: nil)
@cards.combination(n).select do |c|
c.all? do |e|
correct_ranks = allowed_ranks.nil? || allowed_ranks.include?(e.rank)
correct_suits = allowed_suits.nil? || allowed_suits.include?(e.suit)
e.suit == c.first.suit and correct_suits and correct_ranks
end
end.any? do |c|
rank_orders = c.map { |e| ordered_ranks.index(e.rank) }
(rank_orders.max - rank_orders.min + 1) == n
end
end
end
class WarHand < CardsHeap
def play_card
@cards.pop
end
def allow_face_up?
size <= 3
end
end
class BeloteHand < CardsHeap
def highest_of_suit(suit)
rank_order = BELOTE_RANK_ORDER
@cards.select { |c| c.suit == suit }.max do |a, b|
rank_order.index(a.rank) <=> rank_order.index(b.rank)
end
end
def belote?
n_consecutive?(2, allowed_ranks: [:queen, :king])
end
def tierce?
n_consecutive?(3)
end
def quarte?
n_consecutive?(4)
end
def quint?
n_consecutive?(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
private
def ordered_ranks
BELOTE_RANK_ORDER
end
def carre_of_rank?(rank)
@cards.count { |c| c.rank == rank } >= 4
end
end
class SixtySixHand < CardsHeap
def twenty?(trump_suit)
- allowed_ranks = [:queen, :king]
- allowed_suits = ordered_suits - trump_suit
- n_consecutive(2, allowed_ranks: allowed_ranks, allowed_suits: allowed_suits)
+ ranks = [:queen, :king]
+ suits = ordered_suits - [trump_suit]
+ n_consecutive?(2, allowed_ranks: ranks, allowed_suits: suits)
end
def forty?(trump_suit)
- n_consecutive(2, allowed_ranks: [:queen, :king], allowed_suits: trump_suit)
+ ranks = [:queen, :king]
+ suits = [trump_suit]
+ n_consecutive?(2, allowed_ranks: ranks, allowed_suits: suits)
end
def ordered_ranks
SIXTY_SIX_RANK_ORDER
end
end
class Deck < CardsHeap
include Enumerable
def initialize(cards = nil)
@cards = cards ? cards.dup : preferred_cards
end
def each
@cards.each { |e| yield e }
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
@cards.sort! do |a, b|
rank_order_a = ordered_ranks.index(a.rank)
rank_order_b = ordered_ranks.index(b.rank)
suit_order_a = ordered_suits.index(a.suit)
suit_order_b = ordered_suits.index(b.suit)
[suit_order_a, rank_order_b] <=> [suit_order_b, rank_order_a]
end
end
def to_s
@cards.join("\n")
end
def deal
hand_class.new(@cards.first(hand_size))
end
private
def preferred_cards
ordered_ranks.product(ordered_suits).map { |p| Card.new(p[0], p[1]) }
end
def hand_class
CardsHeap
end
def hand_size
0
end
end
class WarDeck < Deck
private
def ordered_ranks
WAR_RANK_ORDER
end
def hand_class
WarHand
end
def hand_size
WAR_HAND_SIZE
end
end
class BeloteDeck < Deck
private
def ordered_ranks
BELOTE_RANK_ORDER
end
def hand_class
BeloteHand
end
def hand_size
BELOTE_HAND_SIZE
end
end
class SixtySixDeck < Deck
private
def ordered_ranks
SIXTY_SIX_RANK_ORDER
end
def hand_class
SixtySixHand
end
def hand_size
SIXTY_SIX_HAND_SIZE
end
end

Александър обнови решението на 11.11.2015 08:19 (преди около 9 години)

WAR_RANK_ORDER = [2, 3, 4, 5, 6, 7, 8, 9, 10, :jack, :queen, :king, :ace]
BELOTE_RANK_ORDER = [7, 8, 9, :jack, :queen, :king, 10, :ace]
SIXTY_SIX_RANK_ORDER = [9, :jack, :queen, :king, 10, :ace]
WAR_HAND_SIZE = 26
BELOTE_HAND_SIZE = 8
SIXTY_SIX_HAND_SIZE = 6
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)
other.class == self.class && other.state == self.state
end
protected
def state
[@rank, @suit]
end
end
class CardsHeap
def initialize(cards)
@cards = cards.dup
end
def size
@cards.size
end
private
def ordered_ranks
[]
end
def ordered_suits
[:spades, :hearts, :diamonds, :clubs]
end
def n_consecutive?(n, allowed_ranks: nil, allowed_suits: nil)
@cards.combination(n).select do |c|
c.all? do |e|
correct_ranks = allowed_ranks.nil? || allowed_ranks.include?(e.rank)
correct_suits = allowed_suits.nil? || allowed_suits.include?(e.suit)
e.suit == c.first.suit and correct_suits and correct_ranks
end
end.any? do |c|
rank_orders = c.map { |e| ordered_ranks.index(e.rank) }
(rank_orders.max - rank_orders.min + 1) == n
end
end
end
class WarHand < CardsHeap
def play_card
@cards.pop
end
def allow_face_up?
size <= 3
end
end
class BeloteHand < CardsHeap
def highest_of_suit(suit)
- rank_order = BELOTE_RANK_ORDER
@cards.select { |c| c.suit == suit }.max do |a, b|
- rank_order.index(a.rank) <=> rank_order.index(b.rank)
+ ordered_ranks.index(a.rank) <=> ordered_ranks.index(b.rank)
end
end
def belote?
n_consecutive?(2, allowed_ranks: [:queen, :king])
end
def tierce?
n_consecutive?(3)
end
def quarte?
n_consecutive?(4)
end
def quint?
n_consecutive?(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
private
def ordered_ranks
BELOTE_RANK_ORDER
end
def carre_of_rank?(rank)
@cards.count { |c| c.rank == rank } >= 4
end
end
class SixtySixHand < CardsHeap
def twenty?(trump_suit)
ranks = [:queen, :king]
suits = ordered_suits - [trump_suit]
n_consecutive?(2, allowed_ranks: ranks, allowed_suits: suits)
end
def forty?(trump_suit)
ranks = [:queen, :king]
suits = [trump_suit]
n_consecutive?(2, allowed_ranks: ranks, allowed_suits: suits)
end
def ordered_ranks
SIXTY_SIX_RANK_ORDER
end
end
class Deck < CardsHeap
include Enumerable
def initialize(cards = nil)
@cards = cards ? cards.dup : preferred_cards
end
def each
@cards.each { |e| yield e }
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
@cards.sort! do |a, b|
rank_order_a = ordered_ranks.index(a.rank)
rank_order_b = ordered_ranks.index(b.rank)
suit_order_a = ordered_suits.index(a.suit)
suit_order_b = ordered_suits.index(b.suit)
[suit_order_a, rank_order_b] <=> [suit_order_b, rank_order_a]
end
end
def to_s
@cards.join("\n")
end
def deal
hand_class.new(@cards.first(hand_size))
end
private
def preferred_cards
ordered_ranks.product(ordered_suits).map { |p| Card.new(p[0], p[1]) }
end
def hand_class
CardsHeap
end
def hand_size
0
end
end
class WarDeck < Deck
private
def ordered_ranks
WAR_RANK_ORDER
end
def hand_class
WarHand
end
def hand_size
WAR_HAND_SIZE
end
end
class BeloteDeck < Deck
private
def ordered_ranks
BELOTE_RANK_ORDER
end
def hand_class
BeloteHand
end
def hand_size
BELOTE_HAND_SIZE
end
end
class SixtySixDeck < Deck
private
def ordered_ranks
SIXTY_SIX_RANK_ORDER
end
def hand_class
SixtySixHand
end
def hand_size
SIXTY_SIX_HAND_SIZE
end
end

Александър обнови решението на 11.11.2015 15:38 (преди около 9 години)

WAR_RANK_ORDER = [2, 3, 4, 5, 6, 7, 8, 9, 10, :jack, :queen, :king, :ace]
BELOTE_RANK_ORDER = [7, 8, 9, :jack, :queen, :king, 10, :ace]
SIXTY_SIX_RANK_ORDER = [9, :jack, :queen, :king, 10, :ace]
WAR_HAND_SIZE = 26
BELOTE_HAND_SIZE = 8
SIXTY_SIX_HAND_SIZE = 6
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)
other.class == self.class && other.state == self.state
end
protected
def state
[@rank, @suit]
end
end
class CardsHeap
def initialize(cards)
@cards = cards.dup
end
def size
@cards.size
end
private
def ordered_ranks
[]
end
def ordered_suits
[:spades, :hearts, :diamonds, :clubs]
end
def n_consecutive?(n, allowed_ranks: nil, allowed_suits: nil)
@cards.combination(n).select do |c|
c.all? do |e|
correct_ranks = allowed_ranks.nil? || allowed_ranks.include?(e.rank)
correct_suits = allowed_suits.nil? || allowed_suits.include?(e.suit)
e.suit == c.first.suit and correct_suits and correct_ranks
end
end.any? do |c|
rank_orders = c.map { |e| ordered_ranks.index(e.rank) }
(rank_orders.max - rank_orders.min + 1) == n
end
end
end
class WarHand < CardsHeap
def play_card
@cards.pop
end
def allow_face_up?
size <= 3
end
end
class BeloteHand < CardsHeap
def highest_of_suit(suit)
@cards.select { |c| c.suit == suit }.max do |a, b|
ordered_ranks.index(a.rank) <=> ordered_ranks.index(b.rank)
end
end
def belote?
n_consecutive?(2, allowed_ranks: [:queen, :king])
end
def tierce?
n_consecutive?(3)
end
def quarte?
n_consecutive?(4)
end
def quint?
n_consecutive?(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
private
def ordered_ranks
BELOTE_RANK_ORDER
end
def carre_of_rank?(rank)
@cards.count { |c| c.rank == rank } >= 4
end
end
class SixtySixHand < CardsHeap
def twenty?(trump_suit)
ranks = [:queen, :king]
suits = ordered_suits - [trump_suit]
n_consecutive?(2, allowed_ranks: ranks, allowed_suits: suits)
end
def forty?(trump_suit)
ranks = [:queen, :king]
suits = [trump_suit]
n_consecutive?(2, allowed_ranks: ranks, allowed_suits: suits)
end
def ordered_ranks
SIXTY_SIX_RANK_ORDER
end
end
class Deck < CardsHeap
include Enumerable
def initialize(cards = nil)
@cards = cards ? cards.dup : preferred_cards
end
def each
@cards.each { |e| yield e }
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
@cards.sort! do |a, b|
rank_order_a = ordered_ranks.index(a.rank)
rank_order_b = ordered_ranks.index(b.rank)
suit_order_a = ordered_suits.index(a.suit)
suit_order_b = ordered_suits.index(b.suit)
[suit_order_a, rank_order_b] <=> [suit_order_b, rank_order_a]
end
end
def to_s
@cards.join("\n")
end
def deal
- hand_class.new(@cards.first(hand_size))
+ hand_class.new(@cards.slice!(0, hand_size))
end
private
def preferred_cards
ordered_ranks.product(ordered_suits).map { |p| Card.new(p[0], p[1]) }
end
def hand_class
CardsHeap
end
def hand_size
0
end
end
class WarDeck < Deck
private
def ordered_ranks
WAR_RANK_ORDER
end
def hand_class
WarHand
end
def hand_size
WAR_HAND_SIZE
end
end
class BeloteDeck < Deck
private
def ordered_ranks
BELOTE_RANK_ORDER
end
def hand_class
BeloteHand
end
def hand_size
BELOTE_HAND_SIZE
end
end
class SixtySixDeck < Deck
private
def ordered_ranks
SIXTY_SIX_RANK_ORDER
end
def hand_class
SixtySixHand
end
def hand_size
SIXTY_SIX_HAND_SIZE
end
end