2011-06-23 14 views
1

これはJavaScriptプロジェクトでクラスを使用する私の最初の試みです。私はHTML5 CanvasでConwayのGame of Lifeを実装しようとしています。 Here's the code.ご覧のとおり、第1世代は上手くレンダリングされますが、これ以上実行されないようにするにはnext()関数に問題があります。 (私はどちらかの機能ですべての問題を見つけることができません。問題のエラーは、実際にnext()によって呼び出されget()の最後の行、neighbors()によって呼び出された機能の一つ、でスローされていることの通知をしましたが、はっきり何かの間違った)未定義のプロパティ '-1'を読み取れません

答えて

3

問題が意図したとおりにget/set機能で警備員が動作しない[%についての仮定は、このように間違っているとこと]です!

コーディング
-1 % 42 // results in -1 

ハッピー。


私はget/set関数でガードを除去し(例えば、最初/最後の行と列が実際に画面に描画されることはありません)ボーダーためsentinel values(または他の隣接エッジケーシング)を用いて検討します。

これはを避けることができ、ガードをチェックし、かなりの数のからget/setは(私も機能として、それらを持っていないでしょう)回各イテレーションの全体の束と呼ばれます。私はget/setの削除を考慮しています。これらの操作はプロセスの内部でアルゴリズムに密接に関連しているため、「大丈夫」です。これらは直接公開されておらず、JavaScriptは非常に高速です。

"フルグリッド隣接チェック"を実行すると、1サイクルあたりC * O(h*w)になります。それは同じ複雑さを持っていますが、はるかに小さいCはプログラムをもっと速く動かすことができます。

+0

「%」は奇妙なものです。私はそれを追加する前に大文字小文字を区別しています(http://google.com/search?q=-1+%25+42)。説明をありがとう! – nkorth

+0

私は、地図を端にラップさせるというアイデアは気に入っていますが、私はスピードのために境界方法をとるかもしれません。 – nkorth

+0

@nkorthできるトリックがたくさんあります。複雑さは、 'y * w + x'インデックス付きの2次元配列をシミュレートし、次に配列のプロパティを反復するだけで(隣のチェック/更新演算も調整する必要があります)、' O(alive_cells) 'に移動できます。あるいは、生存細胞のための '[x、y]'(または平坦化されたインデックス)のリストを格納することができます。しかし、私は複雑さ/パフォーマンスをそれよりもはるかに上げる方法はわかりません。 –

1

あなたはnextで、このループを持っている:

for(var y = 0; y < this.height; y++){ 
    for(var x = 0; x < this.width; x++){ 
     newMap[x][y] = this.get(x, y); 

     //Rule 1: any live cell with fewer than two live neighbors dies 
     if(this.get(x, y) == true && this.neighbors(x, y) < 2){ 
      newMap[x][y] = false; 
     } 

     //... 

ので、あなたの最初の反復で、xyがゼロです。 0をしている

this.neighbors = function(x, y){ 
    n = 0; 
    //... 
    if(this.get(x-1, y-1)){n++;} 
    //... 
    return n; 
} 

x場合とy、それはセル(-1,-1)検査しようとします:

this.map[x][y] = val; 

をしかし、あなたのmapが唯一の正の整数キーを持っている今neighborsが何をしているのか見てみましょう。

あなたは "ラップアラウンド" したい場合は、負の値を避けるためにgetの値インクリメント:予想通り

x = (x + this.width) % this.width; 
y = (y + this.height) % this.height; 
+0

私は実際にそれが負になることを意図していたので、 'get()'と 'set()'関数でコードの端にマップループを作ることができました。しかし、これは問題に関連していました(pstの回答を参照) – nkorth

1

ライン

x = x % this.width; 

は動作しません:

-1 % 640 

は、

-1 

簡単修正:

x = (x + this.width) % this.width; 
1

のは、最初のセルを調べてみましょう。 xが0で、yが0であるとします。そのセルの処理中に、this.map[-1][-1]をチェックすることになります。 this.map[-1]は定義されていないので、存在していても要素-1を見つけることはできません。

  • チェックx > 0そのそれの右に何かをつかむ前に、そのセルの左側、およびx < this.width - 1に何かをつかむ前に:

    あなたはいくつかのオプションがあります。 ythis.heightについても同様です。
  • this.map[x - 1]またはthis.map[x + 1]が何かにアクセスする前に定義されていることを確認してください。 y +/- 1と同じです。未定義の場合はfalseとみなしてください。
  • this.map[-1]およびthis.map[whatever][-1]を偽と定義し、またthis.map[this.width]およびthis.map[whatever][this.height]と定義します。
  • x - 1(x + width - 1) % widthになるように数学をやり直してください。 y - 1と同じです。それは地図をラップアラウンドさせるべきです。
関連する問題