为数组中的相似对象赋值 - BlackJack

Assign value to similar objects in array - BlackJack

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

根据规则,玩家可以假设 A 可以是 1 或 11,如果你有 2 张牌就没问题,如果有 3 张牌就麻烦了。

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

我如何对 ruby 说其中一张 A 的值为 11 而另一张为 1?数组的元素是 class 具有值属性的卡片的对象。

更新

我对其中一个答案进行了一些编辑,所以如果我没有得到 ace 并且得分超过 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

我使用其中一个评论想法将方法重构为 2 行:

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

对 A 使用哈希。

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

简单,key/value 对存储附加值。

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

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

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

如果前两张牌没有出:BLACKJACK,玩家可以选择用这两张牌停牌(:HOLD)或者可以向庄家索要第三张牌(:HIT).因此,如果前两张牌不产生二十一点,我将在计算总分的方法中添加一个参数 hold_or_hit。(Tt 可能更有用,因为参数是玩家用来决定的规则介于 hold 和 hit 之间。)如果玩家选择 "hit" 并且三张牌的总和小于 21,则玩家可以要求另一张 "hit",依此类推。由于问题的措辞,我假设这里最多可以请求一次命中。

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

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 反映了一张 A 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

说 A 值涉及任何玩家选择是一种误导。一手二十一点的点数其实是有严格规定的,很简单:

  1. 把 A 算作一个。期间.
  2. 如果手牌总数小于12,且手牌中至少有一张A,则加10并标记"soft"。

就是这样。无需弄乱单个卡片值、计算 A 或任何其他废话。只需使用上述规则编写一个简单的函数来 return 手牌的价值。