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

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

Към профила на Десислава Цветкова

Резултати

  • 6 точки от тестове
  • 1 отнета точка
  • 5 точки общо
  • 55 успешни тест(а)
  • 2 неуспешни тест(а)

Код

class Card
attr_accessor :rank, :suit
def initialize(rank, suit)
@rank = rank
@suit = suit
end
def to_s
"#{@rank.to_s.capitalize} of #{@suit.to_s.capitalize}"
end
def inspect
"#{@rank.to_s.capitalize} of #{@suit.to_s.capitalize}"
end
def ==(other)
@rank == other.rank and @suit == other.suit
end
end
module Sizer
def size
@cards.size
end
end
class Deck
include Sizer
include Enumerable
attr_accessor :cards
HAND_SIZE = 52
RANKS = [2, 3, 4, 5, 6, 7, 8, 9, 10, :jack, :queen, :king, :ace]
SUITS =[:spades, :hearts, :diamonds,:clubs]
class << self
def generate_full_deck
self::RANKS.product(self::SUITS).map{|x| Card.new(x.first, x.last)}
end
def sorting_ranks_suit(ranks, suits, card_first, card_second)
comp_suit = suits.index(card_first.suit) <=> suits.index(card_second.suit)
comp_rank = ranks.index(card_second.rank) <=> ranks.index(card_first.rank)
return comp_suit unless comp_suit == 0
return comp_rank
end
def sorting(card_first, card_second)
sorting_ranks_suit(self::RANKS, self::SUITS, card_first, card_second)
end
end
def initialize(cards = nil)
if cards.nil?
@cards = self::class::generate_full_deck
sort
else
@cards = cards.clone
end
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!(&self::class.method(:sorting))
end
def each
@cards.each{|card| yield(card)}
end
def to_s
@cards.reduce("") {|whole_string, x| whole_string + "\n" + x.to_s}.strip
end
def deal
deal_elements = []
smaller = [self::class::HAND_SIZE, @cards.size].min
1.upto(smaller) {deal_elements << draw_top_card}
self::class.class_variable_get(:@@hand).new(deal_elements)
end
end
class WarDeck < Deck
RANKS = [2, 3, 4, 5, 6, 7, 8, 9, 10, :jack, :queen, :king, :ace]
HAND_SIZE = 26
@@hand = Class.new do
include Sizer
def initialize(cards)
@cards = cards
end
def play_card
@cards.pop
end
def allow_face_up?
@cards.size <= 3
end
end
end
class BeloteDeck < Deck
RANKS = [7, 8, 9, :jack, :queen, :king, 10, :ace]
HAND_SIZE = 8
def self.consecutive?(cards)
# проверява дали cards са последователни
all_consecutive = true
cards.each_cons(2) do | (card_first, card_second) |
# -1 защото са сортирани в намаляващ ред
if RANKS.index(card_first.rank) - 1 != RANKS.index(card_second.rank)
all_consecutive = false
end
end
all_consecutive
end
def self.sequence(number, cards)
# Групираме ги по бои и после ще проверим дали има n последователни
# от всяка бои.
sorted = cards.sort(&BeloteDeck.method(:sorting)).group_by do |card|
card.suit
end
# Разглеждаме ги по боя, дали вътре има number последователни
sorted.each do |cards|
cards = cards.last
result = cards.each_cons(number).reduce(false) do |result, group_cards|
result or consecutive?(group_cards)
end
return result if true
end
# връща false, ако вече не е върнало true
false
end
@@hand = Class.new do
include Sizer
def initialize(cards)
@cards = cards
end
def highest_of_suit(suit)
@cards.sort(&BeloteDeck.method(:sorting)).find do |card|
card.suit == suit
end
end
def belote?
kings_queens = @cards.select do |card|
card.rank == :queen or card.rank == :king
end
kings_queens.permutation(2).any? do | (card_first, card_second) |
equal_suits = card_first.suit == card_second.suit
different_ranks = card_first.rank != card_second.rank
equal_suits and different_ranks
end
end
def tierce?
BeloteDeck.sequence(3, @cards)
end
def quarte?
BeloteDeck.sequence(4, @cards)
end
def quint?
BeloteDeck.sequence(5, @cards)
end
def carre(suit)
grouped_cards = @cards.group_by{|card| card.rank}
grouped_cards[suit].nil? ? false : grouped_cards[suit].size == 4
end
def carre_of_jacks?
carre(:jack)
end
def carre_of_nines?
carre(9)
end
def carre_of_aces?
carre(:ace)
end
end
end
class SixtySixDeck < Deck
RANKS = [9, :jack, :queen, :king, 10, :ace]
HAND_SIZE = 6
@@hand = Class.new do
include Sizer
def initialize(cards)
@cards = cards
end
def king_and_queen?(cards)
kings_queens = cards.select do |card|
card.rank == :queen or card.rank == :king
end
kings_queens.permutation(2).any? do | (card_first, card_second) |
equal_suits = card_first.suit == card_second.suit
different_ranks = card_first.rank != card_second.rank
equal_suits and different_ranks
end
end
def twenty?(trump_suit)
cards_no_trump_suit = @cards.reject{|card| card.suit == trump_suit}
king_and_queen?(cards_no_trump_suit)
end
def forty?(trump_suit)
cards_trump_suit = @cards.select{|card| card.suit == trump_suit}
king_and_queen?(cards_trump_suit)
end
end
end

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

