2016-10-10 3 views
2

私はuminokirin.comで実行中のelmで書かれたConwayの生活ゲームの基本的な実装を持っています。エルムライフプログラムのゲームが応答しなくなる - 正常に失敗する方法はありますか?

ソースは表示されますhereです。

このプログラムでは、トロイダルグリッドのサイズを調整し、セルをクリックしてステータスを変更し、世界をランダム化します。それは私のコンピュータ上の小さな値(50未満)に対してうまく機能します。

しかし、大きなグリッドでグリッドをランダムに使用しようとすると(しきい値が常に同じではないように見える)、プログラムは何の警告もなく応答しなくなり、回復する唯一の方法はアプリをリロードすることです。

GOLアルゴリズムでは最適化が行われず、すべてのセルに1つのsvgの矩形を使用すると非常に効率的ではありませんが、プログラムがなぜこのように動作するのか説明しません。

これはelmの実行時間をあきらめていますか?あるいは何らかのブラウザセーフガード?

さらに重要なのは、グリッドの最大サイズを任意にキャッピングする以外に、この動作を防ぐ方法があるかどうかです。

答えて

6

あなたが観察している動作は、Javascriptのスタックオーバーフローによるものです。 「ランダム化」ボタンを押すと、ブラウザコンソールに「Uncaught RangeError:最大呼び出しスタックサイズを超過しました」というメッセージが表示されます。

これは、randomize関数が複数の大きな一時変数を割り当てるためです。特に、シャッフル関数(ランダム化関数から呼び出される)は、ライフグリッド内のすべてのセルに対してそれぞれ1つの要素を持つ2つの一時的なリストを割り当てるように見えます。 Elmはこれらをタイムリーにリリースすることに賢明かもしれませんが、これはあまりにも遠すぎます。

これを修正するには、より簡単なランダム化機能を使用できます。以下に示すバージョンでは、Elm Generatorsを使用してDead/Alive値の単一のリストを生成し、そのリストからランダム化された配列を初期化します。

randomize2 : Array Cell -> Int -> Int -> Int -> Array Cell 
randomize2 grid gs sd n = 
    let floatGen = Random.float 0.0 1.0 
     lifeGen = Random.map (\b -> if (b < toFloat n/100) then Alive else Dead) floatGen 
     listGen = Random.list (gs*gs) lifeGen 
    in fst (Random.step listGen (initialSeed sd)) |> fromList 

このランダム化機能を使用すると、600x600までのグリッドのサイズを変更して正常にランダム化することができました。その時点で私はテストを中止しました。

関連する問題