【问题标题】:Better way of initializing a deck of cards初始化一副纸牌的更好方法
【发布时间】:2011-02-21 11:50:39
【问题描述】:

有没有更简单的方法来代替手动将每个元素插入到数组中

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)

【问题讨论】:

  • 设计一个方案来用一个数字来表示每张卡片,编写方法来确定它的面和类型。然后只需使用从 1 到 52 的循环数填充一个数组

标签: ruby loops playing-cards


【解决方案1】:

只需遍历等级和花色即可。

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

【讨论】:

  • 我可能会建议内部循环应该是:ranks.each_with_index do |rank,i| 允许将ranks[i] 替换为rank
  • 我会使用suits.product(ranks.with_index.to_a).map do |suit, (rank, index)|
【解决方案2】:

是的,有:创建一组面孔和一组西装,然后在嵌套循环中迭代它们。还要更改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

或在 1.9.2 之前的 ruby​​ 中:

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。尽管我对 Scala 的 for 理解和 C# 的 LINQ 查询理解至少表面上熟悉,它们都是基于 flatMap(或 .NET 称之为 SelectMany),但我总是忘记它也在 Enumerable现在。
【解决方案3】:

首先:为什么要分别代表一张牌的等级和价值?有没有一个例子,比如说,杰克 not 的值是 11?例如,为什么你有

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

而不仅仅是

Card.new(7, "Spades")

有没有你会遇到的实例

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

如果不是,那么这两个应该一起打包成一个对象。

另外,为什么花色表示为字符串而不是Suits 或至少是符号?

我可能会这样做:

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) }

【讨论】:

  • 由于可变性,结构有其自身的问题。例如,您不想允许card.suit = -9
【解决方案4】:

基于 Mark Rushakoff 解决方案并使用 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

【讨论】:

    【解决方案5】:

    David A. Black 的 The Well Grounded Rubyist 使用牌组初始化作为演示 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: The Solitaire Cipher 涉及使用一副纸牌对消息进行编码。查看解决方案。您将看到解决此问题的几种不同方法。

    【讨论】:

      【解决方案6】:
      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
      

      【讨论】:

        【解决方案7】:

        这里有两种用 Ruby 制作卡片组的方法。

        1。数组数组

        ...更简单,但如果您需要相互比较卡片可能会更难(Tealeaf Academy 提供的代码项目)

        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...
        

        您还可以添加 .shuffle 或 .shuffle!到甲板上

        deck = values.product(suits).shuffle
        
        => [[9, "diamonds"], [2, "clubs"], [7, "spades"], [4, "clubs"] #etc...
        

        2。带有数字分数的哈希数组与每张卡片相关联

        ...因此您可以通过“分数”轻松排序或比较卡片(由 General Assembly DC 的 @amaseda 提供)

        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...
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-06-07
          • 2023-01-11
          • 2017-08-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-12-07
          • 2017-06-17
          相关资源
          最近更新 更多