私は何年もプログラムしていますが、私が今提示している問題はおそらく私が見ているうちで最も異常なものの1つです。ランダムに三つの可能なタイプで、一連のトークンを生成し、私のアプリのコードのブロックがあり乱数ジェネレータ(非決定的に作用する)
は、のは、A、BまたはC
だから、10個のトークンがあるかもしれないABCCAAABACをしましょう。コードのブロックの開始時に
は、乱数ジェネレータのシードはこれのように初期化される:シード値が一定ときmath.randomseed(seed)
math.random()
さて、当然、私は常に、トークンの同じシーケンスを取得し、ので、ランダム生成コードは決定論的な方法で実行される。まあ、ほぼです。
実際には、まれに、青から同じ種子を与えられた異なるランダム配列が得られます。その後、私はそれを知る前に正常に戻ります。あなたはおそらく考えている - ああ、副作用、これはおそらく、トークンのランダムなシーケンスを生成するコードのブロックが何回(例えば)random()
を呼び出すかを変更する変数を利用する状態関連の問題です。しかし、私はすべての明白な副作用のために制御していると確信しています。外部の状態にアクセスするコードブロックにはわずかな場所しかなく、それらはすべて一定のままです。
プロットがさらに濃くなりました。この問題は、私が構築してきたアプリのAndroidデプロイメントで私には明らかでした。確かに、これはまれなバグであり、確実に繰り返すことはできません。したがって、iOSデプロイメントにも存在する可能性があります。しかし、私はまだそれを他のプラットフォームで見てきました。私は、アプリを開発するためにCorona SDKを通してluaスクリプトを使用していることにも言及しています。
私はこの問題に多くの思考を与えている、といくつかの可能性に絞られている:私は
- インタラクションLUAでこのさえ可能ですか?)ヒープ破損のいくつかの並べ替えは、奇妙な副作用につながっている
- 私はめちゃめちゃてきたと私はデバッグの多くの時間全体で見逃している外部の状態にいくつか気明白な参照があります
この中で最も厄介な点は、バグの非再現性です。ほとんどの場合、コードブロックは繰り返しの種を与えられて完全に確定的に動作します。それで、非決定論のフェーズがあるかのようであり、それは次に何らかの未知の時間の後に再び散逸する。私はここで専門家の脳を選ぶのが大好きです。
ここで何が起こっている可能性がありますか?また、Androidのデプロイメントでしか見ていないので、この特定の問題に関してプラットフォーム固有のものがある可能性はありますか?
参考までに、完全なコードブロックを示します。実際には、2つのランダムなプロパティ(3つの色の1つと3つの図形の1つ)を持つトークンを生成していますが、それは問題の本質の点ではあまり意味がありません。
math.randomseed(currentRandomSeed)
math.random()
local tokenListPlan = {}
-- randomly assign weighting distribution
local thresh1, thresh2
while (true) do
local s0 = math.random(1, 99)
local s1 = math.random(1, 99)
local c0 = s0
local c1 = s1 - c0
local c2 = 100 - c1 - c0
if (c0 >= eng.DEVIATION_THRESHOLD and c1 >= eng.DEVIATION_THRESHOLD and c2 >= eng.DEVIATION_THRESHOLD) then
thresh1 = c0
thresh2 = c0 + c1
break
end
end
-- generate tokens (deterministic based on seed)
for i = 1, sortedCountTarget do
local token
local c = 1
local rnd = math.random(1, 100)
if (rnd < thresh1) then -- skewed dist
c = 1
elseif (rnd < thresh2) then
c = 2
else
c = 3
end
if (paramGameMode == eng.GAME_MODE_COLOR) then
local rnd46 = math.random(4, 6)
token = {color = c, shape = rnd46}
elseif (paramGameMode == eng.GAME_MODE_SHAPE) then
local rnd13 = math.random(1, 3)
token = {color = rnd13, shape = c + 3}
else
local rnd13 = math.random(1, 3)
local rnd46 = math.random(4, 6)
token = {color = rnd13, shape = rnd46}
end
tokenListPlan[#tokenListPlan + 1] = token
end
ここでは、正確にランダムシードを設定していますか?アンドロイドでは、何らかの理由でランダムセッティングラインが2回以上実行されることがあります。 – muratgu
コードのブロックの直前(その間に何もない)に、ここであまりあいまいでないように投稿を編集します。残念ながら、私はそれが何度も実行される可能性はありません。特に散発的ではありません。 –
math.randomは、このコードが実行されている間に予想される量以上のものを起動する場合がありますか?クロージャを使用して呼び出された量を数える関数にラップしてみてください。異なる結果が出たときに変更されているかどうかを確認してください。 – warspyking