Лучший способ инициализации колоды карт - PullRequest
2 голосов
/ 21 февраля 2011

Есть ли более простой способ сделать это вместо вставки каждого элемента в массив вручную

stack_of_cards << Card.new("A", "Spades", 1)
stack_of_cards << Card.new("2", "Spades", 2)
stack_of_cards << Card.new("3", "Spades", 3)
stack_of_cards << Card.new("4", "Spades", 4)
stack_of_cards << Card.new("5", "Spades", 5)
stack_of_cards << Card.new("6", "Spades", 6)
stack_of_cards << Card.new("7", "Spades", 7)
stack_of_cards << Card.new("8", "Spades", 8)
stack_of_cards << Card.new("9", "Spades", 9)
stack_of_cards << Card.new("10", "Spades", 10)
stack_of_cards << Card.new("J", "Spades", 11)
stack_of_cards << Card.new("Q", "Spades", 12)
stack_of_cards << Card.new("K", "Spades", 13)

stack_of_cards << Card.new("A", "Hearts", 1)
stack_of_cards << Card.new("2", "Hearts", 2)
stack_of_cards << Card.new("3", "Hearts", 3)
stack_of_cards << Card.new("4", "Hearts", 4)
stack_of_cards << Card.new("5", "Hearts", 5)
stack_of_cards << Card.new("6", "Hearts", 6)
stack_of_cards << Card.new("7", "Hearts", 7)
stack_of_cards << Card.new("8", "Hearts", 8)
stack_of_cards << Card.new("9", "Hearts", 9)
stack_of_cards << Card.new("10", "Hearts", 10)
stack_of_cards << Card.new("J", "Hearts", 11)
stack_of_cards << Card.new("Q", "Hearts", 12)
stack_of_cards << Card.new("K", "Hearts", 13)

stack_of_cards << Card.new("A", "Diamonds", 1)
stack_of_cards << Card.new("2", "Diamonds", 2)
stack_of_cards << Card.new("3", "Diamonds", 3)
stack_of_cards << Card.new("4", "Diamonds", 4)
stack_of_cards << Card.new("5", "Diamonds", 5)
stack_of_cards << Card.new("6", "Diamonds", 6)
stack_of_cards << Card.new("7", "Diamonds", 7)
stack_of_cards << Card.new("8", "Diamonds", 8)
stack_of_cards << Card.new("9", "Diamonds", 9)
stack_of_cards << Card.new("10", "Diamonds", 10)
stack_of_cards << Card.new("J", "Diamonds", 11)
stack_of_cards << Card.new("Q", "Diamonds", 12)
stack_of_cards << Card.new("K", "Diamonds", 13)

stack_of_cards << Card.new("A", "Clubs", 1)
stack_of_cards << Card.new("2", "Clubs", 2)
stack_of_cards << Card.new("3", "Clubs", 3)
stack_of_cards << Card.new("4", "Clubs", 4)
stack_of_cards << Card.new("5", "Clubs", 5)
stack_of_cards << Card.new("6", "Clubs", 6)
stack_of_cards << Card.new("7", "Clubs", 7)
stack_of_cards << Card.new("8", "Clubs", 8)
stack_of_cards << Card.new("9", "Clubs", 9)
stack_of_cards << Card.new("10", "Clubs", 10)
stack_of_cards << Card.new("J", "Clubs", 11)
stack_of_cards << Card.new("Q", "Clubs", 12)
stack_of_cards << Card.new("K", "Clubs", 13)

Ответы [ 7 ]

6 голосов
/ 21 февраля 2011

Просто обведите все ряды и костюмы.

ranks = %w{A 2 3 4 5 6 7 8 9 10 J Q K}
suits = %w{Spades Hearts Diamonds Clubs}
suits.each do |suit|
  ranks.size.times do |i|
    stack_of_cards << Card.new( ranks[i], suit, i+1 )
  end
end
2 голосов
/ 21 февраля 2011

Да, есть: создать массив граней и массив костюмов, а затем выполнить итерацию по ним во вложенном цикле.Также измените класс Card, чтобы вам не приходилось указывать грань в виде строки как целое число, поскольку это избыточно.Это наиболее удобно, если вам нужно только указать параметр int.

Таким образом код будет выглядеть следующим образом:

faces = 1..13
suits = %w(Spades Hearts Diamonds Clubs)
cards = suits.flat_map do |suit|
  faces.map |face_int_value|
    Card.new(suit, face_int_value)
  end
end

Или в ruby ​​до 1.9.2:

faces = 1..13
suits = %w(Spades Hearts Diamonds Clubs)
cards = suits.map do |suit|
  faces.map |face_int_value|
    Card.new(suit, face_int_value)
  end
end.flatten
1 голос
/ 21 февраля 2011

Прежде всего: почему вы представляете ранг и стоимость карты отдельно? Есть ли когда-нибудь случай, когда, скажем, Джек не имеет значение 11? Например, почему у вас

Card.new("7", "Spades", 7)

вместо

Card.new(7, "Spades")

и есть ли когда-нибудь случай, когда у вас будет

Card.new("7", "Spades", 42)

Если нет, то эти два должны быть упакованы вместе в объект.

Кроме того, почему костюмы представлены в виде строк, а не в виде Suit s или, по крайней мере, в виде символов?

Я бы, наверное, сделал что-то вроде этого:

Rank = Struct.new(:rank, :value) do
  def to_s; rank end
  alias_method :inspect, :to_s
end

Card = Struct.new(:rank, :suit) do
  def to_s; "#{rank} of #{suit.capitalize}" end
  alias_method :inspect, :to_s
end

ranks = %w[Ace 2 3 4 5 6 7 8 9 10 Jack Queen King].map.with_index {|rank, value|
  Rank.new(rank, value + 1)
}

suits = [:spades, :hearts, :diamonds, :clubs]

deck = suits.product(ranks).map {|suit, rank| Card.new(rank, suit) }
0 голосов
/ 30 октября 2015

Вот два способа сделать колоду карт в Ruby.

1.Массив массивов

... проще, но может быть сложнее, если вам нужно сравнивать карточки друг с другом (проект кода вежливости от Академии Tealeaf)

values = ["A", 2, 3, 4, 5, 6, 7, 8, 9, 10, "J", "Q", "K" ]
suits = [ "hearts", "spades", "clubs", "diamonds" ]
deck = values.product(suits)

=> [["A", "hearts"], ["A", "spades"], ["A", "clubs"], ["A", "diamonds"] #etc...

Вы также можете добавить.huffle или .shuffle!на палубу

deck = values.product(suits).shuffle

=> [[9, "diamonds"], [2, "clubs"], [7, "spades"], [4, "clubs"] #etc...

2.Массив хэшей с числовыми баллами, связанными с каждой карточкой

... так что вы можете легко сортировать или сравнивать карточки с помощью "баллов" (любезно предоставлено @amaseda в Генеральной Ассамблее DC)

def deck_o_cards
  values = [2, 3, 4, 5, 6, 7, 8, 9, 10, 'J', 'Q', 'K', 'A']
  suits = ['hearts', 'diamonds', 'clubs', 'spades']
  deck = []

  values.each_with_index do |v, i|
    suits.each do |s|
      deck.push({
        score: i,
        value: v,
        suit: s,
      })
    end
  end

  return deck.shuffle
end

=> [{:score=>8, :value=>10, :suit=>"hearts"}, {:score=>4, :value=>6, :suit=>"diamonds"}, #etc...
0 голосов
/ 08 октября 2012
Card = Struct.new(:name, :suit,:number) 
stack_of_cards = []
%w{'Spades Hearts Diamonds Clubs'}.each do |suit|
    %w{'A 2 3 4 5 6 7 8 9 10 J Q K'}.each_with_index do |name, i|
        stack_of_cards << Card.new(name, suit, i+1) 
    end
end
p stack_of_cards
0 голосов
/ 21 февраля 2011

Дэвид А. Блэк Хорошо заземленный рубист использует инициализацию колоды как способ демонстрации метода cycle. Я думаю, что полученный код является умным и очень простым:

class Card 
  SUITS = %w{ clubs diamonds hearts spades } 
  RANKS=%w{2345678910JQKA}
  class Deck 
    attr_reader :cards
    def initialize(n=1) 
      @cards = [] SUITS.cycle(n) do |s|
        RANKS.cycle(1) do |r| @cards << "#{r} of #{s}"
        end
      end
    end 
  end
end

Кроме того, Ruby Quiz # 1: Solitaire Cipher включал использование колоды карт для кодирования сообщения. Проверьте решения. Вы увидите несколько разных способов решения этой проблемы.

0 голосов
/ 21 февраля 2011

Опираясь на решение Марка Рушакова и используя Ruby 1.9

Card = Struct.new(:rank, :suit,:rank_id) 
ranks = %w{A 2 3 4 5 6 7 8 9 10 J Q K}
suits = %w{Spades Hearts Diamonds Clubs}
stack_of_cards = suits.each_with_object([]) do |suit,res|
  ranks.size.times do |i|
    res << Card.new(ranks[i], suit,i + 1)
  end
end
puts stack_of_cards.inspect
...