Skip to content

Commit

Permalink
start on amazepartments
Browse files Browse the repository at this point in the history
  • Loading branch information
expenses committed Dec 16, 2024
1 parent 0d658c8 commit e9e5175
Show file tree
Hide file tree
Showing 4 changed files with 248 additions and 28 deletions.
143 changes: 143 additions & 0 deletions examples/paths.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@

from markov import *
from markov.wfc import TaggingTileset, Tags, wave_from_tiles, collapse_all_with_callback
from pprint import pprint

dim = 16

tileset = TaggingTileset()

empty = tileset.add(2.0, "empty", symmetry="X_3d")
line = tileset.add_mul(
1.0, 2, {"x": "line", "y": Tags(outgoing="empty"), "z": "empty"}, symmetry="I_3d"
)
turn = tileset.add_mul(
1.0, 4, {"x": "line", "negx": "empty", "z": "empty"}, symmetry="L_3d"
)
x = tileset.add(
0.1, {"x": Tags(incoming="cross", outgoing="line"), "z": "empty"}, symmetry="X_3d"
)

down = tileset.add_mul(
4.0,
4,
{
"x": "empty",
"negx": Tags(incoming="down", outgoing=["line", "up", "cross"]),
"y": "empty",
"negy": "empty",
"z": lambda i: f"stairs_{i}",
"negz": "empty",
},
)
up = tileset.add_mul(
4.0,
4,
{
"x": Tags(incoming="up", outgoing=["line", "down", "cross"]),
"negx": "empty",
"y": "empty",
"negy": "empty",
"negz": lambda i: f"stairs_{i}",
"z": "empty",
},
)

tiles = np.zeros((tileset.tileset.num_tiles(), 5, 5, 5), dtype=np.uint8)
line_vox = load_mkjr_vox("MarkovJunior/resources/tilesets/Paths/Line.vox")
corner_vox = load_mkjr_vox("MarkovJunior/resources/tilesets/Paths/Turn.vox")
down_vox = load_mkjr_vox("MarkovJunior/resources/tilesets/Paths/Down.vox")
up_vox = load_mkjr_vox("MarkovJunior/resources/tilesets/Paths/Up.vox")


tiles[x] = load_mkjr_vox("MarkovJunior/resources/tilesets/Paths/X.vox")
#tiles[empty] = load_mkjr_vox("MarkovJunior/resources/tilesets/Paths/Empty.vox")

for i, slot in enumerate(line):
tiles[slot] = np.rot90(line_vox, axes=(1, 2), k=i)

for i, slot in enumerate(turn):
tiles[slot] = np.rot90(corner_vox, axes=(1, 2), k=i)

for i, slot in enumerate(down):
tiles[slot] = np.rot90(down_vox, axes=(1, 2), k=i)

for i, slot in enumerate(up):
tiles[slot] = np.rot90(up_vox, axes=(1, 2), k=i + 2)

output = np.zeros((dim * 5, dim * 5, dim * 5), dtype=np.uint8)


iters = 0
while True:
iters += 1
wfc = tileset.tileset.create_wfc((dim, dim, dim))
for j in range(dim):
for i in range(dim):
#wfc.collapse((j, i, 0), empty)
wfc.collapse((i, j, dim - 1), empty)
wfc.collapse((i, 0, j), empty)
wfc.collapse((i, dim - 1, j), empty)
wfc.collapse((0, i, j), empty)
wfc.collapse((dim - 1, i, j), empty)

wfc.partial_collapse(
(i, j, 0), wave_from_tiles([empty, x] + line + down + turn)
)
found_contradiction = wfc.collapse_all()
if not found_contradiction:
print(iters)
break


