Skip to content

Instantly share code, notes, and snippets.

@chrisamaphone
Last active October 23, 2023 22:05
Show Gist options
  • Save chrisamaphone/04ef080716b1c4bddbec71592ac54108 to your computer and use it in GitHub Desktop.
Save chrisamaphone/04ef080716b1c4bddbec71592ac54108 to your computer and use it in GitHub Desktop.
loopy-tiles
% Goal: tiles have paths that connect any of 8 corners/midpoints
% of the square.
anchor(up;down;left;right;ul;ur;lr;ll).
#const max=9.
dim(0..max).
% anchor adjacency
adj(up,ur).
adj(ur,right).
adj(right,lr).
adj(lr,down).
adj(down,ll).
adj(ll,left).
adj(left,ul).
adj(ul,up).
adj(A1, A2) :- adj(A2, A1).
tooclose(A, A) :- anchor(A).
tooclose(A1, A2) :- adj(A1, A2).
valid_tile(path(A1, A2)) :- anchor(A1), anchor(A2), not tooclose(A1, A2).
% place a tile at each position in the grid
1 { tile_at(X, Y, T) : valid_tile(T) } 1 :- dim(X), dim(Y).
% valid placement
% define neighbors
step(0,-1,down).
step(0,1,up).
step(1,-1,lr).
step(1,0,right).
step(1,1,ur).
step(-1,-1,ll).
step(-1,0,left).
step(-1,1,ul).
neighbor(X1, Y1, X2, Y2, Direction)
:- dim(X1), dim(Y1), dim(X2), dim(Y2),
step(DX, DY, Direction), X1+DX=X2, Y1+DY=Y2.
has_anchor(X, Y, A) :- tile_at(X, Y, path(A, B)).
has_anchor(X, Y, A) :- tile_at(X, Y, path(B, A)).
has_path_to(X1, Y1, X2, Y2, D)
:- neighbor(X1, Y1, X2, Y2, D), has_anchor(X1, Y1, D).
% if my neighbor has a path to me, then i should have an anchor
% in their direction.
:- neighbor(X1, Y1, X2, Y2, D), has_path_to(X2, Y2, X1, Y1, _),
not has_anchor(X1, Y1, D).
% edges don't have paths off the grid
:- has_anchor(X, Y, D), not neighbor(X, Y, _, _, D).
#show tile_at/3.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment