patterns — colony

generator verdict no votes yet
source — color/auto/e003_colony.g53_colony
def g53_colony(rng):
    """Colony — a cyclic cellular automaton; each cell's settled state is its ramp step.

    States 0..steps-1 chase each other cyclically on a wrapped lattice: a cell
    advances to the next state once enough of its neighbours already hold it.
    Run long enough, random noise resolves into rotating spiral fronts, and the
    settled state of every cell becomes its ramp index directly — no field, no
    quantiser, the automaton IS the ramp.
    """
    N = rng.choice([30, 40, 50])
    steps = rng.randint(5, 9)
    c = Canvas(N, rng.choice(PALETTE_NAMES), steps, "colony", "squares", tiles=True)

    moore = rng.random() < 0.6
    if moore:
        deltas = [(-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1)]
        threshold = rng.choice([2, 3, 3, 4])
    else:
        deltas = [(-1, 0), (1, 0), (0, -1), (0, 1)]
        threshold = rng.choice([1, 1, 2])

    state = [[rng.randrange(steps) for _ in range(N)] for _ in range(N)]
    gens = int(N * rng.uniform(1.8, 2.4))

    for _ in range(gens):
        nxt = [[0] * N for _ in range(N)]
        for j in range(N):
            row_above = state[j - 1]
            row = state[j]
            row_below = state[(j + 1) % N]
            for i in range(N):
                s = row[i]
                nx = (s + 1) % steps
                cnt = 0
                for (di, dj) in deltas:
                    src = row_above if dj == -1 else (row_below if dj == 1 else row)
                    if src[(i + di) % N] == nx:
                        cnt += 1
                        if cnt >= threshold:
                            break
                nxt[j][i] = nx if cnt >= threshold else s
        state = nxt

    c.ground(lambda i, j: state[j][i])

    C = c.C
    hi = steps // 2
    for j in range(N):
        row_above = state[j - 1]
        row = state[j]
        row_below = state[(j + 1) % N]
        for i in range(N):
            s = row[i]
            nx = (s + 1) % steps
            front = (row_above[i] == nx or row_below[i] == nx or
                     row[i - 1] == nx or row[(i + 1) % N] == nx)
            if front:
                ins = C * 0.30
                cx, cy = i * C + ins, j * C + ins
                c.sq(cx, cy, C - 2 * ins, C - 2 * ins, (s + hi) % steps)

    return c
colony-squares-40-e304
colony-squares-40-e304
colony-squares-40-8ddc
colony-squares-40-8ddc
colony-squares-30-d9fc
colony-squares-30-d9fc

generator