【问题标题】:Assign value to similar objects in array - BlackJack为数组中的相似对象赋值 - BlackJack
【发布时间】:2018-07-24 11:23:27
【问题描述】:

所以我最近在做 BlackJack 项目,我现在有点卡在 Ace 值程序上。

根据规则,玩家可以假设 Ace 可以是 1 或 11,如果你有 2 张牌,那就太平了,3 张牌有问题。

我有一组 3 张牌和 2 个 A,可以是 - [A, A, 9], [A, 9, A], [9, A, A]

我如何对 ruby​​ 说其中一个 A 的值应该是 11,而另一个应该是 1?数组的元素是具有 value 属性的 Card 类的对象。

更新

我拿了一个答案并稍微编辑了一下,所以如果我没有 A 并且得分超过 21,我得到的不是零值

def score_array aces, non_aces = current_cards.partition(&:ace?) base_value = non_aces.sum(&:value) + aces.size return base_value unless aces? score_array = Array.new(aces.size + 1) { |high_aces| base_value + 10 * high_aces } ace_value = score_array.select { |score| score <= 21 }.max end

更新 2

我已经使用 cmets 的想法将方法重构为 2 行:

def count_score @score = current_cards.sum(&:value) @score += 10 if score < 12 && aces? end

【问题讨论】:

    标签: ruby blackjack


    【解决方案1】:

    说 A 的价值涉及任何玩家选择是一种误导。二十一点手牌的价值实际上是由规则严格固定的,这很简单:

    1. 将 A 计为 1。期间。
    2. 如果一手牌的总点数小于 12,并且该手牌至少包含一张 A,则加 10 并将其标记为“软”。

    就是这样。无需弄乱个人牌面值、数 A 或任何其他废话。只需编写一个简单的函数来使用上述规则返回手牌的值。

    【讨论】:

    • 谢谢。这很有帮助,我现在将我的方法重构为 2 行。
    【解决方案2】:

    对 A 使用哈希。

    cards = [{A: 1}, {A: 11}, 9]
    

    用于存储附加值的简单键/值对。

    【讨论】:

      【解决方案3】:

      不要说 Ace 是 1 或 11,因为它并不是真正需要的:要说 [A, A, 9] 的值是 11、21 或 31。一种简单的方法,假设 card.ace?返回一个布尔值,card.value 为任何非 Ace 的整数:

      def score(cards)
        aces, non_aces = cards.partition { |card| card.ace? }
        base_value = non_aces.sum { |card| card.value } + aces.size
        return (aces.size + 1).times.map { |high_aces| base_value + 10 * high_aces }
      end
      

      那么你就可以轻松挑出不超过21的最高分:

      def hand_score(cards)
        score(cards).select { |x| x <= 21 }.max
      end
      

      【讨论】:

        【解决方案4】:

        cards 是一个 3 元素数组,每个元素是 :A(用于 ace)或介于 210 之间的数字。最初发给玩家的牌对应于cards 的前两个元素。如果其中一张是 A,另一张是 10,则返回 :BLACKJACK,玩家赢了庄家(除非庄家也有二十一点。请注意,[:A, 10] 胜过[:A, 4, 6][:A, :A, 9])。

        如果前两张牌没有产生:BLACKJACK,玩家可以选择用两张牌(:HOLD)站着拍,或者可以向庄家请求第三张牌(:HIT)。因此,如果前两张牌没有产生二十一点,我将在计算总分的方法中添加一个参数hold_or_hit。(对于作为玩家用来决定是否保留的规则的参数,Tt 可能更有用并击中。)如果玩家选择“击中”并且三张牌的总和小于21,则玩家可以要求另一个“击中”,依此类推。由于问题的措辞,我假设这里最多可以请求一次点击。

        简单计算三张牌的总和并不是特别有用,所以我将修改返回值以更接近实际游戏。

        def outcome(cards, hold_or_hit)
          return 13 if hold_or_hit == :HIT && cards.count(:A) == 3 
          first2 = cards[0,2]
          return :BLACK_JACK if first2 == [:A,10] || first2 == [10,:A]
          total(hold_or_hit == :HOLD ? first2 : cards)
        end
        
        def total(arr)
          sum_non_aces = arr.sum { |c| c == :A ? 0 : c }
          sum_non_aces +
          case arr.count(:A)
            when 0
              0
            when 1
              sum_non_aces > 10 ? 1 : 11
            else
              12
            end
          end
        end
        

        请注意,在total 中,如果arr.count(:A) == 212 反映一个王牌11,另一个1

        outcome [10, :A,  4], :HOLD  #=> :BLACK_JACK
        outcome [ 9, :A,  4], :HOLD  #=> 20
        outcome [ 9, :A,  4], :HIT   #=> 14
        outcome [:A, :A,  4], :HIT   #=> 16
        outcome [:A, :A,  9], :HIT   #=> 21
        outcome [:A, :A,  9], :HOLD  #=> 12
        outcome [ 7,  9,  6], :HOLD  #=> 16
        outcome [ 7,  9,  6], :HIT   #=> 22
        outcome [:A, :A, :A], :HIT   #=> 13
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-03-14
          • 2014-01-02
          • 2022-11-10
          • 1970-01-01
          • 2011-06-21
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多