..............................FF.........................

Failures:

  1) BeloteDeck hand #tierce? with tierce returns true for cards with names
     Failure/Error: expect(hand.tierce?).to be true
       
       expected #<TrueClass:20> => true
            got #<FalseClass:0> => false
       
       Compared using equal?, which compares object identity,
       but expected and actual are not the same object. Use
       `expect(actual).to eq(expected)` if you don't care about
       object identity in this example.
     # /tmp/d20151112-27349-15t4ps7/spec.rb:284:in `block (5 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 #tierce? with tierce returns true for cards with numbers
     Failure/Error: expect(hand.tierce?).to be true
       
       expected #<TrueClass:20> => true
            got #<FalseClass:0> => false
       
       Compared using equal?, which compares object identity,
       but expected and actual are not the same object. Use
       `expect(actual).to eq(expected)` if you don't care about
       object identity in this example.
     # /tmp/d20151112-27349-15t4ps7/spec.rb:299:in `block (5 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.04307 seconds
57 examples, 2 failures

Failed examples:

rspec /tmp/d20151112-27349-15t4ps7/spec.rb:272 # BeloteDeck hand #tierce? with tierce returns true for cards with names
rspec /tmp/d20151112-27349-15t4ps7/spec.rb:287 # BeloteDeck hand #tierce? with tierce returns true for cards with numbers

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

Десислава обнови решението на 07.11.2015 20:20 (преди над 8 години)