output = map_3d(wfc.values(), output, tiles)
output[0, :, :] = index_for_colour("N")
output[1, :, :] = index_for_colour("E")
write_usd("pipes.usdc", output)
'''
rep(output, Prl(Pattern("Y=C", chance=0.25), settings=ONCE))
rep(output, "Y=B")
print(line_vox, index_for_colour("D"))
print(list(PICO8_PALETTE.srgb[index_for_colour("D")]))
#print(list(PICO8_PALETTE.srgb[80]))
print(chr(PALETTE_CHARS_TO_INDEX.index(40)))
rep(output, Pattern('DB=*F', shuffles=[[2,1,0]], flips=[[True, False, False]]))
rep(output, Pattern('FB=FF', shuffles=[[2,1,0]], flips=[[True, False, False]]))
#writer.write(output)
def chr_for_val(val):
return chr(PALETTE_CHARS_TO_INDEX.index(val))
rep(output, One(
"FF,EE=BB,EE",
"pF=*B",
Pattern('FB=BB', shuffles=[[2,1,0]], flips=TOGGLE_X)
))
print(up_vox, chr_for_val(18))
#rep(output, Pattern('FF,EE=BB,EE'))
#writer.write(output)
#rep(output, Pattern('FF,FD,EE=FF,BD,EE'))
#writer.write(output)
#rep(output, Pattern('FB=BB', shuffles=[[2,1,0]], flips=[[True, False, False]]))
#writer.write(output)
#rep(output, Pattern('BF=BB', shuffles=[[2,1,0]], flips=[[True, False, False]]))
writer.write(output)
rep(output, Pattern((
np.array([0, 42], dtype=np.uint8).reshape((2, 1, 1)),
np.array([index_for_colour("F"), 42], dtype=np.uint8).reshape((2, 1, 1))
), shuffles=NO_SHUFFLES, flips = NO_FLIPS))
rep(output, Pattern((
np.array([0, index_for_colour("F")], dtype=np.uint8).reshape((2, 1, 1)),
np.array([index_for_colour("F"), index_for_colour("F")], dtype=np.uint8).reshape((2, 1, 1))
), shuffles=NO_SHUFFLES, flips = NO_FLIPS))
'''

#write_usd("pipes.usdc", output)
79 changes: 79 additions & 0 deletions examples/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
from markov.wfc import *
import unittest


def mk_conns(updates):
conns = {
"x": Tags(),
"negx": Tags(),
"z": Tags(),
"negz": Tags(),
"y": Tags(),
"negy": Tags(),
}
conns.update(updates)
return conns


class Tester(unittest.TestCase):
def test_t_i(self):
c = MkJrConnector()
c.add("T", "T_3d")
c.add("I", "I_3d")

c.connect("I", 1, "T", 1)
c.tiles["T"][0].apply_symmetry()
self.assertEqual(
c.tiles["T"][0].conns,
mk_conns(
{
"negy": Tags(incoming="T_y_0", outgoing="I_negy_0"),
"y": Tags(incoming="T_y_0", outgoing="I_negy_0"),
}
),
# "{'x': (), 'y': (in: {'T_y_0'} out: {'I_negy_0'}), 'negx': (), 'negy': (in: {'T_y_0'} out: {'I_negy_0'}), 'z': (), 'negz': ()}"
)

def test_i_i(self):
c = MkJrConnector()
c.add("I", "I_3d")

c.connect("I", 1, "I", 1)
c.tiles["I"][0].apply_symmetry()
self.assertEqual(
c.tiles["I"][0].conns,
mk_conns(
{
"negy": Tags("I_y_0", "I_negy_0"),
"y": Tags("I_y_0", "I_negy_0"),
}
),
)

def test_i_i_flipped(self):
c = MkJrConnector()
c.add("I", "I_3d")

c.connect("I", 1, "I", 0, on_z=True)
self.assertEqual(
c.tiles["I"][0].conns,
mk_conns(
{
"z": Tags(incoming="I_z_0", outgoing="I_negz_1"),
"negz": Tags(incoming="I_negz_0", outgoing="I_z_1"),
}
),
)

"""def test_b(self):
c = MkJrConnector()
c.add("I", "I_3d")
c.connect("I", 0, "I", 1)
self.assertEqual(
str(c.tiles["I"][0].conns),
"{'x': (in: {'I_x_0'} out: {'I_negx_0'}), 'y': (), 'negx': (in: {'I_negx_0'} out: {'I_x_0'}), 'negy': (), 'z': (), 'negz': ()}"
)"""


