この記事について
この記事は、生成AIを活用した自動生成フローで作成しています。
Canvas 2Dの公式APIとライフゲームのB3/S23ルールを参照し、架空の16×16盤を1世代ずつ動かす教材を制作しました。P1〜P5は同じChatGPT内の自己審査で、別AIによる独立審査ではありません。検証ステータス:🧪 Canvas公式資料確認済み/V8ロジック8条件・JS構文PASS/実ブラウザ・公開Pages・WordPress表示未確認
2026年11月1日、固定コミットの世代計算と構文を再検査。実ブラウザ、青い囲み、モバイル・印刷/PDFは未確認です。
横に並んだ3つのマスは、1回進めると縦に並び、もう1回で横に戻ります。 この小さな動きから、「単純なルールだけで複雑な変化が生まれる」仕組みを体験します。数学のライフゲームをブラウザのCanvasに描く教材です。
| 項目 | 今回の条件 |
|---|---|
| 対象 | Canvas 2D対応ブラウザ(実機未確認) |
| 技術 | HTML・JavaScript・Canvas 2D |
| 費用 | 無料・APIキー/外部ライブラリ不要 |
| データ | 16×16の架空マス、通信不要 |
| 制限 | 端は折り返さない有限盤 |
| 初期状態 | 停止中。操作で1世代ずつ進む |
まず試す:3マスを縦横に動かす
🔷 動く教材
Canvasライフゲームのライブデモを開く(公開到達・ブラウザ動作未確認)
Daily Codeの完成版とREADME(GitHub保存済み)
初期パターン「点滅(3マス)」のまま、「1世代進める」を押します。
青いマスが横3つから縦3つに変わり、表示が「第1世代」になるか見ます。
もう一度押し、横3つに戻るかを比べます。
これはGitHub保存コードのロジックから導いた期待結果で、公開デモの実測ではありません。画面下には「第N世代/生きたマス:N個」と文字でも表示する設計なので、色だけに頼らず状態を確認できます。
操作後はここを見る
| 操作 | 期待する結果 |
|---|---|
| 開いた直後 | 横3マス・第0世代 |
| 1回進める | 縦3マス・第1世代 |
| もう1回 | 横3マス・第2世代 |
| 「最初から」 | 横3マス・第0世代 |
形だけでなく「生きたマス:3個」が変わらない点にも注目してください。マスが移動したように見えても、実際には各マスの状態を世代ごとに再計算しています。点滅パターンでは生存数は3のままです。
なぜ3マスだけで形が変わるのか
ライフゲームは、上下左右と斜めを合わせた周囲8マスの生存数で、次世代の状態を決めます。規則は「B3/S23」と表記されます。B3は空白マスの周囲に生きたマスがちょうど3つなら誕生、S23は生存マスの周囲が2つまたは3つなら生き残る、という意味です。
| 今の状態 | 周囲の生存数 | 次の世代 |
|---|---|---|
| 空白 | 3 | 誕生する |
| 生存 | 2または3 | 生き残る |
| 生存 | 0・1・4以上 | 消える |
| 空白 | 3以外 | 空白のまま |
横3マスの両端は、生きた隣が1つしかないため次に消えます。中央の上下の空白マスは、周囲に生きたマスが3つあるため新たに生まれます。中央は隣が2つなので残ります。こうして縦3マスになるわけです。
重要なのは全マスを同時に更新すること。 左から順に盤を直接書き換えると、後続のマスが「すでに次世代へ変わった隣」を読んでしまいます。サンプルは古い盤を読み、新しい盤へ結果を書き込んでから一度に置き換えます。
flowchart LR
A["今の盤"] --> B["周囲8マスを数える"]
B --> C["B3/S23を判定"]
C --> D["新しい盤へ一括反映"]
D --> E["Canvasと世代数を更新"]
この図は教材の計算順を表すもので、ブラウザの内部描画処理すべてを示すものではありません。
コードの核心:今の盤と次の盤を分ける
完成版のlogic.jsでは、各マスの周囲を数えてから次のように判定します。
const n = neighbours(board, r, c); out[r][c] = board[r][c] ? (n === 2 || n === 3) : n === 3;
boardは今の盤、outは次の盤です。trueは生存、falseは空白です。三項演算子の左側は「今生きている場合」、右側は「今は空白の場合」の判定です。完全な処理には境界チェック、Canvas描画、ボタン操作も必要なので、記事に長いコードを貼らずDaily Codeへ分離しました。
Canvas自体がマスの状態を計算するわけではありません。計算済みの生存・空白をfillRect()で青と淡色の四角形に描き分けます。計算と表示を分離すると、色やマスの大きさを変更してもB3/S23の規則は変わりません。
1か所変えてみる:点滅から四角へ
「初期パターン」を「四角(4マス)」へ変更して、同じ「1世代進める」を押してみてください。2×2の四角は各マスの生存隣が3つなので、形が変わらない設計です。点滅の周期変化と四角の安定状態を比べると、同じ規則でも初期配置によって結果が違うことが分かります。
| 初期パターン | 期待する変化 |
|---|---|
| 点滅 | 2世代で元に戻る |
| 四角 | 何世代でも同じ |
| グライダー | 4世代で右下へ1マス |
| 空白 | ずっと空白 |
「グライダー」は小さな形が移動して見える例です。ただし本教材は16×16の有限盤で、端の外側は空白として計算します。無限平面とは異なり、グライダーが端へ近づくと欠けたり消えたりします。周期や移動を無条件に永久保証するものではありません。
マスを自分で変えてみる
盤をクリックすると、そのマスの生存・空白が反転します。キーボードで操作する場合は「行」「列」に1〜16の数字を入力し、「指定マスを切り替える」を押します。変更すると再生は停止し、世代数は0へ戻ります。自分の配置から次の1手を予想できるようにするためです。
「再生」は700ミリ秒ごとに1世代進める補助機能です。初期状態では動きません。タブを非表示にすると停止し、OSで「動きを減らす」を設定している場合は自動再生を使わず、手動ステップで観察する設計です。長時間の自動再生より、数回の手動操作で規則を確かめる方が学習には向いています。
うまく動かないとき
| 症状 | 確認すること |
|---|---|
| 「準備中」のまま | logic.jsとapp.js、Console |
| マスが表示されない | Canvas 2D対応、スクリプトエラー |
| 再生できない | 「動きを減らす」設定、タブの表示 |
| 端で形が崩れる | 有限盤の境界。バグとは限らない |
| 変化しない | 「四角」「空白」など安定パターンか |
自分のPCで動かす
Daily Codeの
docs/demos/canvas-life-lab/からindex.html、logic.js、app.jsを同じフォルダへ保存します。index.htmlをブラウザで開き、画面下の世代数が表示されるか確認します。表示されない場合はConsoleで読み込みエラーを確認します。
file://が制限される環境では、外部公開せずローカルHTTPサーバーで試してください。
これは手順の案内であり、今回ローカルブラウザで起動に成功したという報告ではありません。
仕事・学習で使うなら
この教材は、状態遷移、同時更新、境界条件、テストの考え方を小さな例で学ぶのに向いています。たとえば「現在の状態から次の状態を一括計算する」業務処理では、途中の更新結果を次の判定へ混ぜない設計が重要です。ライフゲーム自体が顧客の業務判断や現実の動きを予測できるという意味ではありません。
テストは「見た目がきれい」だけでは足りません。点滅が2世代で元に戻る、四角が安定する、空白が空白のまま、端で反対側へ折り返さない、といった入力と期待値を先に決めます。今回の5条件はV8でロジックを検査しました。一方、実際のクリック座標、スマートフォンのタッチ、印刷時の配置は未検証です。
追加実験:世代の更新順を確かめる
ライフゲームでは次の状態を決めるとき、全マスが同じ「現在の世代」を見て判断することが重要です。一つのマスを計算した直後に盤面を書き換えると、後から処理する隣のマスだけ新しい状態を見ることになり、期待するルールと異なる結果になる可能性があります。現在の盤と次の盤を分けて計算し、全マスを調べてから世代を切り替える設計なのかを確認してください。
横に3個並んだ点滅パターンはルールを追いやすい小さな教材です。しかし盤の端に置くと、外側をどう扱うかによって結果が変わる場合があります。画面外を死んだマスとみなすのか、反対側につながる盤とみなすのかは別の設計です。このサンプルの端の扱いを読み、中央に置いた例と端に置いた例を混同しないようにします。
初期状態の点滅パターンは、次の一世代で縦と横が入れ替わることを観察するためのものです。数式を暗記するより、中央のマスとその両隣の生存数を一つずつ数える方が理解しやすいでしょう。今の盤に生きているマスと次の盤に生きるマスを色や表示で区別できれば、計算の順序を読み違えにくくなります。周囲のマスが3個のときに誕生し、2個または3個のときに生存するという条件を具体的な場所に当てはめてみてください。
手でマスを変更したとき、変更直後に一世代が進むのか、次へ進むボタンを押すまで盤が変わらないのかを区別してください。ボタン一回の結果だけで正しいと判断せず、二回進めたとき元の形へ戻るか、初期化で最初の盤へ戻るかを比べると、計算と画面更新の両方を検査できます。実際の管理業務に応用するときは、更新前と更新後の状態を別に保持する考え方が役立ちます。
公式資料・専門資料
MDN:CanvasRenderingContext2D — Canvas 2Dの描画API。
MDN:fillRect() — 四角形を塗りつぶす方法。
LifeWiki:Conway’s Game of Life — B3/S23の規則と代表パターン。
LifeWiki:Rulestring — B3/S23という表記の意味。
GitHubサンプル
検証範囲と注意
今回確認: GitHub固定コミットのlogic.jsでV8ロジック8条件PASS(点滅、四角、空白、グライダー移動、境界、異常サイズ等)。logic.jsとapp.jsは構文PASS。MDNのfillRect()公式仕様を確認しました。LifeWikiの規則説明は以前の照合結果を維持し、今回の再取得は403で未完了です。
未確認: Node標準テスト、実ブラウザ操作、GitHub Pages到達、WordPress実表示(青い引用枠を含む)、実機モバイル、印刷/PDF。アイキャッチは登録画像を確認できないため未設定です。
