Ruby中的堆栈级别太深,试图绘制一张随机卡

Ruby中的堆栈级别太深,试图绘制一张随机卡,ruby,stack-level,Ruby,Stack Level,运行下面的代码时出现错误“堆栈级别太深”。如果随机选择的卡不在那里,它会选择另一张随机卡。我想我应该以某种方式去尝试代码,但我不知道怎么做。有什么建议吗 def hit choice_of_card = rand($deck.length); #choose a random card out of the deck drawn_card = $deck[choice_of_card]; #draw that random card from the deck i

运行下面的代码时出现错误“堆栈级别太深”。如果随机选择的卡不在那里,它会选择另一张随机卡。我想我应该以某种方式去尝试代码,但我不知道怎么做。有什么建议吗

   def hit 
    choice_of_card = rand($deck.length); #choose a random card out of the deck
    drawn_card = $deck[choice_of_card]; #draw that random card from the deck
    if drawn_card != 0 #if there is a card there 
     $deck[choice_of_card] = 0; #remove that card from the deck by making the space blank
     if drawn_card == 11 #if you draw an ace
      self.ace_count += 1;
     end 
     self.hand_value += drawn_card ;
    else hit; #if there is no card at that space then redraw (recursion)
    end
  end

如前所述,递归深度基于随机数生成器是“无限”的。当甲板上只剩下一张卡片时,考虑一下。它将继续选择随机数并递归,直到最后选择剩下的一张牌;一个非常深的堆栈。在52张牌组中剩余一张牌的情况下,一次不选择剩余牌的几率为51/52=98%。要获得50%的选择机会,您需要大约35次迭代/递归。要达到99%的选择概率,它需要大约237次迭代:
(1.0-(51/52)^237)=99%


要使用这个特定的实现,有必要将其更改为循环(只是迭代而不是递归)。然而,这仍然不是很有效,在找到剩下的几张牌中的一张之前,可能会循环很长时间。另一种方法可能是在移除卡片时移除卡片组中的间隙,然后始终会有一个命中。或者使用一个前置,然后按顺序遍历它们。

我认为可以肯定地说是递归导致了错误。在我看来,你不需要递归,你只需要循环直到你被抽到卡!=0,例如

drawn_card = 0
while drawn_card == 0
  choice_of_card = rand($deck.length); #choose a random card out of the deck
  drawn_card = $deck[choice_of_card]; #draw that random card from the deck
end

您应该检查牌组
deck.find{c | c>0}
中是否至少有一张牌,以防止无限循环或简化代码。+1表示洗牌算法。我总是发现它更适合于卡片。在Ruby中,数组有一个
洗牌
。我发现更有效的方法是说$deck。删除(卡片的选择),从而缩短数组,这样就不会有空白。