unittest.main()
43 changes: 19 additions & 24 deletions markov/wfc.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from markov import Tileset, load_mkjr_vox, map_3d
import os
import numpy as np
import types

FLIPPED = {"x": "negx", "y": "negy", "negx": "x", "negy": "y", "z": "negz", "negz": "z"}

Expand Down Expand Up @@ -85,7 +86,7 @@ def merge(self, other):
other.outgoing = self.outgoing

def __repr__(self):
return "{}" if len(self.outgoing) == 0 else str(self.outgoing)
# return "{}" if len(self.outgoing) == 0 else str(self.outgoing)
bidirectional = self.incoming & self.outgoing
string = "("
if bidirectional != set():
Expand Down Expand Up @@ -116,40 +117,28 @@ def wave_from_tiles(tiles):

def apply_symmetry(tags, symmetry):
if type(tags) is not dict:
tags = {"x": tags}
tags = {"x": tags, "y": tags, "z": tags}

for dir in ["x", "y", "negx", "negy", "z", "negz"]:
if not dir in tags:
tags[dir] = Tags()
if type(tags[dir]) is str:
tags[dir] = Tags(tags[dir])

if symmetry == "X":
if symmetry.startswith("X"):
for dir in ["x", "y", "negx", "negy"]:
for other in tags.values():
tags[dir].merge(other)
if symmetry == "I":
for other in ["x", "y", "negx", "negy"]:
tags[dir].merge(tags[other])
if symmetry.startswith("I"):
tags["x"].merge(tags["negx"])
tags["y"].merge(tags["negy"])
if symmetry == "L":
if symmetry.startswith("L"):
tags["x"].merge(tags["y"])
tags["negx"].merge(tags["negy"])
if symmetry == "T":
tags["y"].merge(tags["negy"])
if symmetry == "X_3d":
for dir in ["x", "y", "negx", "negy", "z", "negz"]:
for other in tags.values():
tags[dir].merge(other)
if symmetry == "I_3d":
tags["x"].merge(tags["negx"])
tags["y"].merge(tags["negy"])
tags["z"].merge(tags["negz"])
if symmetry == "L_3d":
tags["x"].merge(tags["y"])
tags["negx"].merge(tags["negy"])
tags["z"].merge(tags["negz"])
if symmetry == "T_3d":
if symmetry.startswith("T"):
tags["y"].merge(tags["negy"])

if symmetry.endswith("_3d"):
tags["z"].merge(tags["negz"])
return tags

Expand Down Expand Up @@ -195,7 +184,14 @@ def add_mul(self, prob, rots, tags, symmetry=""):
prob /= rots
tags = apply_symmetry(tags, symmetry)
for i in range(rots):
res.append(self.add(prob, tags))
resolved_tags = {}
for dir, tag in tags.items():
if isinstance(tag, types.FunctionType):
resolved_tags[dir] = tag(i)
else:
resolved_tags[dir] = tag

res.append(self.add(prob, resolved_tags))
tags = rot_z(tags)
return res

Expand Down Expand Up @@ -437,7 +433,6 @@ def add_and_get_tile_ids(self, tileset):
print(" ", dir, variant.conns[dir])
print()


tile_ids[name] = [
tileset.add(variant.weight, variant.conns, symmetry="")
for variant in variants
Expand Down
11 changes: 7 additions & 4 deletions src/wfc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -380,10 +380,13 @@ impl<Wave: WaveNum, const BITS: usize> Wfc<Wave, BITS> {
}

pub fn set_values(&self, values: &mut [u8]) {
self.array
.iter()
.zip(values)
.for_each(|(wave, value)| *value = wave.trailing_zeros() as u8);
self.array.iter().zip(values).for_each(|(wave, value)| {
*value = if wave.count_ones() == 1 {
wave.trailing_zeros() as u8
} else {
u8::max_value()
}
});
}

#[cfg(test)]
Expand Down

0 comments on commit e9e5175

Please sign in to comment.