patterns — accrete

generator verdict no votes yet
source — color/auto/e001_accrete.g51_accrete
def g51_accrete(rng):
    """Accrete — multi-seed Eden growth; each cell's ramp step is its arrival time.

    A handful of seed cells grow outward one random frontier cell at a time,
    like invasion percolation. The fill order, ranked and reshaped by a random
    exponent, becomes the ramp step, so the earliest growth reads darkest and
    the outer shell reads lightest. A dot marks each seed once growth is laid.
    """
    N = rng.choice([30, 40, 50])
    steps = rng.randint(6, 10)
    c = Canvas(N, rng.choice(PALETTE_NAMES), steps, "accrete", "dots")

    moore = rng.random() < 0.5
    deltas = ([(-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1)]
              if moore else [(-1, 0), (1, 0), (0, -1), (0, 1)])

    nseeds = rng.randint(2, 6)
    seeds = set()
    while len(seeds) < nseeds:
        seeds.add((rng.randrange(N), rng.randrange(N)))
    seeds = list(seeds)

    arrival = [[-1] * N for _ in range(N)]
    order = 0
    frontier = []
    infront = set()
    for (si, sj) in seeds:
        arrival[si][sj] = order
        order += 1

    def push(i, j):
        for (di, dj) in deltas:
            ni, nj = i + di, j + dj
            if 0 <= ni < N and 0 <= nj < N and arrival[ni][nj] == -1 and (ni, nj) not in infront:
                frontier.append((ni, nj))
                infront.add((ni, nj))

    for (si, sj) in seeds:
        push(si, sj)

    while frontier:
        idx = rng.randrange(len(frontier))
        frontier[idx], frontier[-1] = frontier[-1], frontier[idx]
        i, j = frontier.pop()
        infront.discard((i, j))
        if arrival[i][j] != -1:
            continue
        arrival[i][j] = order
        order += 1
        push(i, j)

    total = N * N
    gamma = rng.uniform(0.85, 1.05)

    def band(i, j):
        t = (arrival[i][j] / (total - 1)) ** gamma
        return min(steps - 1, int(t * steps))

    c.ground(band)

    r = c.C * rng.uniform(0.45, 0.75)
    for (si, sj) in seeds:
        cx, cy = c.center(si, sj)
        c.dot(cx, cy, r, steps - 1)

    return c
accrete-dots-30-668b
accrete-dots-30-668b
accrete-dots-30-43cb
accrete-dots-30-43cb
accrete-dots-30-c192
accrete-dots-30-c192
accrete-dots-40-6196
accrete-dots-40-6196
accrete-dots-50-d263
accrete-dots-50-d263

generator