Skip to content

Instantly share code, notes, and snippets.

@kriskowal
Created November 5, 2019 20:08
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 kriskowal/285622566b3c609ac5e9e4ff0ebb20b9 to your computer and use it in GitHub Desktop.
Save kriskowal/285622566b3c609ac5e9e4ff0ebb20b9 to your computer and use it in GitHub Desktop.
Wandering Ents Lobster Proof of Concept
import gui
import texture
def scatter(dst, src, stencils):
for(stencils) stencil, i:
for(stencil) j, k:
dst[i][k] = src[j]
def gather_intents(intents, neighborhoods, ents):
for(neighborhoods) neighbors, i:
intents[i] = if(ents[i]):
let candidates = filter(neighbors) n: !ents[n]
if length(candidates): candidates[rnd(length(candidates))]
else: -1
else: -1
def gather_winners(area, winners, neighborhoods, intent_neighborhoods, weight_neighborhoods):
for(area) i:
winners[i] = find_winner(i, neighborhoods[i], intent_neighborhoods[i], weight_neighborhoods[i])
def find_winner(i, neighborhood, intent_neighborhood, weight_neighborhood):
var best = -1
var winner = -1
for(length(neighborhood)) j:
if intent_neighborhood[j] == i and (best < 0 or weight_neighborhood[j] > best):
best = weight_neighborhood[j]
winner = neighborhood[j]
return winner
def gather_transitions(area, transitions, directions, neighborhoods, winners, winner_neighborhoods):
for(area) i:
let transition, direction = find_transition(i, neighborhoods[i], winners[i], winner_neighborhoods[i])
transitions[i] = transition
directions[i] = direction
def find_transition(i, neighbors, winner, winner_neighbors):
if winner >= 0: return winner, xy_0i
let found = find(winner_neighbors) j: i == j
if found >= 0: return neighbors[found], cardinal_directions[found]
return i, xy_0i
def transit(area, dst, src, transitions):
for(area) i:
let j = transitions[i]
dst[j] = src[i]
def move(area, dst, src):
for(area) i:
dst[i] = src[i]
def tick(
area,
neighborhoods,
ents,
intents,
intent_neighborhoods,
weights,
weight_neighborhoods,
winners,
winner_neighborhoods,
transitions,
directions,
ents_prev,
weights_prev
):
move(area, ents, ents_prev)
move(area, weights, weights_prev)
gather_intents(intents, neighborhoods, ents)
scatter(intent_neighborhoods, intents, neighborhoods)
scatter(weight_neighborhoods, weights, neighborhoods)
gather_winners(area, winners, neighborhoods, intent_neighborhoods, weight_neighborhoods)
scatter(winner_neighborhoods, winners, neighborhoods)
gather_transitions(area, transitions, directions, neighborhoods, winners, winner_neighborhoods)
transit(area, ents_prev, ents, transitions)
transit(area, weights_prev, weights, transitions)
def center_unit_square():
let size = float(gl_window_size())
let major = min(size.x, size.y)
let scale = xy_1 * major
gl_translate((size - scale) / 2)
gl_scale(scale)
do():
let astride = 16
let area = astride * astride
let grid = xy_1i * astride
let indices = map(area) i: i
let points = flatten(mapxy(grid) v: v)
def modxy(v, w): return xy{ (w.x + v.x) % w.x, (w.y + v.y) % w.y }
def index_of_point(v): return v.y * astride + v.x
let neighborhoods = map(points) v: map(cardinal_directions) d: index_of_point(modxy(v + d, grid))
let weights_prev = randomize(map(area) n: n)
let weights = map(area): 0
let ents_prev = map(area): if rnd(2) > 0: 1 else: 0
let ents = map(area): 0
let intents = map(points): 0
let intent_neighborhoods = map(points): map(cardinal_directions): 0
let weight_neighborhoods = map(points): map(cardinal_directions): 0
let winners = map(points): 0
let winner_neighborhoods = map(points): map(cardinal_directions): 0
let transitions = map(points): 0
let directions = map(points): xy_0i
var start = 0.0
def next():
tick(
area,
neighborhoods,
ents,
intents,
intent_neighborhoods,
weights,
weight_neighborhoods,
winners,
winner_neighborhoods,
transitions,
directions,
ents_prev,
weights_prev
)
start = gl_time()
next()
fatal(gl_window("Wandering Ents", 512, 512, 0))
let tex = gl_load_texture("1f332.png")
assert tex
while gl_frame():
var between = (gl_time() - start) * 5.0
if between > 1.0:
next()
between = 0.0
center_unit_square()
gl_clear(color_white)
gl_set_shader("textured")
gl_set_primitive_texture(0, tex)
for(area) i: if ents[i]:
let v1 = float(points[i])
let v2 = float(points[i] + directions[i])
let v = lerp(v1, v2, clamp(between, 0.0, 1.0))
gl_translate v/astride + xy_1/astride/4:
gl_rect(xy_1 / astride / 2, 0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment