Created
November 5, 2019 20:08
-
-
Save kriskowal/285622566b3c609ac5e9e4ff0ebb20b9 to your computer and use it in GitHub Desktop.
Wandering Ents Lobster Proof of Concept
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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