为数组中的相似对象赋值 - 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)或 2
和 10
之间的数字。最初发给玩家的牌对应于 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) == 2
,12
反映了一张 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 值涉及任何玩家选择是一种误导。一手二十一点的点数其实是有严格规定的,很简单:
- 把 A 算作一个。期间.
- 如果手牌总数小于12,且手牌中至少有一张A,则加10并标记"soft"。
就是这样。无需弄乱单个卡片值、计算 A 或任何其他废话。只需使用上述规则编写一个简单的函数来 return 手牌的价值。
所以我最近在做 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)或 2
和 10
之间的数字。最初发给玩家的牌对应于 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) == 2
,12
反映了一张 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 值涉及任何玩家选择是一种误导。一手二十一点的点数其实是有严格规定的,很简单:
- 把 A 算作一个。期间.
- 如果手牌总数小于12,且手牌中至少有一张A,则加10并标记"soft"。
就是这样。无需弄乱单个卡片值、计算 A 或任何其他废话。只需使用上述规则编写一个简单的函数来 return 手牌的价值。