简单说明我的故障是这样的: 1.查找包含“选项”值的哈希 2.提示用户应该选择“选项”的值 3.将“选项”更改为用户想要的值(11或1)
我正在构建一个Blackjack游戏以更好地理解Ruby,并且我试图让用户能够从“手”中切换出值。我将牌组存储为包含牌组的哈希,然后像这样得分值:D8 => 8这是八颗钻石价值八分。 Aces,因为它们可以是1或11,就像这样存储:: SA => “选项。”
我希望能够提示用户输入值或者这是当前代码的一部分:
def checkAce
if @player_hand.has_value?("option")
puts "What do you want your aces to be worth? 11 or 1"
ace_value = gets.chomp
aces = @player_hand.find {|k, v| @player_hand[k] == "option"}
if ace_value == "1" || ace_value == "11"
aces.each { |k, v| aces[k] = ace_value }
else
checkAce
end
# merge back into hand
@player_hand.merge!(aces)
else
puts "No aces, so on to the main event."
end
end
但是这段代码不起作用:首先,ace_value给了我一个类型错误,说符号不能被强制转换为整数。第二,@ player_hand.merge!(aces)找不到方法。有什么建议吗?
答案 0 :(得分:1)
您的代码出现错误:
aces = @player_hand.find {|k, v| @player_hand[k] == "option"}
根据documentation,find返回第一个匹配值,而不是每个匹配值。你可能想要的是#find_all
。
例如:
hand = { a: 1, b: 2, c: 'option', d: 'option' }
hand.find { |_, v| v == 'option' } # => [:c, "option"]
hand.find_all { |_, v| v == 'option' } # => [[:c, "option"], [:d, "option"]]
您还会注意到,返回的内容不是哈希值,而是数组。您可以使用Hash[ [ [key, value], ... ] ]
来获取哈希值。
例如:
Hash[[:c, "option"], [:d, "option"]] # => {[:c, "option"]=>[:d, "option"]}
因此,将它们放在一起,您可以使用以下内容提取哈希的相关部分:
hand = { a: 1, b: 2, c: 'option', d: 'option' }
aces = Hash[hand.find_all { |_, v| v == 'option' }]
其余代码按预期工作:
ace_value = 4
aces.each { |k, v| aces[k] = ace_value }
hand.merge!(aces) # => {:a=>1, :b=>2, :c=>4, :d=>4}
我真的不知道"最好的"更改与值匹配的哈希值的方法,但以下内容可能更少:
hand = { a: 1, b: 2, c: 'option', d: 'option' }
option_value = 'option'
ace_value = 4
hand.each do |k, v|
if v == option_value
hand[k] = ace_value
end
end # => {:a=>1, :b=>2, :c=>4, :d=>4}
你可以缩短为
hand.each { |k, v| hand[k] = ace_value if v == option_value }
如果你愿意的话。
答案 1 :(得分:1)
不一定非常有必要使用merge!。只需迭代哈希值即可更改相应的值。
def check_ace
if @player_hand.has_value?("option")
# get your input ace_value
# ...
if ["1", "11"].include?(ace_value)
@player_hand.each_key { |k| @player_hand[k] = ace_value if @player_hand[k] == "option" }
else
check_ace
end
else
puts "No aces, so on to the main event."
end
end
答案 2 :(得分:0)
因此,通过哈希映射在ruby中有点笨拙。这是基本的想法:
data = { a: 1, b: 2, c: 3 }
data = data.map do |k, v|
if k == :b
[k, 4]
else
[k, v]
end
end.to_h
p(data) #=> {:a=>1, :b=>4, :c=>3}
如果有人知道一种更容易/更清洁的方式,我也会有兴趣看到它。
编辑:coderz
有更好的答案,因为在这种情况下,您只需要更改一些值,而不是映射整个哈希值。