import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation
from mpl_toolkits.mplot3d import Axes3D # needed for 3D projection
mpl.rcParams["animation.ffmpeg_path"] = "/usr/bin/ffmpeg" # adjust path
def count_neighbors(g):
"""
Count alive neighbors for each cell in a 3D grid with periodic boundaries.
g has shape (Z, Y, X).
"""
nz, ny, nx = g.shape
neighbors = np.zeros_like(g, dtype=np.uint8)
# iterate over shifts in {-1, 0, 1} for each axis, skip (0,0,0)
for dz in (-1, 0, 1):
for dy in (-1, 0, 1):
for dx in (-1, 0, 1):
if dz == 0 and dy == 0 and dx == 0:
continue # skip the cell itself
neighbors += np.roll(
np.roll(
np.roll(g, dz, axis=0),
dy, axis=1
),
dx, axis=2
)
return neighbors