+class Card
+ attr_accessor :rank, :suit
+
+ def initialize(rank, suit)
+ @rank = rank
+ @suit = suit
+ end
+
+ def to_s
+ "#{@rank.to_s.capitalize} of #{@suit.to_s.capitalize}"
+ end
+
+ def inspect
+ "#{@rank.to_s.capitalize} of #{@suit.to_s.capitalize}"
+ end
+
+ def ==(other)
+ @rank == other.rank and @suit == other.suit
+ end
+end
+
+module Sizer
+ def size
+ @cards.size
+ end
+end
+
+
+class Deck
+ include Sizer
+ include Enumerable
+
+ attr_accessor :cards
+ HAND_SIZE = 52
+ RANKS = [2, 3, 4, 5, 6, 7, 8, 9, 10, :jack, :queen, :king, :ace]
+ SUITS =[:spades, :hearts, :diamonds,:clubs]
+
+ class << self
+ def generate_full_deck
+ self::RANKS.product(self::SUITS).map{|x| Card.new(x.first, x.last)}
+ end
+
+ def sorting_ranks_suit(ranks, suits, card_first, card_second)
+ comp_suit = suits.index(card_first.suit) <=> suits.index(card_second.suit)
+ comp_rank = ranks.index(card_second.rank) <=> ranks.index(card_first.rank)
+ return comp_suit unless comp_suit == 0
+ return comp_rank
+ end
+
+ def sorting(card_first, card_second)
+ # comment for myself:
+ # self here is the class
+ sorting_ranks_suit(self::RANKS, self::SUITS, card_first, card_second)
+ end
+ end
+
+ def initialize(cards = nil)
+ if cards.nil?
+ @cards = self::class::generate_full_deck
+ else
+ @cards = cards
+ end
+ end
+
+ def draw_top_card
+ self.next
+ 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!(&self::class.method(:sorting))
+ end
+
+ def each
+ @cards.each{|card| yield(card)}
+ end
+
+ def to_s
+ @cards.reduce("") {|whole_string, x| whole_string + "\n" + x.to_s}.strip
+ end
+
+ def deal
+ # comment for myself:
+ # self here is the instance
+ self::class.class_variable_get(:@@hand).new(take(self::class::HAND_SIZE))
+ end
+
+end
+
+
+class WarDeck < Deck
+ RANKS = [2, 3, 4, 5, 6, 7, 8, 9, 10, :jack, :queen, :king, :ace]
+ HAND_SIZE = 26
+ @@hand = Class.new do
+ include Sizer
+
+ def initialize(cards)
+ @cards = cards
+ end
+
+ def play_card
+ @cards.pop
+ end
+
+ def allow_face_up?
+ @cards.size <= 3
+ end
+ end
+end
+
+
+class BeloteDeck < Deck
+ RANKS = [7, 8, 9, :jack, :queen, :king, 10, :ace]
+
+ HAND_SIZE = 8
+
+ def self.consecutive?(cards)
+ # проверява дали cards са последователни
+ all_consecutive = true
+ cards.each_cons(2) do | (card_first, card_second) |
+ # -1 защото са сортирани в намаляващ ред
+ if RANKS.index(card_first.rank) - 1 != RANKS.index(card_second.rank)
+ all_consecutive = false
+ end
+ end
+ all_consecutive
+ end
+
+ def self.sequence(number, cards)
+ # Групираме ги по бои и после ще проверим дали има n последователни
+ # от всяка бои.
+ sorted = cards.sort(&BeloteDeck.method(:sorting)).group_by do |card|
+ card.suit
+ end
+ # Разглеждаме ги по боя, дали вътре има number последователни
+ sorted.each do |cards|
+ cards = cards.last
+ result = cards.each_cons(number).reduce(false) do |result, group_cards|
+ result or consecutive?(group_cards)
+ end
+ return result if true
+ end
+ # връща false, ако вече не е върнало true
+ false
+ end
+
+ @@hand = Class.new do
+ include Sizer
+
+ def initialize(cards)
+ @cards = cards
+ end
+
+ def highest_of_suit(suit)
+ @cards.sort(&BeloteDeck.method(:sorting)).find do |card|
+ card.suit == suit
+ end
+ end
+
+ def belote?
+ kings_queens = @cards.select do |card|
+ card.rank == :queen or card.rank == :king
+ end
+ kings_queens.permutation(2).any? do | (card_first, card_second) |
+ equal_suits = card_first.suit == card_second.suit
+ different_ranks = card_first.rank != card_second.rank
+ equal_suits and different_ranks
+ end
+ end
+
+ def tierce?
+ BeloteDeck.sequence(3, @cards)
+ end
+
+ def quarte?
+ BeloteDeck.sequence(4, @cards)
+ end
+
+ def quint?
+ BeloteDeck.sequence(5, @cards)
+ end
+
+ def carre(suit)
+ grouped_cards = @cards.group_by{|card| card.rank}
+ grouped_cards[suit].nil? ? false : grouped_cards[suit].size == 4
+ end
+
+ def carre_of_jacks?
+ carre(:jack)
+ end
+
+ def carre_of_nines?
+ carre(9)
+ end
+
+ def carre_of_aces?
+ carre(:ace)
+ end
+ end
+end
+
+
+class SixtySixDeck < Deck
+ RANKS = [9, :jack, :queen, :king, 10, :ace]
+ HAND_SIZE = 6
+ @@hand = Class.new do
+ include Sizer
+
+ def initialize(cards)
+ @cards = cards
+ end
+
+ def king_and_queen?(cards)
+ kings_queens = cards.select do |card|
+ card.rank == :queen or card.rank == :king
+ end
+ kings_queens.permutation(2).any? do | (card_first, card_second) |
+ equal_suits = card_first.suit == card_second.suit
+ different_ranks = card_first.rank != card_second.rank
+ equal_suits and different_ranks
+ end
+ end
+
+ def twenty?(trump_suit)
+ cards_no_trump_suit = @cards.reject{|card| card.suit == trump_suit}
+ king_and_queen?(cards_no_trump_suit)
+ end
+
+ def forty?(trump_suit)
+ cards_trump_suit = @cards.select{|card| card.suit == trump_suit}
+ king_and_queen?(cards_trump_suit)
+ end
+ end
+end

Десислава обнови решението на 09.11.2015 11:21 (преди над 8 години)

