Java | 三次元版ライフゲーム(セルオートマトン)

APP Java
スポンサーリンク

では「三次元ライフゲームで安定構造や振動構造を探す」例題を作ってみましょう。
ライフゲームの面白さは「進化の結果、安定した形や周期的に繰り返す形が現れる」ことです。三次元版でも同じように、セルの配置によって 安定構造(ずっと変わらない)振動構造(一定周期で繰り返す) が生まれます。


ポイント

  • 安定構造: 次世代に移っても形が変わらない。
  • 振動構造: 2ステップや3ステップごとに元の形に戻る。
  • 探索方法: 初期配置を決めてシミュレーションを回し、同じ状態が再出現するかチェックする。

コード例(Java)

import java.util.*;

public class LifeGame3DStable {
    static final int SIZE = 3; // 3x3x3の立方体
    static final int STEPS = 10;

    public static void main(String[] args) {
        // 初期配置(例:中央に小さなブロック)
        int[][][] grid = new int[SIZE][SIZE][SIZE];
        grid[1][1][1] = 1;
        grid[1][1][2] = 1;
        grid[1][2][1] = 1;
        grid[1][2][2] = 1;

        // 過去の状態を記録して安定/振動を検出
        Set<String> seen = new HashSet<>();

        for (int step = 0; step < STEPS; step++) {
            System.out.println("Step " + step);
            printGrid(grid);

            String state = encode(grid);
            if (seen.contains(state)) {
                System.out.println("→ この形は過去に出現しました!(安定または振動構造)");
                break;
            }
            seen.add(state);

            grid = nextGeneration(grid);
        }
    }

    static int[][][] nextGeneration(int[][][] grid) {
        int[][][] newGrid = new int[SIZE][SIZE][SIZE];
        for (int z = 0; z < SIZE; z++) {
            for (int x = 0; x < SIZE; x++) {
                for (int y = 0; y < SIZE; y++) {
                    int neighbors = countNeighbors(grid, z, x, y);
                    if (grid[z][x][y] == 1) {
                        newGrid[z][x][y] = (neighbors == 2 || neighbors == 3) ? 1 : 0;
                    } else {
                        newGrid[z][x][y] = (neighbors == 3) ? 1 : 0;
                    }
                }
            }
        }
        return newGrid;
    }

    static int countNeighbors(int[][][] grid, int z, int x, int y) {
        int count = 0;
        for (int dz = -1; dz <= 1; dz++) {
            for (int dx = -1; dx <= 1; dx++) {
                for (int dy = -1; dy <= 1; dy++) {
                    if (dz == 0 && dx == 0 && dy == 0) continue;
                    int nz = z + dz, nx = x + dx, ny = y + dy;
                    if (nz >= 0 && nz < SIZE && nx >= 0 && nx < SIZE && ny >= 0 && ny < SIZE) {
                        count += grid[nz][nx][ny];
                    }
                }
            }
        }
        return count;
    }

    static void printGrid(int[][][] grid) {
        for (int z = 0; z < SIZE; z++) {
            System.out.println("Layer " + z + ":");
            for (int x = 0; x < SIZE; x++) {
                for (int y = 0; y < SIZE; y++) {
                    System.out.print(grid[z][x][y] == 1 ? "■ " : "□ ");
                }
                System.out.println();
            }
            System.out.println("---");
        }
    }

    static String encode(int[][][] grid) {
        StringBuilder sb = new StringBuilder();
        for (int z = 0; z < SIZE; z++) {
            for (int x = 0; x < SIZE; x++) {
                for (int y = 0; y < SIZE; y++) {
                    sb.append(grid[z][x][y]);
                }
            }
        }
        return sb.toString();
    }
}
Java

実行イメージ

  • 初期配置が「小さな立方体ブロック」の場合 → 安定構造としてずっと変わらない。
  • 他の配置(例えば直線状に3セル並べる) → 振動構造になり、2ステップごとに形が変わって戻る。

✅ まとめ

  • 三次元ライフゲームでも「安定構造」「振動構造」が存在する。
  • 過去の状態を記録して再出現を検出することで判定できる。
  • 小さな立方体ブロックは安定構造、直線は振動構造の典型例。
タイトルとURLをコピーしました