Skip to content

Instantly share code, notes, and snippets.

@GlitchedCode
Last active April 10, 2023 00:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GlitchedCode/a64b57b74843cff0f8082fa6035e90ef to your computer and use it in GitHub Desktop.
Save GlitchedCode/a64b57b74843cff0f8082fa6035e90ef to your computer and use it in GitHub Desktop.
"Continuous" Life-Like CA simulation using tf.nn.conv2d
# implements simulation of a set of CA rules containing life-like cellular automata
# by allowing for real-valued states from 0 to 1, and by "filling the gaps" using
# linear interpolation
# inspired by https://github.com/conceptacid/conv2d_life/blob/master/life.py
import tensorflow as tf
import numpy as np
from matplotlib.animation import FFMpegWriter
from matplotlib import pyplot as plt
sim_shape = (1, 100, 100, 1)
ca_kernel = tf.reshape(tf.ones([3, 3]), [3, 3, 1, 1])
@tf.function
def computeCA(rule, state):
# concentration sum of neighboring cells
neighbors = tf.nn.conv2d(state, ca_kernel, [1, 1, 1, 1], 'SAME') - state
one = tf.constant(1, tf.float32)
nine = tf.constant(9, tf.int32)
@tf.function
def compute(state):
s = state[0]
n = state[1]
t = tf.math.floormod(n, 1.0)
lb = tf.cast(tf.floor(n), tf.int32)
ub = tf.cast(tf.floor(n), tf.int32)
born = ((one - t) * rule[lb]) + (t * rule[ub])
survive = ((one - t) * rule[lb+nine]) + (t * rule[ub+nine])
return tf.clip_by_value(((one - s) * born) + (s * survive), 0.0, 1.0)
shape = tf.shape(state)
state = tf.reshape(state, [-1])
neighbors = tf.reshape(neighbors, [-1])
newState = tf.vectorized_map(compute, [state, neighbors])
state = tf.reshape(state,shape)
newState = tf.reshape(newState,shape)
return [state, newState]
if __name__ == '__main__':
state = tf.cast((tf.random.uniform(sim_shape) > 0.5), tf.float32)
# this encodes game of life's rule. edit this and see what happens!
rule = np.array([0,0,0,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0], np.float32)
writer = FFMpegWriter(10)
fig = plt.figure()
img = plt.imshow(state[0])
with writer.saving(fig, 'result.mp4', 100):
writer.grab_frame()
for _ in range(600):
state = computeCA(rule, state)[1]
img.set_data(state[0])
writer.grab_frame()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment