Skip to content

Instantly share code, notes, and snippets.

@nst
Last active April 3, 2023 08:09
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 nst/f9269ff6b8cadd619b9c3058868da70f to your computer and use it in GitHub Desktop.
Save nst/f9269ff6b8cadd619b9c3058868da70f to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
# Nicolas Seriot
# 2023-03-31
# https://gist.github.com/nst/f9269ff6b8cadd619b9c3058868da70f
# https://seriot.ch/visualization/wang_pipes.png
import random
import cairo
random.seed(0)
TS = 32
W = 16
H = 16
# sprite structure
# http://www.cr31.co.uk/stagecast/wang/intro.html
# http://www.cr31.co.uk/stagecast/wang/tiles_e.html
SPRITE_POS = [(0,3), # 0
(0,2), # 1
(1,3), # 2
(1,2), # 3
(0,0), # 4
(0,1), # 5
(1,0), # 6
(1,1), # 7
(3,3), # 8
(3,2), # 9
(2,3), # 10
(2,2), # 11
(3,0), # 12
(3,1), # 13
(2,0), # 14
(2,1)] # 15
def draw_tile(c, img, n):
assert(n in range(0,16))
x, y = SPRITE_POS[n]
c.save()
c.translate(TS*-x, TS*-y)
c.rectangle(TS*x, TS*y, TS, TS)
c.clip()
c.set_source_surface(img, 0, 0)
c.paint()
c.restore()
def fill_board(width, height, clean_edges):
# bits 1111 WSEN
m = [[0 for x in range(width)] for y in range(height)]
for y in range(height):
for x in range(width):
t = random.randint(0,15)
# propagate E -> W
if x > 0:
n = m[y][x-1]
t = (t & 0b0111) | ((n & 0b0010) << 2)
# propagate S -> N
if y > 0:
n = m[y-1][x]
t = (t & 0b1110) | ((n & 0b0100) >> 2)
if clean_edges:
if x == 0:
t &= 0b0111
if x == (width-1):
t &= 0b1101
if y == 0:
t &= 0b1110
if y == (height-1):
t &= 0b1001
m[y][x] = t
return m
def draw_board(m, sprite_name, board_name):
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, TS*W, TS*H)
c = cairo.Context(surface)
c.set_source_rgb(1,1,1)
c.paint()
sprite = cairo.ImageSurface.create_from_png(sprite_name)
assert(sprite.get_width() == 128)
assert(sprite.get_height() == 128)
for y in range(H):
for x in range(W):
n = m[y][x]
c.save()
c.translate(TS*x, TS*y)
draw_tile(c, sprite, n)
c.restore()
surface.write_to_png(board_name)
def main():
m = fill_board(width=W, height=H, clean_edges=False)
for l in m:
print(*[("{0:04b}".format(t)) for t in l])
draw_board(m, "wang2e.png", "wang.png")
# draw_board("pipe1.png", "wang.png")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment