def g52_accretion(rng):
"""ACCRETION — a growth cluster built one cell at a time from a seed, each
step adding the open edge cell most favoured by a fixed stickiness field, so
growth chases the field's peaks instead of spreading evenly. Glyph weight at
each cell comes from its final neighbour count: core reads solid, fingers
reading light where the growth thinned out."""
N = rng.choice([32, 40, 50])
c = Canvas(N, "GLYPH", "glyph", "accretion", tiles=False)
NX, NY = c.cols, c.rows
occ = [[False] * NY for _ in range(NX)]
dirs4 = [(1, 0), (-1, 0), (0, 1), (0, -1)]
dirs8 = dirs4 + [(1, 1), (-1, -1), (1, -1), (-1, 1)]
n_seeds = rng.choice([1, 1, 2, 3])
seeds = set()
tries = 0
while len(seeds) < n_seeds and tries < 50:
tries += 1
seeds.add((rng.randrange(NX), rng.randrange(NY)))
for (si, sj) in seeds:
occ[si][sj] = True
frontier = set()
def open_around(i, j):
for dx, dy in dirs4:
ni, nj = i + dx, j + dy
if 0 <= ni < NX and 0 <= nj < NY and not occ[ni][nj]:
frontier.add((ni, nj))
for (si, sj) in seeds:
open_around(si, sj)
nz = Value2D(rng, res=rng.choice([3, 4, 5, 6]))
gamma = rng.uniform(1.0, 4.0)
target = int(NX * NY * rng.uniform(0.30, 0.50))
filled = len(seeds)
while filled < target and frontier:
items = list(frontier)
weights = []
for (i, j) in items:
u, v = (i + 0.5) / NX, (j + 0.5) / NY
weights.append(nz(u, v) ** gamma + 0.02)
tot = sum(weights)
r = rng.uniform(0.0, tot)
acc = 0.0
pick = items[-1]
for it, w in zip(items, weights):
acc += w
if r <= acc:
pick = it
break
i, j = pick
occ[i][j] = True
filled += 1
frontier.discard((i, j))
open_around(i, j)
ramp_chars = ramp([".", ":", "+", "x", "o", "#", "▒", "▓", "█"])
for i in range(NX):
for j in range(NY):
if not occ[i][j]:
continue
deg = 0
for dx, dy in dirs8:
ni, nj = i + dx, j + dy
if 0 <= ni < NX and 0 <= nj < NY and occ[ni][nj]:
deg += 1
k = min(len(ramp_chars) - 1, int(deg / 8.0 * (len(ramp_chars) - 1)))
c.glyph(i, j, ramp_chars[k])
return c