CodepenでJavaScriptプログラミング：環境構築不要でライフゲームを作る

## はじめに

JavaScriptでプログラミングを始めようと思ったとき、環境構築の壁に直面することがあります。
しかし、**Codepen**を使えば、そんな悩みとはおさらばです！
今回は、Codepenの魅力と、その活用例としてライフゲームの実装を紹介します。

## Codepenとは？

[Codepen](https://codepen.io/)は、ウェブ開発者のための強力なオンラインツールです。HTML、CSS、JavaScriptのコードをブラウザ上で書いて、即座に結果を確認できます。

### Codepenの主な特徴

1. **環境構築不要**: ブラウザさえあれば、すぐにコーディングを始められます。
2. **リアルタイムプレビュー**: コードを書きながら、即座に結果を確認できます。
3. **簡単な共有**: URLを共有するだけで、他の人とコードを共有できます。
4. **豊富なライブラリ**: 多数のJavaScriptライブラリやCSSフレームワークが利用可能です。

## ライフゲームとは？

ライフゲームは、1970年にジョン・ホートン・コンウェイによって考案された「セル・オートマトン」の一種です。

### ライフゲームの基本ルール

1. 生きているセルに隣接する生きたセルが2つか3つならば、次の世代でも生存する。
2. 死んでいるセルに隣接する生きたセルがちょうど3つあれば、次の世代で誕生する。
3. 上記以外の場合、セルは死滅する（過疎または過密により）。

これらのシンプルなルールから、複雑で興味深いパターンが生まれます。

## CodepenでライフゲームをCreatePlaces作る

では、実際にCodepenを使ってライフゲームを実装してみましょう。

```javascript
const GRID_SIZE = 50;
const CELL_SIZE = 10;
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');

canvas.width = GRID_SIZE * CELL_SIZE;
canvas.height = GRID_SIZE * CELL_SIZE;

let grid = createGrid();

function createGrid() {
    return new Array(GRID_SIZE).fill(null)
        .map(() => new Array(GRID_SIZE).fill(false));
}

function drawGrid() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.fillStyle = 'black';
    for (let x = 0; x < GRID_SIZE; x++) {
        for (let y = 0; y < GRID_SIZE; y++) {
            if (grid[x][y]) {
                ctx.fillRect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE);
            }
        }
    }
}

function countNeighbors(x, y) {
    let count = 0;
    for (let i = -1; i <= 1; i++) {
        for (let j = -1; j <= 1; j++) {
            if (i === 0 && j === 0) continue;
            const newX = (x + i + GRID_SIZE) % GRID_SIZE;
            const newY = (y + j + GRID_SIZE) % GRID_SIZE;
            if (grid[newX][newY]) count++;
        }
    }
    return count;
}

function updateGrid() {
    const newGrid = createGrid();
    for (let x = 0; x < GRID_SIZE; x++) {
        for (let y = 0; y < GRID_SIZE; y++) {
            const neighbors = countNeighbors(x, y);
            if (grid[x][y]) {
                newGrid[x][y] = neighbors === 2 || neighbors === 3;
            } else {
                newGrid[x][y] = neighbors === 3;
            }
        }
    }
    grid = newGrid;
}

function gameLoop() {
    updateGrid();
    drawGrid();
    requestAnimationFrame(gameLoop);
}

canvas.addEventListener('click', (event) => {
    const rect = canvas.getBoundingClientRect();
    const x = Math.floor((event.clientX - rect.left) / CELL_SIZE);
    const y = Math.floor((event.clientY - rect.top) / CELL_SIZE);
    grid[x][y] = !grid[x][y];
    drawGrid();
});

// ランダムな初期状態を設定
for (let x = 0; x < GRID_SIZE; x++) {
    for (let y = 0; y < GRID_SIZE; y++) {
        grid[x][y] = Math.random() > 0.7;
    }
}

gameLoop();
```

このコードをCodepenのJavaScriptパネルに貼り付け、HTMLパネルに以下を追加します：

```html
<canvas id="gameCanvas"></canvas>
```

そして、CSSパネルに以下を追加します：

```css
body {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
    background-color: #f0f0f0;
}

canvas {
    border: 1px solid #000;
}
```

## コードの解説

1. **キャンバスの設定**: HTMLのcanvas要素を使用して、ゲームの描画領域を作成します。

2. **グリッドの生成**: `createGrid()`関数で、セルの状態を保持する2次元配列を作成します。

3. **描画**: `drawGrid()`関数で、現在のグリッドの状態をキャンバスに描画します。

4. **近隣セルのカウント**: `countNeighbors()`関数で、各セルの周囲8マスの生きたセルをカウントします。

5. **グリッドの更新**: `updateGrid()`関数で、ライフゲームのルールに基づいて次の世代のグリッドを計算します。

6. **ゲームループ**: `gameLoop()`関数で、グリッドの更新と描画を繰り返します。

7. **クリックイベント**: キャンバス上のクリックで、セルの状態を切り替えられるようにしています。

## Codepenの利点

1. **即時フィードバック**: コードを書くと同時に結果が見られるため、デバッグが容易です。

2. **共有の簡単さ**: URLを共有するだけで、他の人と作品を共有できます。

3. **バージョン管理**: 作品の変更履歴を保存できるため、実験的な変更も安心して行えます。

4. **コミュニティ**: 他の開発者の作品を参考にしたり、フィードバックをもらえたりします。

## まとめ

Codepenを使用することで、JavaScriptプログラミングの環境構築の手間を省き、すぐにコーディングを始められます。ライフゲームのような複雑なアルゴリズムも、ブラウザ上で簡単に実装・共有できるのです。

プログラミング学習やプロトタイピングに、ぜひCodepenを活用してみてください。環境構築の壁を越え、アイデアを素早く形にする楽しさを体験できるはずです！

## 参考リンク

- [Codepen公式サイト](https://codepen.io/)
- [ライフゲーム - Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%A9%E3%82%A4%E3%83%95%E3%82%B2%E3%83%BC%E3%83%A0)


## デモ

以下の埋め込みデモを確認できます：

<p class="codepen" data-height="500" data-theme-id="light" data-default-tab="js,result" data-user="vehtzcsf-the-encoder" data-slug-hash="bGPdyMp" style="height: 500px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Conway's Game of Life">
  <span>See the Pen <a href="https://codepen.io/vehtzcsf-the-encoder/pen/bGPdyMp">
  Conway's Game of Life</a> by vehtzcsf-the-encoder (<a href="https://codepen.io/vehtzcsf-the-encoder">@vehtzcsf-the-encoder</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>