0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ライフゲーム作ってみた!

Last updated at Posted at 2025-10-30

1.作ろうと思ったきっかけ

自分は最近AtCoderをやりすぎてjavascriptを全然やっていなくてjavascriptが読めなくなるかもしれなかったためjavascriptでなにか作ってみようと思いました。その時、youtubeを見ていたらライフゲームの動画が出てきたためライフゲームを作って見ようと思いました。

2.作り方

今回はCSSは全然書かないだろと思ってHTMLファイルにまとめました。javascriptは長くなりそうだったので別ファイルにしました。その結果HTMLとCSSは30行くらいで書けました。

2-1. HTML+CSSコードの解説

<!doctype html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
        <title>ライフゲーム</title>
        <style>
            body{
                background-color: black;
                color: white;
            }

            .title{
                color: green;
                font-size: 60px;
                line-height: 0;
                text-align: center;
			}

			#canvas{
				border: 5px solid white;
				display: block;
				margin: 0 auto;
			}
        </style>
    </head>
	<body>
		<h1 class="title">ライフゲーム</h1>
        <p id="count_frame" style="text-align: center;"></p>
		<canvas id="canvas" width="800" height="800"></canvas>
        <script src="lifegame.js"></script>
	</body>
</html>

だいたい自分の場合は背景色は黒で見出しは緑で書く傾向があります。

  1. count_frame
    フレーム数を表示します
    中の構造はjavascriptの解説で書きます
  2. canvas
    ライフゲームの盤面となります

2-2.javascriptコードの解説

// 定数定義層
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const dx = [1, 1, 0, -1, -1, -1, 0, 1];
const dy = [0, -1, -1, -1, 0, 1, 1, 1];
const cell_size = 40;
const canvas_size = canvas.width;

// クラス定義層
class Grid {
    constructor(type = "random") {
        this.cells = [];
        const rows = canvas_size / cell_size;
        const cols = canvas_size / cell_size;

        for (let i = 0; i < rows; i++) {
            this.cells[i] = [];
            for (let j = 0; j < cols; j++) {
                if (type === "random") {
                    this.cells[i][j] = Math.random() < 0.5;
                } else {
                    this.cells[i][j] = false;
                }
            }
        }
    }

    draw() {
        ctx.clearRect(0, 0, canvas_size, canvas_size);
        const rows = canvas_size / cell_size;
        const cols = canvas_size / cell_size;

        for (let i = 0; i < rows; i++) {
            for (let j = 0; j < cols; j++) {
                ctx.fillStyle = this.cells[i][j] ? "green" : "black";
                ctx.fillRect(j * cell_size, i * cell_size, cell_size, cell_size);
            }
        }
    }

	next() {
		const rows = canvas_size / cell_size;
		const cols = canvas_size / cell_size;
		const newGrid = new Grid("empty");

		for (let i = 0; i < rows; i++) {
			for (let j = 0; j < cols; j++) {
				let count = 0;
				for (let k = 0; k < 8; k++) {
					const ni = (i + dy[k] + rows) % rows;
					const nj = (j + dx[k] + cols) % cols;
					if (this.cells[ni][nj]) {
						count++;
					}
				}

				if (this.cells[i][j]) {
					newGrid.cells[i][j] = (count === 2 || count === 3);
				} else {
					newGrid.cells[i][j] = (count === 3);
				}
			}
		}

		this.cells = newGrid.cells;
	}
}

// 表示層
let frame = 0;
const grid = new Grid("random");
setInterval(() => {
    grid.next();
    grid.draw();
	document.getElementById("count_frame").innerHTML = `フレーム数:${frame++}`;
}, 100);
  1. 定数定義層
    定数を定義しています
    dxやdyなど競技プログラミングのような表記が少しあります
  2. Gridクラス
    コンストラクタ: ランダムに初期状態を作ります
    draw関数: canvasに表示します
    next関数: つぎの盤面を作ります
  3. 表示層
    frame: count_frameにフレーム数を表示させるための変数です
    grid: グリッドを作ります
    setIntervalの中: 100ms毎に
  • 次の盤面を作る
  • 盤面を表示する
  • count_frameのIDを取ってフレーム数を表示する
    といった流れです

普通に見てて気持ちいいです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?