1

以下のコードを実行すると、「スタックレベルが深すぎます」というエラーが発生します。選ばれたランダムカードがそこにない場合、それは別のランダムカードを選びます。どういうわけかコードを偶然見つけたほうがいいと思いますが、どうすればいいのかわかりません。助言がありますか?

   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
4

2 に答える 2

2

書かれているように、再帰の深さは乱数ジェネレーターに基づいて「無制限」です。デッキにカードが1枚しか残っていない場合を考えてみてください。最終的に残りの1枚のカードを選択するまで、乱数を選択して繰り返します。潜在的に非常に深いスタック。52枚のカードデッキに1枚のカードが残っている場合、残りのカードを一度も選択しない確率は51/52 = 98%です。それを選択する可能性が50%になるには、約35回の反復/再帰が必要です。99%の確率で選択するには、約237回の反復が必要です (1.0 - (51/52)^237)=99%

この特定の実装を使用するには、それをループに変更する必要があります(再帰ではなく反復するだけです)。ただし、それでもあまり効率的ではなく、残りの数少ないカードの1つを見つけるまでに長い時間がかかる可能性があります。別の方法は、カードが取り除かれるときにデッキからギャップを取り除くことであり、それから常にヒットがあります。または、前もってシャッフルアルゴリズムを使用してから、それらを順番に繰り返すこともできます。

于 2012-10-04T13:24:31.373 に答える
1

再帰がエラーの原因であると言っても差し支えないと思います。私には、再帰は必要ないようです。drawn_card!= 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
于 2012-10-04T13:28:12.903 に答える