class Card
attr_accessor :rank, :suit
def initialize(rank, suit)
@rank = rank
@suit = suit
end
def to_s
"#{@rank.to_s.capitalize} of #{@suit.to_s.capitalize}"
end
def inspect
"#{@rank.to_s.capitalize} of #{@suit.to_s.capitalize}"
end
def ==(other)
@rank == other.rank and @suit == other.suit
end
end
module Sizer
def size
@cards.size
end
end
class Deck
include Sizer
include Enumerable
attr_accessor :cards
HAND_SIZE = 52
RANKS = [2, 3, 4, 5, 6, 7, 8, 9, 10, :jack, :queen, :king, :ace]
SUITS =[:spades, :hearts, :diamonds,:clubs]
class << self
def generate_full_deck
self::RANKS.product(self::SUITS).map{|x| Card.new(x.first, x.last)}
end
def sorting_ranks_suit(ranks, suits, card_first, card_second)
comp_suit = suits.index(card_first.suit) <=> suits.index(card_second.suit)
comp_rank = ranks.index(card_second.rank) <=> ranks.index(card_first.rank)
return comp_suit unless comp_suit == 0
return comp_rank
end
def sorting(card_first, card_second)
- # comment for myself:
- # self here is the class
sorting_ranks_suit(self::RANKS, self::SUITS, card_first, card_second)
end
end
def initialize(cards = nil)
if cards.nil?
@cards = self::class::generate_full_deck
+ sort
else
- @cards = cards
+ @cards = cards.clone
end
end
def draw_top_card
- self.next
+ @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!(&self::class.method(:sorting))
end
def each
@cards.each{|card| yield(card)}
end
def to_s
@cards.reduce("") {|whole_string, x| whole_string + "\n" + x.to_s}.strip
end
def deal
- # comment for myself:
- # self here is the instance
- self::class.class_variable_get(:@@hand).new(take(self::class::HAND_SIZE))
+ deal_elements = []
+ smaller = [self::class::HAND_SIZE, @cards.size].min
+ 1.upto(smaller) {deal_elements << draw_top_card}
+ self::class.class_variable_get(:@@hand).new(deal_elements)
end
end
class WarDeck < Deck
RANKS = [2, 3, 4, 5, 6, 7, 8, 9, 10, :jack, :queen, :king, :ace]
HAND_SIZE = 26
@@hand = Class.new do
include Sizer
def initialize(cards)
@cards = cards
end
def play_card
@cards.pop
end
def allow_face_up?
@cards.size <= 3
end
end
end
class BeloteDeck < Deck
RANKS = [7, 8, 9, :jack, :queen, :king, 10, :ace]
HAND_SIZE = 8
def self.consecutive?(cards)
# проверява дали cards са последователни
all_consecutive = true
cards.each_cons(2) do | (card_first, card_second) |
# -1 защото са сортирани в намаляващ ред
if RANKS.index(card_first.rank) - 1 != RANKS.index(card_second.rank)
all_consecutive = false
end
end
all_consecutive
end
def self.sequence(number, cards)
# Групираме ги по бои и после ще проверим дали има n последователни
# от всяка бои.
sorted = cards.sort(&BeloteDeck.method(:sorting)).group_by do |card|
card.suit
end
# Разглеждаме ги по боя, дали вътре има number последователни
sorted.each do |cards|
cards = cards.last
result = cards.each_cons(number).reduce(false) do |result, group_cards|
result or consecutive?(group_cards)
end
return result if true
end
# връща false, ако вече не е върнало true
false
end
@@hand = Class.new do
include Sizer
def initialize(cards)
@cards = cards
end
def highest_of_suit(suit)
@cards.sort(&BeloteDeck.method(:sorting)).find do |card|
card.suit == suit
end
end
def belote?
kings_queens = @cards.select do |card|
card.rank == :queen or card.rank == :king
end
kings_queens.permutation(2).any? do | (card_first, card_second) |
equal_suits = card_first.suit == card_second.suit
different_ranks = card_first.rank != card_second.rank
equal_suits and different_ranks
end
end
def tierce?
BeloteDeck.sequence(3, @cards)
end
def quarte?
BeloteDeck.sequence(4, @cards)
end
def quint?
BeloteDeck.sequence(5, @cards)
end
def carre(suit)
grouped_cards = @cards.group_by{|card| card.rank}
grouped_cards[suit].nil? ? false : grouped_cards[suit].size == 4
end
def carre_of_jacks?
carre(:jack)
end
def carre_of_nines?
carre(9)
end
def carre_of_aces?
carre(:ace)
end
end
end
class SixtySixDeck < Deck
RANKS = [9, :jack, :queen, :king, 10, :ace]
HAND_SIZE = 6
@@hand = Class.new do
include Sizer
def initialize(cards)
@cards = cards
end
def king_and_queen?(cards)
kings_queens = cards.select do |card|
card.rank == :queen or card.rank == :king
end
kings_queens.permutation(2).any? do | (card_first, card_second) |
equal_suits = card_first.suit == card_second.suit
different_ranks = card_first.rank != card_second.rank
equal_suits and different_ranks
end
end
def twenty?(trump_suit)
cards_no_trump_suit = @cards.reject{|card| card.suit == trump_suit}
king_and_queen?(cards_no_trump_suit)
end
def forty?(trump_suit)
cards_trump_suit = @cards.select{|card| card.suit == trump_suit}
king_and_queen?(cards_trump_suit)
end
end
end

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

За клас-променливите се разбрахме.

Не оставяй такива коментари в кода, опитай да ги направиш ненужни, като го направиш максимално ясен сам по себе си.