ライフゲームの JavaScript 実装

ライフゲームの JavaScript 実装

コンセプト紹介

セルオートマトンとは、コンピュータの父であるジョン・フォン・ノイマンが、生体システムの自己複製機能をシミュレートするために 1950 年代初頭に提案した理論です。

ライフゲーム、または正式名称はジョン・コンウェイのライフゲームであり、1970 年代にイギリスの数学者ジョン・コンウェイによって発明されたセルオートマトンです。

論理的ルール

2 次元平面グリッドでは、各セルには「生きている」または「死んでいる」という 2 つの状態があり、次の瞬間の状態は周囲の 8 つのセルの状態によって完全に決定されます。

この世界には3つの進化のルールがあります。

  1. 周囲に生き残った細胞が 2 つある場合、細胞の生命状態は同じままです。
  2. 周囲に 3 つの生きている細胞がある場合、その細胞は生きている (死んだ細胞は復活します)。
  3. 周囲に生存しているセルが 2 個未満 (生命数が少ない) または 3 個を超える (生命数が多すぎる) 場合、セルは死んでいます。

完全なコード

バーニングフロスト/ライフゲーム

デモページ

基本構造

index.html // メインページ、システムの初期化、システム操作の制御など。 canvas.js // レンダリングレイヤー、キャンバスの作成、手動描画、キャンバス更新方法など。 LifeGame.js // ロジックレイヤー、システムの作成と実行、システム操作ロジック、データ更新など。

主な実装

システム構成: 2 次元平面グリッドのサイズを定義します。すべてのセルのライフ ステータスは、キーと値の形式でデータに保存されます。Execute は、canvas.js によって公開され、config オブジェクトにマウントされる内部メソッドです。

  定数設定 = {
    width: 100, // 水平セル番号 height: 100, // 垂直セル番号 size: 4 + 1, // セルサイズ、セル間隔 1px
    speed: 200, // セルの反復速度 alive: '#000000', // セルの生存色 dead: '#FFFFFF', // ワールドカラー (セルの死色)
    data: new Map(), // システム操作データ実行、// キャンバスメソッドの更新};

ルールの実装: 2 次元平面で各セルを走査し、現在のセルの状態を取得し、その周囲の生存セルの数を計算し、次の瞬間にセルが生きているか死んでいるかを判断し、この状態を保存し、レンダリング レイヤーの更新キャンバス メソッドの実行を呼び出してインターフェイスの表示を更新します。ここで、データを処理する際には、2 次元座標系を表すために 2 次元配列は使用されず、代わりに 1 次元の線形表現に変換され、データが Map に格納されます。

  // ライフゲーム.js

  // 2 次元座標系の 1 次元線形表現 const MakeKey = (x = 0, y = 0) => y * 10000 + x;

  関数refreshWorld() {
    const next = new Map(); // 更新されたシステム操作データ // 2次元座標系のすべての要素を反復処理する IterateCells(config, (x, y) => {
      const index = MakeKey(x, y); // 座標に対応するキーを計算する
      const current = config.data.get(index); // 現在のセルの状態 // 現在のセルの周囲の生き残ったセルの数を計算する switch (borderSum(x, y)) {
        ケース2:
          // 周囲に 2 つの生きているセルがある場合、セルはそのまま残ります。
          next.set(インデックス、現在値);
          壊す;
        ケース3:
          // 周囲に 3 つの生き残ったセルがある場合、そのセルは生きています。
          next.set(インデックス、true);
          !current && config.execute(x, y, true); // ステータスが変更され、キャンバスが更新されます break;
        デフォルト:
          // 周囲の生きている細胞の数が 2 未満の場合、その細胞は死んでいます。 (命は少ない)
          // 周囲に 3 つ以上の生きている細胞がある場合、その細胞は死んでいます。 (命が多すぎる)
          次はインデックスを false に設定します。
          current && config.execute(x, y, false); // ステータスが変更され、キャンバスが更新されます break;
      }
      true を返します。
    });
    次へ戻る;
  }

システムの起動と停止

  // ライフゲーム.js
  
  // システム関数を開始する startWorld() {
    stopWorld(); // 以前に開始したループを停止します // 反復速度に応じてシステムを開始し、ループ内でシステムを更新します interval = setInterval(() => (config.data = refreshWorld()), config.speed || 500);
    startup = true; // 起動フラグをオンにします return true;
  }

  // システムをシャットダウンし、現在のシステムを実行したままにします data function stopWorld() {
    clearInterval(interval); // ループを停止します。starting = false; // 開始フラグをオフにします。return true;
  }

生細胞を数える方法

  // ライフゲーム.js
  
  関数 borderSum(x = 0, y = 0) {
    const { 幅、高さ、データ } = config;
    合計を 0 とします。
    (j = y - 1; j <= y + 1; j++) の場合 {
      (i = x - 1; i <= x + 1; i++) の場合 {
        // 境界判定 if (i < 0 || j < 0 || i >= 幅 || j >= 高さ || (i === x && j === y)) {
          続く;
        }
        if (data.get(MakeKey(i, j))) {
          sum++; // 生き残ったセルの数を累積する}
      }
    }
    合計を返します。
  }

反復2D座標法

/**
 * 2D 座標系のすべての要素を反復処理し、コールバック関数を実行します * @param config: { width: number, height: number }
 * @param コールバック: (x: 数値、y: 数値) => ブール値
 */
const IterateCells = ({ 幅, 高さ }, コールバック) => {
  (y = 0; y < 高さ; y++) の場合 {
    (x = 0; x < 幅; x++) の場合 {
      if (コールバック && !コールバック(x, y)) {
        false を返します。
      }
    }
  }
  true を返します。
};

キャンバスメソッドの更新

  // キャンバス.js
  
  関数実行(x, y, life) {
    const { size, alive, dead } = config;
    // セルの色を設定します context.fillStyle = life ? alive : dead;
    // セル間の間隔を 1px にしてセルを描画します
    context.fillRect(x * サイズ + 1、y * サイズ + 1、サイズ - 1、サイズ - 1);

    true を返します。
  }

以上がJavaScriptによるライフゲームの実装の詳細です。JavaScriptによるライフゲームの詳細については、123WORDPRESS.COMの関連記事もご覧ください。

以下もご興味があるかもしれません:
  • クリックナンバーゲームを実装するネイティブJS
  • js でパズルゲームを実装する
  • コメント付きのスネークゲームを実装する js
  • 2048 ゲームを実装するためのネイティブ js
  • JavaScript タイピングゲーム
  • JavaScript ジグソーパズルゲーム
  • ネイティブ js でカスタム難易度のマインスイーパ ゲームを実装する
  • Gobangゲームを実現するためのjsキャンバス
  • JavaScript を使って格闘ゲームを書く方法
  • JavaScript ベースのシンプルなマインスイーパ ゲームの実装

<<:  MySQLデータベース設計:Pythonを使ったスキーマ操作方法の詳しい解説

>>:  SpringbootはDockerデプロイメントを統合し、Dockerイメージを構築する2つの方法を実装します。

推薦する

MySQL 8.0.15 のインストールと設定方法のグラフィックチュートリアル

この記事ではMySQL 8.0.15のインストールと設定方法を参考までに記録します。具体的な内容は以...

Mysql マスタースレーブ同期構成の実践の詳細な説明

1. はじめに以前、「MySQL マスター スレーブ同期の原理」という記事を書きました。この記事を読...

MySQL の分離レベル、ロック、MVCC の紹介

この記事の目的は、これらの概念とその機能の関係を明らかにすることです。 Mysql がトランザクショ...

Linux mpstat コマンドの使用方法の詳細な説明

1. mpstatコマンド1.1 コマンド形式 mpstat [ -A ] [ -u ] [ -V ...

VMware 12 での Ubuntu 16.04 インストール チュートリアル

この記事では、VMware 12でのUbuntu 16.04のインストールチュートリアルを参考までに...

Vueフォームで画像を処理する方法

質問: Vue にブログ投稿をアップロードするためのフォームがあり、タイトル、本文、説明、スニペット...

nginx高可用性クラスタの実装プロセス

この記事は主に、nginx 高可用性クラスタの実装プロセスを紹介します。この記事のサンプルコードは非...

Linuxは、単一のIPをバインドするためにデュアルネットワークカードを実装するためにボンドを使用します。サンプルコード

ネットワークの高可用性を実現するには、複数のネットワーク カードを仮想ネットワーク カードにバインド...

Layuiテーブルは指定された行のラジオボタンを選択し、その行の実装コードまでスクロールします。

layui テーブルには複数行のデータがあります。外部入力コンテンツを通じて、指定された行を見つけ...

Vueカスタムカプセル化ボタンコンポーネント

Vueボタンコンポーネントのカスタムカプセル化コードは参考用です。具体的な内容は次のとおりです。ボタ...

Vue 組み込みコンポーネントのキープアライブでの LRU アルゴリズムの使用

目次Vue の keep-alive 組み込みコンポーネントの使用でもこのアルゴリズムが使用されます...

MySQL のデータベース パフォーマンスに影響を与える要因の説明

データベースのパフォーマンスに関する話面接では、「データベースにどのくらい精通していますか?」など、...

Vue における Vue.use() の原理と基本的な使用法

目次序文1. 例で理解する2. ソースコードを分析する3. まとめ要約する序文他の人のコンポーネント...

フォーム要素とプロンプトテキストが揃っていない問題

最近のプロジェクトでは、多くのフォーム、特にチェックボックスとラジオボタンの作成が含まれます。しかし...

JSはカリキュラムタイムテーブルアプレット(スーパーカリキュラムタイムテーブルを模倣)を実装し、カスタムバックグラウンド機能を追加します

概要:市販されているいくつかのタイムテーブルソフトウェアから教訓を得ました。機能が複雑すぎるため、タ...