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

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

Към профила на Анджелин Неделчев

Резултати

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

Код

###
### Abstract
###
class Card
SUITS = [:diamonds, :spades, :clubs, :hearts].freeze
RANKS = Hash[((2..10).to_a + [:jack, :queen, :king, :ace])
.map.with_index.to_a]
attr_reader :rank
attr_reader :suit
def initialize(rank, suit)
@rank = rank
@suit = suit
end
def to_s()
"#{@rank.capitalize rescue @rank} of #{@suit.capitalize}"
end
def ==(other)
@rank == other.rank and @suit == other.suit
end
end
class Deck
include Enumerable
def initialize(cards = nil)
@cards = cards ? cards.dup : generate_all_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()
power = ranks()
@cards.sort! { |a, b| [b.suit, power[b.rank]] <=> [a.suit, power[a.rank]] }
end
def to_s()
each { |card| card.to_s }
end
def deal()
hand = []
hand_size().times { hand << draw_top_card unless size() == 0 }
hand_class.new(hand)
end
def each()
return @cards.each unless block_given?
@cards.each { |card| yield card }
end
def ranks()
Card::RANKS
end
def generate_all_cards()
ranks().keys.product(Card::SUITS).map { |r, s| Card.new(r, s) }
end
end
class Hand
include Enumerable
attr_reader :cards
def initialize(cards)
@cards = cards
end
def size()
@cards.size
end
def each()
return @cards.each unless block_given?
@cards.each { |card| yield card }
end
end
######################
#####
##### War
#####
class WarHand < Hand
ALLOW_FACE_UP_COUNT = 3
def play_card()
@cards.delete(@cards.sample)
end
def allow_face_up?()
size() <= ALLOW_FACE_UP_COUNT
end
end
class WarDeck < Deck
HAND_SIZE = 26
TOTAL_CARDS = 52
def hand_size()
HAND_SIZE
end
def hand_class()
WarHand
end
def ranks()
Card::RANKS
end
end
##########################
#####
##### Belote
#####
class BeloteHand < Hand
CARRE_COUNT = 4
def highest_of_suit(suit)
power = BeloteDeck::RANKS
highest = Card.new(7, :spades)
select { |c| c.suit == suit}
.each { |c| highest = c if power[c.rank] > power[highest.rank] }
highest
end
def belote?()
kings = select { |card| card.rank == :king }
kings.each do |king|
match = select do |card|
card.rank == :queen and card.suit == king.suit
end
return true if match.size != 0
end
false
end
def tierce?()
n_in_a_row?(3)
end
def quarte?()
n_in_a_row?(4)
end
def quint?()
n_in_a_row?(5)
end
def carre_of_jacks?()
carre_of_x?(:jack)
end
def carre_of_nines?()
carre_of_x?(9)
end
def carre_of_aces?()
carre_of_x?(:ace)
end
private
def n_in_a_row?(amount)
power = BeloteDeck::RANKS
grouped = @cards.sort! { |a, b| power[a.rank] <=> power[b.rank] }
.group_by { |card| card.suit }.values
grouped.any? do |suited|
next if suited.size < amount
suited.each_cons(amount).any? do |con|
are_following_numbers?(con)
end
end
end
def are_following_numbers?(numbers)
numbers.each_cons(2).all? do |a, b|
BeloteDeck::RANKS[b.rank] - BeloteDeck::RANKS[a.rank] == 1
end
end
def carre_of_x?(rank)
select { |card| card.rank == rank }.size == CARRE_COUNT
end
end
class BeloteDeck < Deck
RANKS = Hash[[7, 8, 9, :jack, :queen, :king, 10, :ace].map.with_index.to_a]
HAND_SIZE = 8
TOTAL_CARDS = 32
def hand_size()
HAND_SIZE
end
def hand_class()
BeloteHand
end
def ranks()
RANKS
end
end
#######################
#####
##### SixtySix
#####
class SixtySixHand < Hand
def twenty?(trump_suit)
kings_and_queens?(trump_suit, ->(x, y) { x != y })
end
def forty?(trump_suit)
kings_and_queens?(trump_suit, ->(x, y) { x == y })
end
private
def kings_and_queens?(trump_suit, predicate)
kings = select { |c| c.rank == :king and predicate.(c.suit, trump_suit) }
kings.each do |king|
return true if @cards.any? do |card|
card.rank == :queen and card.suit == king.suit
end
end
false
end
end
class SixtySixDeck < Deck
RANKS = Hash[[9, :jack, :queen, :king, 10, :ace].map.with_index.to_a]
HAND_SIZE = 6
TOTAL_CARDS = 24
def hand_size()
HAND_SIZE
end
def hand_class()
SixtySixHand
end
def ranks()
RANKS
end
end

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

...........F............F..........................F.....

Failures:

  1) WarDeck behaves like a deck #to_s returns the names of the cards, each on its own line
     Failure/Error: expect(small_deck.to_s.strip).to eq "Ace of Spades\n9 of Clubs"
     NoMethodError:
       undefined method `strip' for #<Array:0x007fc2a6439c50>
     Shared Example Group: "a deck" called from /tmp/d20151112-27349-1r8rfvn/spec.rb:140
     # /tmp/d20151112-27349-1r8rfvn/spec.rb:68: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)>'

  2) BeloteDeck behaves like a deck #to_s returns the names of the cards, each on its own line
     Failure/Error: expect(small_deck.to_s.strip).to eq "Ace of Spades\n9 of Clubs"
     NoMethodError:
       undefined method `strip' for #<Array:0x007fc2a645eeb0>
     Shared Example Group: "a deck" called from /tmp/d20151112-27349-1r8rfvn/spec.rb:191
     # /tmp/d20151112-27349-1r8rfvn/spec.rb:68: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)>'

  3) SixtySixDeck behaves like a deck #to_s returns the names of the cards, each on its own line
     Failure/Error: expect(small_deck.to_s.strip).to eq "Ace of Spades\n9 of Clubs"
     NoMethodError:
       undefined method `strip' for #<Array:0x007fc2a6278100>
     Shared Example Group: "a deck" called from /tmp/d20151112-27349-1r8rfvn/spec.rb:400
     # /tmp/d20151112-27349-1r8rfvn/spec.rb:68: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.04319 seconds
57 examples, 3 failures

Failed examples:

rspec /tmp/d20151112-27349-1r8rfvn/spec.rb:67 # WarDeck behaves like a deck #to_s returns the names of the cards, each on its own line
rspec /tmp/d20151112-27349-1r8rfvn/spec.rb:67 # BeloteDeck behaves like a deck #to_s returns the names of the cards, each on its own line
rspec /tmp/d20151112-27349-1r8rfvn/spec.rb:67 # SixtySixDeck behaves like a deck #to_s returns the names of the cards, each on its own line

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

Анджелин обнови решението на 09.11.2015 02:02 (преди над 8 години)

+
+class Card
+ SUITS = [:diamonds, :spades, :clubs, :hearts].freeze
+ RANKS = Hash[((2..10).to_a + [:jack, :queen, :king, :ace])
+ .map.with_index.to_a]
+
+ attr_reader :rank
+ attr_reader :suit
+
+ def initialize(rank, suit)
+ @rank = rank
+ @suit = suit
+ end
+
+ def to_s()
+ "#{@rank.capitalize rescue @rank} of #{@suit.capitalize}"
+ end
+
+ def ==(other)
+ @rank == other.rank and @suit == other.suit
+ end
+end
+
+class Deck
+ include Enumerable
+
+ attr_reader :cards
+
+ def initialize(cards = nil)
+ @cards = cards ? cards : generate_all_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()
+ @cards.sort! { |a, b| [b.suit, Card::RANKS[b.rank]] <=>
+ [a.suit, Card::RANKS[a.rank]] }
+ end
+
+ def to_s()
+ @cards.each { |card| puts card }
+ end
+
+ def deal()
+ hand = []
+ hand_size().times { hand << draw_top_card }
+
+ hand_class.new(hand)
+ end
+
+ def each()
+ @cards.each { |card| yield card }
+ end
+
+ def generate_all_cards()
+ suits = [:spades, :hearts, :diamons, :clubs]
+ ranks = (2..10).to_a + [:jack, :queen, :king, :ace]
+ cards = []
+
+ suits.each { |suit| ranks.each { |rank| cards << Card.new(rank, suit) } }
+ cards
+ end
+
+ def hand_class()
+ nil
+ end
+
+ def hand_size()
+ 0
+ end
+end
+
+class Hand
+ attr_reader :cards
+
+ def initialize(cards)
+ @cards = cards
+ end
+
+ def size()
+ @cards.size
+ end
+end
+
+class WarHand < Hand
+ def play_card()
+ @cards.shift
+ end
+
+ def allow_face_up?()
+ @cards.size <= 3
+ end
+end
+
+class WarDeck < Deck
+ TOTAL_CARDS = 52
+
+ def hand_size()
+ 26
+ end
+
+ def hand_class()
+ WarHand
+ end
+end
+
+class BeloteHand < Hand
+ POWER = Hash[[7, 8, 9, :jack, :queen, :king, 10, :ace].map.with_index.to_a]
+
+ def highest_of_suit(suit)
+ highest = 0
+ @cards.each { |card| highest = POWER[card] if card.rank > highest }
+
+ highest
+ end
+
+ def belote?()
+ kings = @cards.select { |card| card.rank == :king }
+ kings.each do |king|
+ return true if kings.select do |card|
+ card.rank == :queen and card.suit == king.suit
+ end
+ end
+
+ false
+ end
+
+ def n_in_a_row?(amount)
+ @cards.sort! { |a, b| POWER[a.rank] <=> POWER[b.rank] }
+ previous = @cards.first
+
+ @cards.each do |current|
+ matches = (current.suit == previous.suit and
+ current > previous) ? matches += 1 : 0
+
+ return true if matches == amount
+ previous = current
+ end
+
+ false
+ end
+
+ def tierce?()
+ n_in_a_row(3)
+ end
+
+ def quarte?()
+ n_in_a_row(4)
+ end
+
+ def quint?()
+ n_in_a_row(5)
+ end
+
+ def carre_of_x?(rank)
+ @cards.select { |card| card.rank == rank }.size == 4
+ end
+
+ def carre_of_jacks?()
+ carre_of_x?(:jack)
+ end
+
+ def carre_of_nines?()
+ carre_of_x?(9)
+ end
+
+ def carre_of_aces?()
+ carre_of_x?(:ace)
+ end
+end
+
+class BeloteDeck < Deck
+ TOTAL_CARDS = 32
+
+ def hand_size()
+ 8
+ end
+
+ def hand_class()
+ BeloteHand
+ end
+end
+
+class SixtySixHand < Hand
+ def kings_and_queens?(trump_suit)
+ kings = @cards.select { |c| c.rank == :king and yield c.suit, trump_suit }
+ kings.each do |king|
+ return true if kings.select do |card|
+ card.rank == :queen and card.suit == king.suit
+ end
+ end
+
+ false
+ end
+
+ def twenty?(trump_suit)
+ kings_and_queens?(trump_suit) { |one, other| one != other }
+ end
+
+ def forty?(trump_suit)
+ kings_and_queens?(trump_suit) { |one, other| one == other }
+ end
+end
+
+class SixtySixDeck < Deck
+ TOTAL_CARDS = 24
+
+ def hand_size()
+ 6
+ end
+
+ def hand_class()
+ SixtySixHand
+ end
+end

Анджелин обнови решението на 09.11.2015 02:12 (преди над 8 години)

class Card
SUITS = [:diamonds, :spades, :clubs, :hearts].freeze
RANKS = Hash[((2..10).to_a + [:jack, :queen, :king, :ace])
.map.with_index.to_a]
attr_reader :rank
attr_reader :suit
def initialize(rank, suit)
@rank = rank
@suit = suit
end
def to_s()
"#{@rank.capitalize rescue @rank} of #{@suit.capitalize}"
end
def ==(other)
@rank == other.rank and @suit == other.suit
end
end
class Deck
include Enumerable
- attr_reader :cards
-
def initialize(cards = nil)
@cards = cards ? cards : generate_all_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()
- @cards.sort! { |a, b| [b.suit, Card::RANKS[b.rank]] <=>
- [a.suit, Card::RANKS[a.rank]] }
+ @cards.sort! do |a, b|
+ [b.suit, Card::RANKS[b.rank]] <=> [a.suit, Card::RANKS[a.rank]]
+ end
end
def to_s()
@cards.each { |card| puts card }
end
def deal()
hand = []
hand_size().times { hand << draw_top_card }
hand_class.new(hand)
end
def each()
@cards.each { |card| yield card }
end
def generate_all_cards()
- suits = [:spades, :hearts, :diamons, :clubs]
- ranks = (2..10).to_a + [:jack, :queen, :king, :ace]
cards = []
+ Card::SUITS.each do |suit|
+ Card::RANKS.keys.each { |rank| cards << Card.new(rank, suit) }
+ end
- suits.each { |suit| ranks.each { |rank| cards << Card.new(rank, suit) } }
cards
end
-
- def hand_class()
- nil
- end
-
- def hand_size()
- 0
- end
end
class Hand
attr_reader :cards
def initialize(cards)
@cards = cards
end
def size()
@cards.size
end
end
class WarHand < Hand
def play_card()
@cards.shift
end
def allow_face_up?()
@cards.size <= 3
end
end
class WarDeck < Deck
+ HAND_SIZE = 26
TOTAL_CARDS = 52
def hand_size()
- 26
+ HAND_SIZE
end
def hand_class()
WarHand
end
end
class BeloteHand < Hand
POWER = Hash[[7, 8, 9, :jack, :queen, :king, 10, :ace].map.with_index.to_a]
def highest_of_suit(suit)
highest = 0
@cards.each { |card| highest = POWER[card] if card.rank > highest }
highest
end
def belote?()
kings = @cards.select { |card| card.rank == :king }
kings.each do |king|
return true if kings.select do |card|
card.rank == :queen and card.suit == king.suit
end
end
false
end
- def n_in_a_row?(amount)
- @cards.sort! { |a, b| POWER[a.rank] <=> POWER[b.rank] }
- previous = @cards.first
-
- @cards.each do |current|
- matches = (current.suit == previous.suit and
- current > previous) ? matches += 1 : 0
-
- return true if matches == amount
- previous = current
- end
-
- false
- end
-
def tierce?()
n_in_a_row(3)
end
def quarte?()
n_in_a_row(4)
end
def quint?()
n_in_a_row(5)
end
- def carre_of_x?(rank)
- @cards.select { |card| card.rank == rank }.size == 4
- end
-
def carre_of_jacks?()
carre_of_x?(:jack)
end
def carre_of_nines?()
carre_of_x?(9)
end
def carre_of_aces?()
carre_of_x?(:ace)
end
+
+ private
+ def n_in_a_row?(amount)
+ @cards.sort! { |a, b| POWER[a.rank] <=> POWER[b.rank] }
+ previous = @cards.first
+
+ @cards.each do |current|
+ matches = (current.suit == previous.suit and
+ current > previous) ? matches += 1 : 0
+
+ return true if matches == amount
+ previous = current
+ end
+
+ false
+ end
+
+ def carre_of_x?(rank)
+ @cards.select { |card| card.rank == rank }.size == 4
+ end
end
class BeloteDeck < Deck
+ HAND_SIZE = 8
TOTAL_CARDS = 32
def hand_size()
- 8
+ HAND_SIZE
end
def hand_class()
BeloteHand
end
end
class SixtySixHand < Hand
+ def twenty?(trump_suit)
+ kings_and_queens?(trump_suit) { |one, other| one != other }
+ end
+
+ def forty?(trump_suit)
+ kings_and_queens?(trump_suit) { |one, other| one == other }
+ end
+
+ private
def kings_and_queens?(trump_suit)
kings = @cards.select { |c| c.rank == :king and yield c.suit, trump_suit }
kings.each do |king|
return true if kings.select do |card|
card.rank == :queen and card.suit == king.suit
end
end
false
- end
-
- def twenty?(trump_suit)
- kings_and_queens?(trump_suit) { |one, other| one != other }
- end
-
- def forty?(trump_suit)
- kings_and_queens?(trump_suit) { |one, other| one == other }
end
end
class SixtySixDeck < Deck
TOTAL_CARDS = 24
def hand_size()
6
end
def hand_class()
SixtySixHand
end
end

Анджелин обнови решението на 09.11.2015 02:56 (преди над 8 години)

class Card
SUITS = [:diamonds, :spades, :clubs, :hearts].freeze
RANKS = Hash[((2..10).to_a + [:jack, :queen, :king, :ace])
.map.with_index.to_a]
attr_reader :rank
attr_reader :suit
def initialize(rank, suit)
@rank = rank
@suit = suit
end
def to_s()
"#{@rank.capitalize rescue @rank} of #{@suit.capitalize}"
end
def ==(other)
@rank == other.rank and @suit == other.suit
end
end
class Deck
include Enumerable
def initialize(cards = nil)
@cards = cards ? cards : generate_all_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()
@cards.sort! do |a, b|
[b.suit, Card::RANKS[b.rank]] <=> [a.suit, Card::RANKS[a.rank]]
end
end
def to_s()
@cards.each { |card| puts card }
end
def deal()
hand = []
hand_size().times { hand << draw_top_card }
hand_class.new(hand)
end
def each()
@cards.each { |card| yield card }
end
def generate_all_cards()
cards = []
Card::SUITS.each do |suit|
Card::RANKS.keys.each { |rank| cards << Card.new(rank, suit) }
end
cards
end
end
class Hand
attr_reader :cards
def initialize(cards)
@cards = cards
end
def size()
@cards.size
end
end
class WarHand < Hand
def play_card()
@cards.shift
end
def allow_face_up?()
@cards.size <= 3
end
end
class WarDeck < Deck
HAND_SIZE = 26
TOTAL_CARDS = 52
def hand_size()
HAND_SIZE
end
def hand_class()
WarHand
end
end
class BeloteHand < Hand
POWER = Hash[[7, 8, 9, :jack, :queen, :king, 10, :ace].map.with_index.to_a]
def highest_of_suit(suit)
highest = 0
@cards.each { |card| highest = POWER[card] if card.rank > highest }
highest
end
def belote?()
kings = @cards.select { |card| card.rank == :king }
kings.each do |king|
- return true if kings.select do |card|
+ match = kings.select do |card|
card.rank == :queen and card.suit == king.suit
end
+
+ return true if match.size != 0
end
false
end
def tierce?()
n_in_a_row(3)
end
def quarte?()
n_in_a_row(4)
end
def quint?()
n_in_a_row(5)
end
def carre_of_jacks?()
carre_of_x?(:jack)
end
def carre_of_nines?()
carre_of_x?(9)
end
def carre_of_aces?()
carre_of_x?(:ace)
end
private
def n_in_a_row?(amount)
@cards.sort! { |a, b| POWER[a.rank] <=> POWER[b.rank] }
previous = @cards.first
@cards.each do |current|
matches = (current.suit == previous.suit and
current > previous) ? matches += 1 : 0
return true if matches == amount
previous = current
end
false
end
def carre_of_x?(rank)
@cards.select { |card| card.rank == rank }.size == 4
end
end
class BeloteDeck < Deck
HAND_SIZE = 8
TOTAL_CARDS = 32
def hand_size()
HAND_SIZE
end
def hand_class()
BeloteHand
end
end
class SixtySixHand < Hand
def twenty?(trump_suit)
kings_and_queens?(trump_suit) { |one, other| one != other }
end
def forty?(trump_suit)
kings_and_queens?(trump_suit) { |one, other| one == other }
end
private
def kings_and_queens?(trump_suit)
kings = @cards.select { |c| c.rank == :king and yield c.suit, trump_suit }
kings.each do |king|
return true if kings.select do |card|
card.rank == :queen and card.suit == king.suit
end
end
false
end
end
class SixtySixDeck < Deck
TOTAL_CARDS = 24
def hand_size()
6
end
def hand_class()
SixtySixHand
end
end

Анджелин обнови решението на 11.11.2015 04:05 (преди над 8 години)

+###
+### Abstract
+###
+
class Card
SUITS = [:diamonds, :spades, :clubs, :hearts].freeze
RANKS = Hash[((2..10).to_a + [:jack, :queen, :king, :ace])
.map.with_index.to_a]
attr_reader :rank
attr_reader :suit
def initialize(rank, suit)
@rank = rank
@suit = suit
end
def to_s()
"#{@rank.capitalize rescue @rank} of #{@suit.capitalize}"
end
def ==(other)
@rank == other.rank and @suit == other.suit
end
end
class Deck
include Enumerable
def initialize(cards = nil)
- @cards = cards ? cards : generate_all_cards()
+ @cards = cards ? cards.dup : generate_all_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()
- @cards.sort! do |a, b|
- [b.suit, Card::RANKS[b.rank]] <=> [a.suit, Card::RANKS[a.rank]]
- end
+ power = ranks()
+ @cards.sort! { |a, b| [b.suit, power[b.rank]] <=> [a.suit, power[a.rank]] }
end
def to_s()
- @cards.each { |card| puts card }
+ each { |card| card.to_s }
end
def deal()
- hand = []
- hand_size().times { hand << draw_top_card }
+ hand = []
+ hand_size().times { hand << draw_top_card unless size() == 0 }
hand_class.new(hand)
end
def each()
+ return @cards.each unless block_given?
+
@cards.each { |card| yield card }
end
- def generate_all_cards()
- cards = []
- Card::SUITS.each do |suit|
- Card::RANKS.keys.each { |rank| cards << Card.new(rank, suit) }
- end
+ def ranks()
+ Card::RANKS
+ end
- cards
+ def generate_all_cards()
+ ranks().keys.product(Card::SUITS).map { |r, s| Card.new(r, s) }
end
end
class Hand
+ include Enumerable
+
attr_reader :cards
def initialize(cards)
@cards = cards
end
def size()
@cards.size
end
+
+ def each()
+ return @cards.each unless block_given?
+ @cards.each { |card| yield card }
+ end
end
+######################
+
+#####
+##### War
+#####
+
class WarHand < Hand
+ ALLOW_FACE_UP_COUNT = 3
+
def play_card()
- @cards.shift
+ @cards.delete(@cards.sample)
end
def allow_face_up?()
- @cards.size <= 3
+ size() <= ALLOW_FACE_UP_COUNT
end
end
class WarDeck < Deck
HAND_SIZE = 26
TOTAL_CARDS = 52
def hand_size()
HAND_SIZE
end
def hand_class()
WarHand
end
+
+ def ranks()
+ Card::RANKS
+ end
end
+##########################
+
+#####
+##### Belote
+#####
+
class BeloteHand < Hand
- POWER = Hash[[7, 8, 9, :jack, :queen, :king, 10, :ace].map.with_index.to_a]
+ CARRE_COUNT = 4
def highest_of_suit(suit)
- highest = 0
- @cards.each { |card| highest = POWER[card] if card.rank > highest }
+ power = BeloteDeck::RANKS
+ highest = Card.new(7, :spades)
+ select { |c| c.suit == suit}
+ .each { |c| highest = c if power[c.rank] > power[highest.rank] }
highest
end
def belote?()
- kings = @cards.select { |card| card.rank == :king }
+ kings = select { |card| card.rank == :king }
kings.each do |king|
- match = kings.select do |card|
+ match = select do |card|
card.rank == :queen and card.suit == king.suit
end
return true if match.size != 0
end
false
end
def tierce?()
- n_in_a_row(3)
+ n_in_a_row?(3)
end
def quarte?()
- n_in_a_row(4)
+ n_in_a_row?(4)
end
def quint?()
- n_in_a_row(5)
+ n_in_a_row?(5)
end
def carre_of_jacks?()
carre_of_x?(:jack)
end
def carre_of_nines?()
carre_of_x?(9)
end
def carre_of_aces?()
carre_of_x?(:ace)
end
private
def n_in_a_row?(amount)
- @cards.sort! { |a, b| POWER[a.rank] <=> POWER[b.rank] }
- previous = @cards.first
+ power = BeloteDeck::RANKS
- @cards.each do |current|
- matches = (current.suit == previous.suit and
- current > previous) ? matches += 1 : 0
+ grouped = @cards.sort! { |a, b| power[a.rank] <=> power[b.rank] }
+ .group_by { |card| card.suit }.values
- return true if matches == amount
- previous = current
+ grouped.any? do |suited|
+ next if suited.size < amount
+
+ suited.each_cons(amount).any? do |con|
+ are_following_numbers?(con)
+ end
end
+ end
- false
+ def are_following_numbers?(numbers)
+ numbers.each_cons(2).all? do |a, b|
+ BeloteDeck::RANKS[b.rank] - BeloteDeck::RANKS[a.rank] == 1
+ end
end
def carre_of_x?(rank)
- @cards.select { |card| card.rank == rank }.size == 4
+ select { |card| card.rank == rank }.size == CARRE_COUNT
end
end
class BeloteDeck < Deck
+ RANKS = Hash[[7, 8, 9, :jack, :queen, :king, 10, :ace].map.with_index.to_a]
HAND_SIZE = 8
TOTAL_CARDS = 32
def hand_size()
HAND_SIZE
end
def hand_class()
BeloteHand
end
+
+ def ranks()
+ RANKS
+ end
end
+#######################
+
+#####
+##### SixtySix
+#####
+
class SixtySixHand < Hand
def twenty?(trump_suit)
- kings_and_queens?(trump_suit) { |one, other| one != other }
+ kings_and_queens?(trump_suit, ->(x, y) { x != y })
end
def forty?(trump_suit)
- kings_and_queens?(trump_suit) { |one, other| one == other }
+ kings_and_queens?(trump_suit, ->(x, y) { x == y })
end
private
- def kings_and_queens?(trump_suit)
- kings = @cards.select { |c| c.rank == :king and yield c.suit, trump_suit }
+ def kings_and_queens?(trump_suit, predicate)
+ kings = select { |c| c.rank == :king and predicat.e(c.suit, trump_suit) }
+
kings.each do |king|
return true if kings.select do |card|
card.rank == :queen and card.suit == king.suit
end
end
false
end
end
class SixtySixDeck < Deck
+ RANKS = Hash[[9, :jack, :queen, :king, 10, :ace].map.with_index.to_a]
+ HAND_SIZE = 6
TOTAL_CARDS = 24
def hand_size()
- 6
+ HAND_SIZE
end
def hand_class()
SixtySixHand
end
+
+ def ranks()
+ RANKS
+ end
end
+

Анджелин обнови решението на 11.11.2015 04:09 (преди над 8 години)

###
### Abstract
###
class Card
SUITS = [:diamonds, :spades, :clubs, :hearts].freeze
RANKS = Hash[((2..10).to_a + [:jack, :queen, :king, :ace])
.map.with_index.to_a]
attr_reader :rank
attr_reader :suit
def initialize(rank, suit)
@rank = rank
@suit = suit
end
def to_s()
"#{@rank.capitalize rescue @rank} of #{@suit.capitalize}"
end
def ==(other)
@rank == other.rank and @suit == other.suit
end
end
class Deck
include Enumerable
def initialize(cards = nil)
@cards = cards ? cards.dup : generate_all_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()
power = ranks()
@cards.sort! { |a, b| [b.suit, power[b.rank]] <=> [a.suit, power[a.rank]] }
end
def to_s()
each { |card| card.to_s }
end
def deal()
hand = []
hand_size().times { hand << draw_top_card unless size() == 0 }
hand_class.new(hand)
end
def each()
return @cards.each unless block_given?
@cards.each { |card| yield card }
end
def ranks()
Card::RANKS
end
def generate_all_cards()
ranks().keys.product(Card::SUITS).map { |r, s| Card.new(r, s) }
end
end
class Hand
include Enumerable
attr_reader :cards
def initialize(cards)
@cards = cards
end
def size()
@cards.size
end
def each()
return @cards.each unless block_given?
@cards.each { |card| yield card }
end
end
######################
#####
##### War
#####
class WarHand < Hand
ALLOW_FACE_UP_COUNT = 3
def play_card()
@cards.delete(@cards.sample)
end
def allow_face_up?()
size() <= ALLOW_FACE_UP_COUNT
end
end
class WarDeck < Deck
HAND_SIZE = 26
TOTAL_CARDS = 52
def hand_size()
HAND_SIZE
end
def hand_class()
WarHand
end
def ranks()
Card::RANKS
end
end
##########################
#####
##### Belote
#####
class BeloteHand < Hand
CARRE_COUNT = 4
def highest_of_suit(suit)
power = BeloteDeck::RANKS
highest = Card.new(7, :spades)
select { |c| c.suit == suit}
.each { |c| highest = c if power[c.rank] > power[highest.rank] }
highest
end
def belote?()
kings = select { |card| card.rank == :king }
kings.each do |king|
match = select do |card|
card.rank == :queen and card.suit == king.suit
end
return true if match.size != 0
end
false
end
def tierce?()
n_in_a_row?(3)
end
def quarte?()
n_in_a_row?(4)
end
def quint?()
n_in_a_row?(5)
end
def carre_of_jacks?()
carre_of_x?(:jack)
end
def carre_of_nines?()
carre_of_x?(9)
end
def carre_of_aces?()
carre_of_x?(:ace)
end
private
def n_in_a_row?(amount)
power = BeloteDeck::RANKS
grouped = @cards.sort! { |a, b| power[a.rank] <=> power[b.rank] }
.group_by { |card| card.suit }.values
grouped.any? do |suited|
next if suited.size < amount
suited.each_cons(amount).any? do |con|
are_following_numbers?(con)
end
end
end
def are_following_numbers?(numbers)
numbers.each_cons(2).all? do |a, b|
BeloteDeck::RANKS[b.rank] - BeloteDeck::RANKS[a.rank] == 1
end
end
def carre_of_x?(rank)
select { |card| card.rank == rank }.size == CARRE_COUNT
end
end
class BeloteDeck < Deck
RANKS = Hash[[7, 8, 9, :jack, :queen, :king, 10, :ace].map.with_index.to_a]
HAND_SIZE = 8
TOTAL_CARDS = 32
def hand_size()
HAND_SIZE
end
def hand_class()
BeloteHand
end
def ranks()
RANKS
end
end
#######################
#####
##### SixtySix
#####
class SixtySixHand < Hand
def twenty?(trump_suit)
kings_and_queens?(trump_suit, ->(x, y) { x != y })
end
def forty?(trump_suit)
kings_and_queens?(trump_suit, ->(x, y) { x == y })
end
private
def kings_and_queens?(trump_suit, predicate)
- kings = select { |c| c.rank == :king and predicat.e(c.suit, trump_suit) }
+ kings = select { |c| c.rank == :king and predicate.(c.suit, trump_suit) }
kings.each do |king|
- return true if kings.select do |card|
+ return true if @cards.any? do |card|
card.rank == :queen and card.suit == king.suit
end
end
false
end
end
class SixtySixDeck < Deck
RANKS = Hash[[9, :jack, :queen, :king, 10, :ace].map.with_index.to_a]
HAND_SIZE = 6
TOTAL_CARDS = 24
def hand_size()
HAND_SIZE
end
def hand_class()
SixtySixHand
end
def ranks()
RANKS
end
end
-

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

От коментарите в кода няма никакъв смисъл, занапред не оставяй такива.

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