Commit 531db867 authored by Daniel Hader's avatar Daniel Hader

migrated code from wang

parent aa4cb4a9
# WebTAS
A tile assembly simulator for your browser.
requires three.js
Authors: Daniel Hader, Matthew Patitz
A blazing fast tile-assembly simulator for your browser.
6x6_square.tds
temperature=2
Seed0 0 0
TILENAME Seed0
LABEL L0
NORTHBIND 1
NORTHLABEL L0
EASTBIND 2
EASTLABEL fill*
SOUTHBIND 2
SOUTHLABEL *fill
WESTBIND 2
WESTLABEL S1
TILECOLOR Green
CREATE
TILENAME Seed1
LABEL 1
NORTHBIND 1
NORTHLABEL 1
EASTBIND 2
EASTLABEL S1
SOUTHBIND 1
SOUTHLABEL fill
WESTBIND 2
WESTLABEL S2
TILECOLOR Green
CREATE
TILENAME Seed2
LABEL M1
NORTHBIND 2
NORTHLABEL M1
EASTBIND 2
EASTLABEL S2
SOUTHBIND 1
SOUTHLABEL fill
WESTBIND 0
WESTLABEL
TILECOLOR Green
CREATE
TILENAME L0
LABEL L0
NORTHBIND 1
NORTHLABEL L0
EASTBIND 1
EASTLABEL fill
SOUTHBIND 2
SOUTHLABEL L1
WESTBIND 1
WESTLABEL <1
TILECOLOR Yellow
CREATE
TILENAME L1
LABEL L1
NORTHBIND 2
NORTHLABEL L1
EASTBIND 1
EASTLABEL fill
SOUTHBIND 1
SOUTHLABEL L0
WESTBIND 1
WESTLABEL 0>
TILECOLOR Yellow
CREATE
TILENAME <00
LABEL 0
NORTHBIND 1
NORTHLABEL 0
EASTBIND 1
EASTLABEL <0
SOUTHBIND 1
SOUTHLABEL 0
WESTBIND 1
WESTLABEL <0
TILECOLOR Yellow
CREATE
TILENAME <01
LABEL 1
NORTHBIND 1
NORTHLABEL 1
EASTBIND 1
EASTLABEL <1
SOUTHBIND 1
SOUTHLABEL 0
WESTBIND 1
WESTLABEL <0
TILECOLOR Yellow
CREATE
TILENAME <10
LABEL 1
NORTHBIND 1
NORTHLABEL 1
EASTBIND 1
EASTLABEL <0
SOUTHBIND 1
SOUTHLABEL 1
WESTBIND 1
WESTLABEL <0
TILECOLOR Yellow
CREATE
TILENAME <11
LABEL 0
NORTHBIND 1
NORTHLABEL 0
EASTBIND 1
EASTLABEL <1
SOUTHBIND 1
SOUTHLABEL 1
WESTBIND 1
WESTLABEL <1
TILECOLOR Yellow
CREATE
TILENAME 00>
LABEL 0
NORTHBIND 1
NORTHLABEL 0
EASTBIND 1
EASTLABEL 0>
SOUTHBIND 1
SOUTHLABEL 0
WESTBIND 1
WESTLABEL 0>
TILECOLOR Yellow
CREATE
TILENAME 10>
LABEL 1
NORTHBIND 1
NORTHLABEL 1
EASTBIND 1
EASTLABEL 0>
SOUTHBIND 1
SOUTHLABEL 1
WESTBIND 1
WESTLABEL 0>
TILECOLOR Yellow
CREATE
TILENAME M0>
LABEL M0
NORTHBIND 1
NORTHLABEL M0
EASTBIND 1
EASTLABEL 0>
SOUTHBIND 2
SOUTHLABEL M0
WESTBIND 0
WESTLABEL
TILECOLOR Yellow
CREATE
TILENAME M1>
LABEL M1
NORTHBIND 1
NORTHLABEL M1
EASTBIND 1
EASTLABEL 0>
SOUTHBIND 2
SOUTHLABEL M1
WESTBIND 0
WESTLABEL
TILECOLOR Yellow
CREATE
TILENAME <M0
LABEL M0
NORTHBIND 2
NORTHLABEL M0
EASTBIND 1
EASTLABEL <0
SOUTHBIND 1
SOUTHLABEL M0
WESTBIND 0
WESTLABEL
TILECOLOR Yellow
CREATE
TILENAME <M1
LABEL M1
NORTHBIND 2
NORTHLABEL M1
EASTBIND 1
EASTLABEL <0
SOUTHBIND 1
SOUTHLABEL M1
WESTBIND 0
WESTLABEL
TILECOLOR Yellow
CREATE
TILENAME <M1c
LABEL M1
NORTHBIND 2
NORTHLABEL M1
EASTBIND 1
EASTLABEL <1
SOUTHBIND 1
SOUTHLABEL M0
WESTBIND 0
WESTLABEL
TILECOLOR Yellow
CREATE
TILENAME End
LABEL End
NORTHBIND 0
NORTHLABEL
EASTBIND 1
EASTLABEL <1
SOUTHBIND 1
SOUTHLABEL M1
WESTBIND 0
WESTLABEL
TILECOLOR Yellow
CREATE
TILENAME fill
LABEL fill
NORTHBIND 1
NORTHLABEL fill
EASTBIND 1
EASTLABEL fill
SOUTHBIND 1
SOUTHLABEL fill
WESTBIND 1
WESTLABEL fill
TILECOLOR Grey
CREATE
TILENAME fill2
LABEL fill
NORTHBIND 1
NORTHLABEL fill>
EASTBIND 1
EASTLABEL fill>
SOUTHBIND 1
SOUTHLABEL fill>
WESTBIND 1
WESTLABEL fill>
TILECOLOR Grey
CREATE
TILENAME fill>
LABEL fill>
NORTHBIND 1
NORTHLABEL fill*
EASTBIND 1
EASTLABEL fill>
SOUTHBIND 1
SOUTHLABEL fill>
WESTBIND 2
WESTLABEL fill*
TILECOLOR Grey
CREATE
TILENAME fill*
LABEL fill*
NORTHBIND 1
NORTHLABEL fill
EASTBIND 2
EASTLABEL fill*
SOUTHBIND 1
SOUTHLABEL fill*
WESTBIND 1
WESTLABEL fill
TILECOLOR Grey
CREATE
TILENAME *fill
LABEL *fill
NORTHBIND 2
NORTHLABEL *fill
EASTBIND 1
EASTLABEL fill>
SOUTHBIND 1
SOUTHLABEL fill>
WESTBIND 1
WESTLABEL *fill
TILECOLOR Grey
CREATE
TILENAME <fill
LABEL *fill
NORTHBIND 1
NORTHLABEL fill
EASTBIND 1
EASTLABEL *fill
SOUTHBIND 2
SOUTHLABEL *fill
WESTBIND 1
WESTLABEL fill
TILECOLOR Grey
CREATE
SierpinskiTriangle.tds
Temperature=2
SEED 0 0 0
TILENAME SEED
LABEL Seed
NORTHBIND 2
EASTBIND 2
SOUTHBIND 2
WESTBIND 2
NORTHLABEL 1
EASTLABEL 1
SOUTHLABEL foo
WESTLABEL bar
TILECOLOR red
CREATE
TILENAME BOTTOM
LABEL Bottom
NORTHBIND 1
EASTBIND 2
SOUTHBIND 0
WESTBIND 2
NORTHLABEL 1
EASTLABEL 1
SOUTHLABEL
WESTLABEL 1
TILECOLOR red
CREATE
TILENAME RIGHT
LABEL Right
NORTHBIND 2
EASTBIND 1
SOUTHBIND 2
WESTBIND 0
NORTHLABEL 1
EASTLABEL 1
SOUTHLABEL 1
WESTLABEL
TILECOLOR red
CREATE
TILENAME 01
LABEL 1
NORTHBIND 1
EASTBIND 1
SOUTHBIND 1
WESTBIND 1
NORTHLABEL 1
EASTLABEL 1
SOUTHLABEL 0
WESTLABEL 1
TILECOLOR red
CREATE
TILENAME 10
LABEL 1
NORTHBIND 1
EASTBIND 1
SOUTHBIND 1
WESTBIND 1
NORTHLABEL 1
EASTLABEL 1
SOUTHLABEL 1
WESTLABEL 0
TILECOLOR red
CREATE
TILENAME 00
LABEL 0
NORTHBIND 1
EASTBIND 1
SOUTHBIND 1
WESTBIND 1
NORTHLABEL 0
EASTLABEL 0
SOUTHLABEL 0
WESTLABEL 0
CREATE
TILENAME 11
LABEL 0
NORTHBIND 1
EASTBIND 1
SOUTHBIND 1
WESTBIND 1
NORTHLABEL 0
EASTLABEL 0
SOUTHLABEL 1
WESTLABEL 1
CREATE
logwidth_binary_counter.tds
temperature=2
SEED 0 0
TILENAME SEED
LABEL M0*L
NORTHBIND 2
NORTHLABEL M0*L
EASTBIND 0
EASTLABEL
SOUTHBIND 0
SOUTHLABEL
WESTBIND 0
WESTLABEL
CREATE
TILENAME M1*L|-99|M0*L|-99
LABEL M1*L
NORTHBIND 2
NORTHLABEL M1*L
EASTBIND 0
EASTLABEL
SOUTHBIND 2
SOUTHLABEL M0*L
WESTBIND 0
WESTLABEL
TILECOLOR RGBA(255, 0, 0, 255)
CREATE
TILENAME 0*L|-99|M1*L|M
LABEL 0*L
NORTHBIND 2
NORTHLABEL 0*L
EASTBIND 0
EASTLABEL
SOUTHBIND 2
SOUTHLABEL M1*L
WESTBIND 2
WESTLABEL M
CREATE
TILENAME M1|M|-99|M
LABEL M1
NORTHBIND 1
NORTHLABEL M1
EASTBIND 2
EASTLABEL M
SOUTHBIND 0
SOUTHLABEL
WESTBIND 0
WESTLABEL M
TILECOLOR RGBA(255, 0, 0, 255)
CREATE
TILENAME 1L|-99|0*L|c*
LABEL 1L
NORTHBIND 1
NORTHLABEL 1L
EASTBIND 0
EASTLABEL
SOUTHBIND 2
SOUTHLABEL 0*L
WESTBIND 1
WESTLABEL c*
TILECOLOR RGBA(255, 0, 0, 255)
CREATE
TILENAME M1*|c*|M1|-99
LABEL M1*
NORTHBIND 2
NORTHLABEL M1*
EASTBIND 1
EASTLABEL c*
SOUTHBIND 1
SOUTHLABEL M1
WESTBIND 0
WESTLABEL
TILECOLOR RGBA(255, 0, 0, 255)
CREATE
TILENAME M1|*|M0*|-99
LABEL M1
NORTHBIND 1
NORTHLABEL M1
EASTBIND 1
EASTLABEL *
SOUTHBIND 2
SOUTHLABEL M0*
WESTBIND 0
WESTLABEL
TILECOLOR RGBA(255, 0, 0, 255)
CREATE
TILENAME 0|*|M1*|M
LABEL 0
NORTHBIND 1
NORTHLABEL 0
EASTBIND 1
EASTLABEL *
SOUTHBIND 2
SOUTHLABEL M1*
WESTBIND 2
WESTLABEL M
CREATE
TILENAME 0*L|-99|0L|*
LABEL 0*L
NORTHBIND 2
NORTHLABEL 0*L
EASTBIND 0
EASTLABEL
SOUTHBIND 1
SOUTHLABEL 0L
WESTBIND 1
WESTLABEL *
CREATE
TILENAME 0*L|-99|1L|*
LABEL 0*L
NORTHBIND 2
NORTHLABEL 0*L
EASTBIND 0
EASTLABEL
SOUTHBIND 1
SOUTHLABEL 1L
WESTBIND 1
WESTLABEL *
CREATE
TILENAME 0*|c*|0|c
LABEL 0*
NORTHBIND 2
NORTHLABEL 0*
EASTBIND 1
EASTLABEL c*
SOUTHBIND 1
SOUTHLABEL 0
WESTBIND 1
WESTLABEL c
CREATE
TILENAME 0|c|0|c
LABEL 0
NORTHBIND 1
NORTHLABEL 0
EASTBIND 1
EASTLABEL c
SOUTHBIND 1
SOUTHLABEL 0
WESTBIND 1
WESTLABEL c
CREATE
TILENAME M0|c|M0|-99
LABEL M0
NORTHBIND 1
NORTHLABEL M0
EASTBIND 1
EASTLABEL c
SOUTHBIND 1
SOUTHLABEL M0
WESTBIND 0
WESTLABEL
CREATE
TILENAME 1|c|1|c
LABEL 1
NORTHBIND 1
NORTHLABEL 1
EASTBIND 1
EASTLABEL c
SOUTHBIND 1
SOUTHLABEL 1
WESTBIND 1
WESTLABEL c
TILECOLOR RGBA(255, 0, 0, 255)
CREATE
TILENAME M1|c|M1|-99
LABEL M1
NORTHBIND 1
NORTHLABEL M1
EASTBIND 1
EASTLABEL c
SOUTHBIND 1
SOUTHLABEL M1
WESTBIND 0
WESTLABEL
TILECOLOR RGBA(255, 0, 0, 255)
CREATE
TILENAME 0|*|0|*
LABEL 0
NORTHBIND 1
NORTHLABEL 0
EASTBIND 1
EASTLABEL *
SOUTHBIND 1
SOUTHLABEL 0
WESTBIND 1
WESTLABEL *
CREATE
TILENAME 0|*|1|*
LABEL 0
NORTHBIND 1
NORTHLABEL 0
EASTBIND 1
EASTLABEL *
SOUTHBIND 1
SOUTHLABEL 1
WESTBIND 1
WESTLABEL *
CREATE
TILENAME 1|*|0*|c
LABEL 1
NORTHBIND 1
NORTHLABEL 1
EASTBIND 1
EASTLABEL *
SOUTHBIND 2
SOUTHLABEL 0*
WESTBIND 1
WESTLABEL c
TILECOLOR RGBA(255, 0, 0, 255)
CREATE
TILENAME 1|c*|1|c*
LABEL 1
NORTHBIND 1
NORTHLABEL 1
EASTBIND 1
EASTLABEL c*
SOUTHBIND 1
SOUTHLABEL 1
WESTBIND 1
WESTLABEL c*
TILECOLOR RGBA(255, 0, 0, 255)
CREATE
simple_TM.tds
Temperature=2
[q0],0 1 1
1|>|1|> 2 1
1|>|1|> 3 1
0|>|0|> 4 1
1|>|1|> 5 1
0|>|0|> 6 1
RIGHT0 7 1
TILENAME 0|<|0|<
LABEL 0
NORTHBIND 1
EASTBIND 1
SOUTHBIND 1
WESTBIND 1
NORTHLABEL 0
EASTLABEL <
SOUTHLABEL 0
WESTLABEL <
CREATE
TILENAME 0|>|0|>
LABEL 0
NORTHBIND 1
EASTBIND 1
SOUTHBIND 1
WESTBIND 1
NORTHLABEL 0
EASTLABEL >
SOUTHLABEL 0
WESTLABEL >
CREATE
TILENAME [q0],0
LABEL [q0],0
NORTHBIND 2
EASTBIND 1
SOUTHBIND 0
WESTBIND 0
NORTHLABEL [q0],0
EASTLABEL >
SOUTHLABEL -99
WESTLABEL -99
CREATE
TILENAME 1|<|1|<
LABEL 1
NORTHBIND 1
EASTBIND 1
SOUTHBIND 1
WESTBIND 1
NORTHLABEL 1
EASTLABEL <
SOUTHLABEL 1
WESTLABEL <
CREATE
TILENAME 1|>|1|>
LABEL 1
NORTHBIND 1
EASTBIND 1
SOUTHBIND 1
WESTBIND 1
NORTHLABEL 1
EASTLABEL >
SOUTHLABEL 1
WESTLABEL >
CREATE
TILENAME [q0],1
LABEL [q0],1
NORTHBIND 2
EASTBIND 1
SOUTHBIND 0
WESTBIND 0
NORTHLABEL [q0],1
EASTLABEL >
SOUTHLABEL -99
WESTLABEL -99
CREATE
TILENAME _|<|_|<
LABEL _
NORTHBIND 1
EASTBIND 1
SOUTHBIND 1
WESTBIND 1
NORTHLABEL _
EASTLABEL <
SOUTHLABEL _
WESTLABEL <
CREATE
TILENAME _|>|_|>
LABEL _
NORTHBIND 1
EASTBIND 1
SOUTHBIND 1
WESTBIND 1
NORTHLABEL _
EASTLABEL >
SOUTHLABEL _
WESTLABEL >
CREATE
TILENAME [q0],_
LABEL [q0],_
NORTHBIND 2
EASTBIND 1
SOUTHBIND 0
WESTBIND 0
NORTHLABEL [q0],_
EASTLABEL >
SOUTHLABEL -99
WESTLABEL -99
CREATE
TILENAME RIGHT0
LABEL _
NORTHBIND 1
EASTBIND 0
SOUTHBIND 0
WESTBIND 1
NORTHLABEL _*
EASTLABEL -99
SOUTHLABEL -99
WESTLABEL >
CREATE
TILENAME RIGHT1
LABEL _
NORTHBIND 1
EASTBIND 2
SOUTHBIND 1
WESTBIND 1
NORTHLABEL _
EASTLABEL _*
SOUTHLABEL _*
WESTLABEL >
CREATE
TILENAME RIGHT2
LABEL _
NORTHBIND 1
EASTBIND 0
SOUTHBIND 0
WESTBIND 2
NORTHLABEL _*
EASTLABEL -99
SOUTHLABEL -99
WESTLABEL _*
CREATE
TILENAME [q0],0|>|0|[q0],0
LABEL [q0],0
NORTHBIND 2
EASTBIND 1
SOUTHBIND 1
WESTBIND 1
NORTHLABEL [q0],0
EASTLABEL >
SOUTHLABEL 0
WESTLABEL [q0],0
CREATE
TILENAME [q0],1|>|1|[q0],0
LABEL [q0],1
NORTHBIND 2
EASTBIND 1
SOUTHBIND 1
WESTBIND 1
NORTHLABEL [q0],1
EASTLABEL >
SOUTHLABEL 1
WESTLABEL [q0],0
CREATE
TILENAME [q0],_|>|_|[q0],0
LABEL [q0],_
NORTHBIND 2
EASTBIND 1
SOUTHBIND 1
WESTBIND 1
NORTHLABEL [q0],_
EASTLABEL >
SOUTHLABEL _
WESTLABEL [q0],0
CREATE
TILENAME 0|[q0],0|[q0],0|<
LABEL 0
NORTHBIND 1
EASTBIND 1
SOUTHBIND 2
WESTBIND 1
NORTHLABEL 0
EASTLABEL [q0],0
SOUTHLABEL [q0],0
WESTLABEL <
CREATE
TILENAME [q0],0|>|0|[q0],1
LABEL [q0],0
NORTHBIND 2
EASTBIND 1
SOUTHBIND 1
WESTBIND 1
NORTHLABEL [q0],0
EASTLABEL >
SOUTHLABEL 0
WESTLABEL [q0],1
CREATE
TILENAME [q0],1|>|1|[q0],1
LABEL [q0],1
NORTHBIND 2
EASTBIND 1
SOUTHBIND 1
WESTBIND 1
NORTHLABEL [q0],1
EASTLABEL >
SOUTHLABEL 1
WESTLABEL [q0],1
CREATE
TILENAME [q0],_|>|_|[q0],1
LABEL [q0],_
NORTHBIND 2
EASTBIND 1
SOUTHBIND 1
WESTBIND 1
NORTHLABEL [q0],_
EASTLABEL >
SOUTHLABEL _
WESTLABEL [q0],1
CREATE
TILENAME 1|[q0],1|[q0],1|<
LABEL 1
NORTHBIND 1
EASTBIND 1
SOUTHBIND 2
WESTBIND 1
NORTHLABEL 1
EASTLABEL [q0],1
SOUTHLABEL [q0],1
WESTLABEL <
CREATE
TILENAME [q1],1|[q0],_|1|<
LABEL [q1],1
NORTHBIND 2
EASTBIND 1
SOUTHBIND 1
WESTBIND 1
NORTHLABEL [q1],1
EASTLABEL [q0],_
SOUTHLABEL 1
WESTLABEL <
CREATE
TILENAME HALT|[q0],_|0|<
LABEL [q1],0
NORTHBIND 2
EASTBIND 1
SOUTHBIND 1
WESTBIND 1
NORTHLABEL HALT
EASTLABEL [q0],_
SOUTHLABEL 0
WESTLABEL <
CREATE
TILENAME _|>|[q0],_|[q0],_
LABEL _
NORTHBIND 1
EASTBIND 1
SOUTHBIND 2
WESTBIND 1
NORTHLABEL _
EASTLABEL >
SOUTHLABEL [q0],_
WESTLABEL [q0],_
CREATE
TILENAME [q0],0|[q1],1|0|<
LABEL [q0],0
NORTHBIND 2
EASTBIND 1
SOUTHBIND 1
WESTBIND 1
NORTHLABEL [q0],0
EASTLABEL [q1],1
SOUTHLABEL 0
WESTLABEL <
CREATE
TILENAME [q0],1|[q1],1|1|<
LABEL [q0],1
NORTHBIND 2
EASTBIND 1
SOUTHBIND 1
WESTBIND 1
NORTHLABEL [q0],1
EASTLABEL [q1],1
SOUTHLABEL 1
WESTLABEL <
CREATE
TILENAME [q0],_|[q1],1|_|<
LABEL [q0],_
NORTHBIND 2
EASTBIND 1
SOUTHBIND 1
WESTBIND 1
NORTHLABEL [q0],_
EASTLABEL [q1],1
SOUTHLABEL _
WESTLABEL <
CREATE
TILENAME 1|>|[q1],1|[q1],1
LABEL 1
NORTHBIND 1
EASTBIND 1
SOUTHBIND 2
WESTBIND 1
NORTHLABEL 1
EASTLABEL >
SOUTHLABEL [q1],1
WESTLABEL [q1],1
CREATE
TILENAME 0|>|[q1],0|[q1],0
LABEL 0
NORTHBIND 1
EASTBIND 1
SOUTHBIND 2
WESTBIND 1
NORTHLABEL 0
EASTLABEL >
SOUTHLABEL [q1],0
WESTLABEL [q1],0
CREATE
TILENAME HALT
LABEL HALT
NORTHBIND 0
EASTBIND 0
SOUTHBIND 2
WESTBIND 0
NORTHLABEL -99
EASTLABEL -99
SOUTHLABEL HALT
WESTLABEL -99
TILECOLOR red
CREATE
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
<form id="tile-form" class="w3-container w3-small">
<br/>
<label>Tile Name</label>
<input id="tile-name-input" class="w3-input w3-border" type="text" />
<div class="w3-row">
<div class="w3-col w3-threequarter">
<label>Tile Label</label>
<input id="tile-label-input" class="w3-input w3-border" type="text" />
</div>
<div class="w3-quarter">
<label>Tile Color</label>
<input id="tile-color-input" class="w3-input w3-border" style="height: 36px;" type="color" />
</div>
</div>
<br/>
<div class="w3-row">
<div class="w3-col w3-threequarter">
<label>North Glue Label</label>
<input id="north-glue-label-input" class="w3-input w3-border" type="text" />
</div>
<div class="w3-quarter">
<label>Strength</label>
<input id="north-glue-strength-input" class="w3-input w3-border" type="number" />
</div>
</div>
<div class="w3-row">
<div class="w3-col w3-threequarter">
<label>East Glue Label</label>
<input id="east-glue-label-input" class="w3-input w3-border" type="text" />
</div>
<div class="w3-quarter">
<label>Strength</label>
<input id="east-glue-strength-input" class="w3-input w3-border" type="number" />
</div>
</div>
<div class="w3-row">
<div class="w3-col w3-threequarter">
<label>South Glue Label</label>
<input id="south-glue-label-input" class="w3-input w3-border" type="text" />
</div>
<div class="w3-quarter">
<label>Strength</label>
<input id="south-glue-strength-input" class="w3-input w3-border" type="number" />
</div>
</div>
<div class="w3-row">
<div class="w3-col w3-threequarter">
<label>West Glue Label</label>
<input id="west-glue-label-input" class="w3-input w3-border" type="text" />
</div>
<div class="w3-quarter">
<label>Strength</label>
<input id="west-glue-strength-input" class="w3-input w3-border" type="number" />
</div>
</div>
<br/></br>
<div class="w3-row">
<button id="update-tile-button" type="button" class="w3-button w3-border w3-half">Update Tile</button>
<button id="delete-tile-button" type="button" class="w3-button w3-border w3-half">Delete Tile</button>
</div>
</form>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
width="200"
height="200"
viewBox="0 0 52.916665 52.916668"
version="1.1"
id="svg8">
<defs
id="defs2" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1">
<rect
style="fill:#6464ff;fill-opacity:1;stroke:none;stroke-width:0.529;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
id="rect850"
width="21.166666"
height="21.166666"
x="2.6458342"
y="29.104166" />
<rect
style="fill:#ff6464;fill-opacity:1;stroke:none;stroke-width:0.529;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
id="rect852"
width="21.166666"
height="21.166666"
x="2.645834"
y="7.9375" />
<rect
style="fill:#64ff64;fill-opacity:1;stroke:none;stroke-width:0.529;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
id="rect854"
width="21.166666"
height="21.166666"
x="23.8125"
y="29.104166" />
<rect
style="fill:#ffff64;fill-opacity:1;stroke:none;stroke-width:0.529;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
id="rect858"
width="21.166666"
height="21.166666"
x="29.104166"
y="2.6458333" />
<path
style="fill:none;stroke:#000000;stroke-width:0.52916667;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
d="m 2.6458333,29.104166 c 21.1666657,0 21.1666657,0 21.1666657,0 v 21.166667"
id="path860" />
<path
style="fill:none;stroke:#000000;stroke-width:0.52916667;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
d="M 23.812499,29.104166 H 44.979166 V 50.270833"
id="path864" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458333;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
d="m 25.135417,29.104166 c 0,21.166667 0,21.166667 0,21.166667"
id="path868" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458333;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
d="m 22.489584,29.104166 c 0,21.166667 0,21.166667 0,21.166667"
id="path870" />
<path
style="fill:none;stroke:#000000;stroke-width:0.52916667;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
d="M 23.8125,29.104166 V 7.9375002 H 2.6458333"
id="path872" />
<path
style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 2.6458333,30.427083 H 23.8125"
id="path874" />
<path
style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 2.6458333,27.78125 H 23.8125"
id="path876" />
<path
style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 2.6458333,9.2604168 H 23.8125"
id="path878" />
<path
style="fill:none;stroke:#000000;stroke-width:0.52916673;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:1.05833346,1.05833346;stroke-dashoffset:0"
d="M 2.6458333,7.9375002 V 50.270833 H 44.979166"
id="path880" />
<path
style="fill:none;stroke:#000000;stroke-width:0.52916667;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
d="M 29.104166,2.6458333 V 23.8125 H 50.270833 V 2.6458333 Z"
id="path882" />
</g>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-box-arrow-in-down-right" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M6.364 2.5a.5.5 0 0 1 .5-.5H13.5A1.5 1.5 0 0 1 15 3.5v10a1.5 1.5 0 0 1-1.5 1.5h-10A1.5 1.5 0 0 1 2 13.5V6.864a.5.5 0 1 1 1 0V13.5a.5.5 0 0 0 .5.5h10a.5.5 0 0 0 .5-.5v-10a.5.5 0 0 0-.5-.5H6.864a.5.5 0 0 1-.5-.5z"/>
<path fill-rule="evenodd" d="M11 10.5a.5.5 0 0 1-.5.5h-5a.5.5 0 0 1 0-1h3.793L1.146 1.854a.5.5 0 1 1 .708-.708L10 9.293V5.5a.5.5 0 0 1 1 0v5z"/>
</svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-box-arrow-up-left" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M7.364 3.5a.5.5 0 0 1 .5-.5H14.5A1.5 1.5 0 0 1 16 4.5v10a1.5 1.5 0 0 1-1.5 1.5h-10A1.5 1.5 0 0 1 3 14.5V7.864a.5.5 0 1 1 1 0V14.5a.5.5 0 0 0 .5.5h10a.5.5 0 0 0 .5-.5v-10a.5.5 0 0 0-.5-.5H7.864a.5.5 0 0 1-.5-.5z"/>
<path fill-rule="evenodd" d="M0 .5A.5.5 0 0 1 .5 0h5a.5.5 0 0 1 0 1H1.707l8.147 8.146a.5.5 0 0 1-.708.708L1 1.707V5.5a.5.5 0 0 1-1 0v-5z"/>
</svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-caret-left-fill" viewBox="0 0 16 16">
<path d="m3.86 8.753 5.482 4.796c.646.566 1.658.106 1.658-.753V3.204a1 1 0 0 0-1.659-.753l-5.48 4.796a1 1 0 0 0 0 1.506z"/>
</svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-caret-right-fill" viewBox="0 0 16 16">
<path d="m12.14 8.753-5.482 4.796c-.646.566-1.658.106-1.658-.753V3.204a1 1 0 0 1 1.659-.753l5.48 4.796a1 1 0 0 1 0 1.506z"/>
</svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-file-earmark-code-fill" viewBox="0 0 16 16">
<path d="M9.293 0H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V4.707A1 1 0 0 0 13.707 4L10 .293A1 1 0 0 0 9.293 0zM9.5 3.5v-2l3 3h-2a1 1 0 0 1-1-1zM6.646 7.646a.5.5 0 1 1 .708.708L5.707 10l1.647 1.646a.5.5 0 0 1-.708.708l-2-2a.5.5 0 0 1 0-.708l2-2zm2.708 0 2 2a.5.5 0 0 1 0 .708l-2 2a.5.5 0 0 1-.708-.708L10.293 10 8.646 8.354a.5.5 0 1 1 .708-.708z"/>
</svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-folder-fill" viewBox="0 0 16 16">
<path d="M9.828 3h3.982a2 2 0 0 1 1.992 2.181l-.637 7A2 2 0 0 1 13.174 14H2.825a2 2 0 0 1-1.991-1.819l-.637-7a1.99 1.99 0 0 1 .342-1.31L.5 3a2 2 0 0 1 2-2h3.672a2 2 0 0 1 1.414.586l.828.828A2 2 0 0 0 9.828 3zm-8.322.12C1.72 3.042 1.95 3 2.19 3h5.396l-.707-.707A1 1 0 0 0 6.172 2H2.5a1 1 0 0 0-1 .981l.006.139z"/>
</svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-pause-fill" viewBox="0 0 16 16">
<path d="M5.5 3.5A1.5 1.5 0 0 1 7 5v6a1.5 1.5 0 0 1-3 0V5a1.5 1.5 0 0 1 1.5-1.5zm5 0A1.5 1.5 0 0 1 12 5v6a1.5 1.5 0 0 1-3 0V5a1.5 1.5 0 0 1 1.5-1.5z"/>
</svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-play-fill" viewBox="0 0 16 16">
<path d="m11.596 8.697-6.363 3.692c-.54.313-1.233-.066-1.233-.697V4.308c0-.63.692-1.01 1.233-.696l6.363 3.692a.802.802 0 0 1 0 1.393z"/>
</svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-skip-backward-fill" viewBox="0 0 16 16">
<path d="M.5 3.5A.5.5 0 0 0 0 4v8a.5.5 0 0 0 1 0V8.753l6.267 3.636c.54.313 1.233-.066 1.233-.697v-2.94l6.267 3.636c.54.314 1.233-.065 1.233-.696V4.308c0-.63-.693-1.01-1.233-.696L8.5 7.248v-2.94c0-.63-.692-1.01-1.233-.696L1 7.248V4a.5.5 0 0 0-.5-.5z"/>
</svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-skip-forward-fill" viewBox="0 0 16 16">
<path d="M15.5 3.5a.5.5 0 0 1 .5.5v8a.5.5 0 0 1-1 0V8.753l-6.267 3.636c-.54.313-1.233-.066-1.233-.697v-2.94l-6.267 3.636C.693 12.703 0 12.324 0 11.693V4.308c0-.63.693-1.01 1.233-.696L7.5 7.248v-2.94c0-.63.693-1.01 1.233-.696L15 7.248V4a.5.5 0 0 1 .5-.5z"/>
</svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-stop-fill" viewBox="0 0 16 16">
<path d="M5 3.5h6A1.5 1.5 0 0 1 12.5 5v6a1.5 1.5 0 0 1-1.5 1.5H5A1.5 1.5 0 0 1 3.5 11V5A1.5 1.5 0 0 1 5 3.5z"/>
</svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-zoom-in" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M6.5 12a5.5 5.5 0 1 0 0-11 5.5 5.5 0 0 0 0 11zM13 6.5a6.5 6.5 0 1 1-13 0 6.5 6.5 0 0 1 13 0z"/>
<path d="M10.344 11.742c.03.04.062.078.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1.007 1.007 0 0 0-.115-.1 6.538 6.538 0 0 1-1.398 1.4z"/>
<path fill-rule="evenodd" d="M6.5 3a.5.5 0 0 1 .5.5V6h2.5a.5.5 0 0 1 0 1H7v2.5a.5.5 0 0 1-1 0V7H3.5a.5.5 0 0 1 0-1H6V3.5a.5.5 0 0 1 .5-.5z"/>
</svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-zoom-out" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M6.5 12a5.5 5.5 0 1 0 0-11 5.5 5.5 0 0 0 0 11zM13 6.5a6.5 6.5 0 1 1-13 0 6.5 6.5 0 0 1 13 0z"/>
<path d="M10.344 11.742c.03.04.062.078.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1.007 1.007 0 0 0-.115-.1 6.538 6.538 0 0 1-1.398 1.4z"/>
<path fill-rule="evenodd" d="M3 6.5a.5.5 0 0 1 .5-.5h6a.5.5 0 0 1 0 1h-6a.5.5 0 0 1-.5-.5z"/>
</svg>
\ No newline at end of file
uniform sampler2D map;
flat in ivec4 v_strengths;
in vec2 v_uv;
void main() {
vec2 n_uv = (v_uv + vec2(v_strengths.x, 0.0)) / 4.0;
vec2 e_uv = (v_uv + vec2(v_strengths.y, 1.0)) / 4.0;
vec2 s_uv = (v_uv + vec2(v_strengths.z, 2.0)) / 4.0;
vec2 w_uv = (v_uv + vec2(v_strengths.w, 3.0)) / 4.0;
vec4 north = texture2D(map, n_uv);
vec4 east = texture2D(map, e_uv);
vec4 south = texture2D(map, s_uv);
vec4 west = texture2D(map, w_uv);
gl_FragColor = max(north, max(east, max(south, west)));
}
in vec3 offset;
in ivec4 strengths;
flat out ivec4 v_strengths;
out vec2 v_uv;
void main() {
v_uv = uv;
v_strengths = strengths;
gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position + offset, 1.0);
}
precision highp float;
uniform sampler2D map;
in vec2 texCoords;
in vec3 color;
in float screenFieldRange;
float median(vec4 v) {
return max(min(v.r, v.g), min(max(v.r, v.g), v.b));
}
void main() {
vec4 mtsdf = texture2D(map, texCoords);
float signDist = median(mtsdf);
float pxDist = screenFieldRange * (signDist - 0.5);
float alpha = clamp(pxDist + 0.5, 0.0, 1.0);
gl_FragColor = vec4(color, alpha);
}
uniform vec2 viewport;
uniform float fieldRange;
// glyph space attributes
in vec2 atlasOffset;
in vec2 atlasSize;
in vec2 glyphOrigin;
in vec2 glyphUp;
in vec2 glyphRight;
in vec2 glyphOffset;
in vec3 glyphColor;
in float glyphSize;
out vec2 texCoords;
out vec3 color;
out float screenFieldRange;
void main() {
texCoords = uv * atlasSize + atlasOffset;
color = glyphColor;
screenFieldRange = glyphSize * projectionMatrix[1][1] * viewport.y * fieldRange / 2.0;
vec2 glyphPosition = position.x * glyphRight + position.y * glyphUp + glyphOrigin + glyphOffset;
gl_Position = projectionMatrix * viewMatrix * vec4(glyphPosition, 0.0, 1.0);
}
This diff is collapsed.
body {
margin: 0;
background-color: #000;
color: #fff;
font-family: Monospace;
font-size: 13px;
line-height: 24px;
overscroll-behavior: none;
}
a {
color: #ff0;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
button {
cursor: pointer;
text-transform: uppercase;
}
#info {
position: absolute;
top: 0px;
width: 100%;
padding: 10px;
box-sizing: border-box;
text-align: center;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
user-select: none;
pointer-events: none;
z-index: 1; /* TODO Solve this in HTML */
}
a, button, input, select {
pointer-events: auto;
}
.lil-gui {
z-index: 2 !important; /* TODO Solve this in HTML */
}
@media all and ( max-width: 640px ) {
.lil-gui.root {
right: auto;
top: auto;
max-height: 50%;
max-width: 80%;
bottom: 0;
left: 0;
}
}
#overlay {
position: absolute;
font-size: 16px;
z-index: 2;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
background: rgba(0,0,0,0.7);
}
#overlay button {
background: transparent;
border: 0;
border: 1px solid rgb(255, 255, 255);
border-radius: 4px;
color: #ffffff;
padding: 12px 18px;
text-transform: uppercase;
cursor: pointer;
}
#notSupported {
width: 50%;
margin: auto;
background-color: #f00;
margin-top: 20px;
padding: 10px;
}
const scene = new THREE.Scene();
const camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 1, 10);
const renderer = new THREE.WebGLRenderer();
document.getElementById("simulator").appendChild(renderer.domElement);
window.addEventListener('resize', resize, false);
const tile_types = [
new TileType("seed", "seed", "#aaaaff", {
north: new Glue(2, "A"),
east: new Glue(2, "B")}),
new TileType("Vertical", "V", "#ffaaff", {
north: new Glue(2, "A"),
east: new Glue(1, '1'),
south: new Glue(2, "A")}),
new TileType("Horizontal", "H", "#aaffff", {
north: new Glue(1, '0'),
east: new Glue(2, "B"),
west: new Glue(2, "B")}),
new TileType("Add 00", "0", "#cccccc", {
north: new Glue(1, "0"),
east: new Glue(1, "0"),
south: new Glue(1, "0"),
west: new Glue(1, "0")}),
new TileType("Add 01", "1", "#666666", {
north: new Glue(1, "1"),
east: new Glue(1, "0"),
south: new Glue(1, "0"),
west: new Glue(1, "1")}),
new TileType("Add 10", "1", "#666666", {
north: new Glue(1, "1"),
east: new Glue(1, "0"),
south: new Glue(1, "1"),
west: new Glue(1, "0")}),
new TileType("Add 11", "0", "#cccccc", {
north: new Glue(1, "0"),
east: new Glue(1, "1"),
south: new Glue(1, "1"),
west: new Glue(1, "1")}),
];
system = new System(2, tile_types);
camera.position.set(0, 0, 2);
camera.updateProjectionMatrix();
renderer.setClearColor(0xffffaa, 1);
resize();
animate();
function resize() {
const aspect = window.innerWidth / window.innerHeight;
camera.left = -aspect;
camera.right = aspect;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
const NO_MENU = 0;
const FILE_MENU = 1;
const VIEW_MENU = 2;
const SETTINGS_MENU = 3;
let open_menu = NO_MENU;
function dropdown(content_div) {
let open = false;
function click() {
if (open) {
content_div.className = content_div.className.replace(" w3-show", "");
open = false;
} else {
content_div.className += " w3-show";
open = true;
}
}
return click;
}
import * as THREE from './three.module.mjs';
import { Logger } from './logger.mjs';
const textureList = {
//font: "assets/fonts/OpenSansCondensed-Light/mtsdf.png",
font: "assets/fonts/roboto/roboto_mtsdf.png",
outlines: "assets/textures/outlines.png",
//outline0: "assets/textures/outline0.png",
//outline1: "assets/textures/outline1.png",
//outline2: "assets/textures/outline2.png",
no_tile: "assets/textures/no_tile.png",
//selected_tile_label: "assets/textures/selected_tile_label.png",
};
const fileList = {
font_data: "assets/fonts/roboto/roboto_mtsdf.json",
text_vs: "assets/shaders/text.vert",
text_fs: "assets/shaders/text.frag",
outline_vs: "assets/shaders/outline.vert",
outline_fs: "assets/shaders/outline.frag",
sierpinski_tds: "assets/examples/SierpinskiTriangle.tds",
sierpinski_tdp: "assets/examples/SierpinskiTriangle.tdp",
counter_tds: "assets/examples/logwidth_binary_counter.tds",
counter_tdp: "assets/examples/logwidth_binary_counter.tdp",
square6x6_tds: "assets/examples/6x6_square.tds",
square6x6_tdp: "assets/examples/6x6_square.tdp",
turing_machine_tds: "assets/examples/turing_machine.tds",
turing_machine_tdp: "assets/examples/turing_machine.tdp",
tile_properties_html: "assets/html/tile_properties.html",
};
let assetCount = 0;
const textures = {};
const files = {};
export function loadAssets(callback) {
const fileLoader = new THREE.FileLoader();
const textureLoader = new THREE.TextureLoader();
THREE.DefaultLoadingManager.onLoad = () => {
Logger.log(Logger.INFO, `loaded ${assetCount} assets during initialization`);
callback();
};
for (const [name, url] of Object.entries(textureList)) {
textureLoader.load(url, (texture) => {
textures[name] = texture;
assetCount++;
});
}
for (const [name, url] of Object.entries(fileList)) {
fileLoader.load(url, (data) => {
files[name] = data;
assetCount++;
});
}
}
export function getTexture(name) {
return textures[name];
}
export function getFile(name) {
return files[name];
}
import * as AssetManager from './assetmanager.mjs';
import { Logger } from './logger.mjs';
import { parseColor } from './utils.mjs';
const UPDATE_SEED_MESSAGE = 'Warning, updating this tile will clear the simulation assembly. This tile belongs to the seed assembly, so the current assembly will be fully cleared.';
const UPDATE_NO_SEED_MESSAGE = 'Warning, updating this tile will revert the simulation assembly to the seed.';
const DELETE_SEED_MESSAGE = 'Warning, deleting this tile will clear the simulation assembly. This tile belongs to the seed assembly, so the current assembly will be fully cleared.';
const DELETE_NO_SEED_MESSAGE = 'Warning, deleting this tile will revert the simulation assembly to the seed.';
export class Editor {
constructor(simulator) {
this.simulator = simulator;
this.newTileButton = document.getElementById('new-tile-button');
this.newTileButton.disabled = true;
this.selectedType = undefined;
}
init() {
const domparser = new DOMParser();
this.form = domparser.parseFromString(AssetManager.getFile('tile_properties_html'), 'text/html');
this.inputs = {
tileName: this.form.getElementById('tile-name-input'),
tileLabel: this.form.getElementById('tile-label-input'),
tileColor: this.form.getElementById('tile-color-input'),
northLabel: this.form.getElementById('north-glue-label-input'),
northStrength: this.form.getElementById('north-glue-strength-input'),
eastLabel: this.form.getElementById('east-glue-label-input'),
eastStrength: this.form.getElementById('east-glue-strength-input'),
southLabel: this.form.getElementById('south-glue-label-input'),
southStrength: this.form.getElementById('south-glue-strength-input'),
westLabel: this.form.getElementById('west-glue-label-input'),
westStrength: this.form.getElementById('west-glue-strength-input'),
};
this.updateTileButton = this.form.getElementById('update-tile-button');
this.deleteTileButton = this.form.getElementById('delete-tile-button');
this.updateTileButton.addEventListener('click', () => { this.onUpdateTile(); });
this.deleteTileButton.addEventListener('click', () => { this.onDeleteTile(); });
this.newTileButton.addEventListener('click', () => { this.onAddTile(); });
this.setFormDisabled(true);
const properties = document.getElementById('tile-properties');
properties.appendChild(this.form.getElementById('tile-form'));
}
setTiles(tileset) {
this.tileset = tileset;
const tileTypes = this.tileset.getTileTypes();
const tileList = document.getElementById('tile-list');
while (this.newTileButton.nextSibling) {
tileList.removeChild(this.newTileButton.nextSibling)
}
for (const type of tileTypes) {
const tile_elem = document.createElement('button');
const box_span = document.createElement('span');
box_span.classList.add('material-icons', 'w3-small');
box_span.appendChild(document.createTextNode('square'));
box_span.style.color = type.color.getHexString();
tile_elem.appendChild(box_span);
tile_elem.appendChild(document.createTextNode(type.name));
tile_elem.classList.add('tile-list-entry', 'w3-bar-item', 'w3-border-bottom', 'w3-button', 'w3-small', 'w3-white', 'w3-hover-pale-green', 'w3-left-align');
tileList.appendChild(tile_elem);
tile_elem.addEventListener('click', () => { this.simulator.selectTile(type) });
}
this.newTileButton.disabled = false;
}
onSelectTile(type) {
this.selectedType = type;
if (!type) {
this.setFormDisabled(true);
this.inputs.tileName.value = '';
this.inputs.tileLabel.value = '';
this.inputs.tileColor.value = '#ffffff';
for (const dir of ['north', 'east', 'south', 'west']) {
this.inputs[`${dir}Label`].value = '';
this.inputs[`${dir}Strength`].value = 0;
}
} else {
this.setFormDisabled(false);
this.inputs.tileName.value = type.name;
this.inputs.tileLabel.value = type.label;
this.inputs.tileColor.value = type.color.getHexString();
for (const dir of ['north', 'east', 'south', 'west']) {
if (type.glues[dir]) {
this.inputs[`${dir}Label`].value = type.glues[dir].label;
this.inputs[`${dir}Strength`].value = type.glues[dir].strength;
} else {
this.inputs[`${dir}Label`].value = '';
this.inputs[`${dir}Strength`].value = 0;
}
}
}
}
setFormDisabled(disabled=true) {
Object.keys(this.inputs).forEach((key, index) => {
this.inputs[key].disabled = disabled;
});
this.updateTileButton.disabled = disabled;
this.deleteTileButton.disabled = disabled;
}
onUpdateTile() {
let typeInSeed = false;
for (const tile of this.simulator.seedTiles) {
if (this.selectedType.id === tile.type.id) {
typeInSeed = true;
break;
}
}
const warning = typeInSeed ? UPDATE_SEED_MESSAGE : UPDATE_NO_SEED_MESSAGE;
if ( !confirm(warning) )
return false;
const oldName = this.selectedType.name;
const newName = this.inputs.tileName.value;
const newType = {
name: this.inputs.tileName.value,
label: this.inputs.tileLabel.value,
color: parseColor(this.inputs.tileColor.value),
glues: {},
id: this.selectedType.id,
};
for (const dir of ['north', 'east', 'south', 'west']) {
const label = this.inputs[`${dir}Label`].value.trim();
const strength = parseInt(this.inputs[`${dir}Strength`].value);
if (label === '' || strength === NaN) {
newType.glues[dir] = null;
} else {
newType.glues[dir] = {
label: label,
strength: strength,
};
}
}
this.simulator.tileset.updateTileType(this.selectedType.id, newType);
if (oldName === newName) {
Logger.log(Logger.INFO, `updated tile "${oldName}"`);
} else {
Logger.log(Logger.INFO, `updated tile "${oldName}" (now "${newName}")`);
}
this.setTiles(this.simulator.tileset);
this.simulator.reset(!typeInSeed);
this.simulator.selectTile(newType);
}
onDeleteTile() {
let typeInSeed = false;
for (const tile of this.simulator.seedTiles) {
if (this.selectedType.id === tile.type.id) {
typeInSeed = true;
break;
}
}
const warning = typeInSeed ? DELETE_SEED_MESSAGE : DELETE_NO_SEED_MESSAGE;
if ( !confirm(warning) )
return false;
const oldName = this.selectedType.name;
this.simulator.tileset.removeTileType(this.selectedType.id);
Logger.log(Logger.INFO, `deleted tile "${oldName}"`);
this.setTiles(this.simulator.tileset);
this.simulator.reset(!typeInSeed);
this.simulator.selectTile(undefined);
}
onAddTile() {
let tileName = "New Tile";
if (this.simulator.tileset.hasTileWithName(tileName)) {
let num = 1;
while (this.simulator.tileset.hasTileWithName(`${tileName} (${num})`)) num++;
tileName = `${tileName} (${num})`;
}
const type = {
name: tileName,
label: '',
color: parseColor('white'),
glues: {
north: null,
east: null,
south: null,
west: null,
},
id: undefined,
};
this.simulator.tileset.addTileType(type);
Logger.log(Logger.INFO, `added new tile "${tileName}"`);
this.setTiles(this.simulator.tileset);
this.simulator.selectTile(type);
}
}
\ No newline at end of file
This diff is collapsed.
import { StochasticEventSet } from './stochastic_event.mjs';
const NORTH = 0;
const EAST = 1;
const SOUTH = 2;
const WEST = 3;
let temperature = 2;
let Gmc = 19.1, Gse = 10.0;
let kf = 1.2e7;
let eventSet = new StochasticEventSet(Gmc, Gse, kf);
let tileTypes = [];
let glues = [];
let locationMap = new Map(); // maps occupied locations to tile data
let seedLocations = new Set();
let adjacentLocations = new Set();
let signatureTable = new Map();
let signatureMap = new Map();
let frontierMap = new Map();
function locationKey(x, y) {
let a = x * 2;
if (a < 0)
a = -(a + 1);
let b = y * 2;
if (b < 0)
b = -(b + 1);
return Math.round((a + b) * (a + b + 1) / 2 + b);
}
const DX = [0, 1, 0, -1];
const DY = [1, 0, -1, 0];
const DIRS = ["north", "east", "south", "west"];
function calculateStrength(tid, x, y) {
let strength = 0;
const type = tileTypes[tid];
for (let i = 0; i < 4; i++) {
const nbrKey = locationKey(x + DX[i], y + DY[i]);
const glue = type.glues[i];
// if nbr exists, then add glue strength
if (locationMap.has(nbrKey) and glue >= 0) {
const nbr = locationMap.get(nbrKey);
const nbrType = tileTypes[nbr.tid];
const nbrGlue = nbrType.glues[(i + 2) % 4];
if (glue === nbrGlue) {
strength += glues[glue];
}
}
}
return strength;
}
function addTile(tid, x, y, isSeed=false) {
const locKey = locationKey(x, y);
if (locationMap.has(locKey)) {
console.log(`Attempting to add a tile ${tid} in an occupied location (${x}, ${y})`);
return false;
}
const strength = calculateStrength(tid, x, y);
const tile = {tid: tid, x:x, y:y, strength:strength};
// add location to location map
locationMap.set(locKey, tile);
// update neighboring tile strengths
// for (let i = 0; i < 4; i++) {
// const nbrKey = locationKey(x + DX[i], y + DY[i]);
// if (locationMap.has(nbrKey)) {
// const nbr = locationMap.get(nbrKey);
// nbr.strength = calculateStrength(nbr.tid, nbr.x, nbr.y);
// }
// }
// todo update event set
// seed tiles will not detach
if (isSeed) {
}
}
function removeTile(tid, x, y) {
}
function stepForward() {
}
\ No newline at end of file
document.addEventListener('DOMContentLoaded', () => {
Split({
rowGutters: [{
track: 1,
element: document.getElementById("editor-gutter")
},{
track: 3,
element: document.getElementById("log-gutter")
}],
columnGutters: [{
track: 1,
element: document.getElementById("simulator-gutter")
}]
})
});
const MONTH_TABLE = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
export class Logger {
static INFO = 'INFO';
static ERROR = 'ERROR';
static WARNING = 'WARNING';
static messages = [];
static logDom;
static init(logDOM) {
this.messages = [];
this.logDOM = logDOM;
}
static log(type, message) {
const date = new Date();
Logger.messages.push({type: type, message: message, date: date});
const messageDOM = document.createElement('div');
const entryType = document.createElement('div');
const entryMsg = document.createElement('div');
const entryDate = document.createElement('div');
messageDOM.classList.add('log-entry', 'w3-small', 'w3-container', 'w3-leftbar', 'w3-rightbar', 'w3-border-bottom', 'w3-monospace');
entryType.classList.add('log-type');
entryMsg.classList.add('log-message', 'w3-border-left', 'w3-border-right');
entryDate.classList.add('log-date');
if (type === Logger.ERROR) {
messageDOM.classList.add('w3-pale-red', 'w3-border-red');
} else if (type === Logger.WARNING) {
messageDOM.classList.add('w3-pale-yellow', 'w3-border-yellow');
} else {
messageDOM.classList.add('w3-light-gray', 'w3-border-gray');
}
const timeStr = `${String(date.getHours()).padStart(2,0)}:${String(date.getMinutes()).padStart(2,0)}:${String(date.getSeconds()).padStart(2,0)}`;
const dateStr = `${String(date.getDay()).padStart(2,0)}/${String(date.getMonth()).padStart(2,0)}/${date.getFullYear()}`;
entryType.appendChild(document.createTextNode(type));
entryMsg.appendChild(document.createTextNode(message));
entryDate.appendChild(document.createTextNode(timeStr + ' ' + dateStr));
messageDOM.appendChild(entryType);
messageDOM.appendChild(entryMsg);
messageDOM.appendChild(entryDate);
if (Logger.logDOM !== undefined) {
Logger.logDOM.appendChild(messageDOM);
Logger.logDOM.scrollTop = Logger.logDOM.scrollHeight;
}
}
}
This diff is collapsed.
import * as THREE from './three.module.mjs';
import * as AssetManager from './assetmanager.mjs';
import { TextManager } from './textmanager.mjs';
import { Vector2D } from './utils.mjs';
export class SelectedTile {
constructor(scene) {
this.backgroundColor = 0xffffee;
this.simulator = simulator;
this.canvas = document.getElementById('tile-canvas');
this.renderer = new THREE.WebGLRenderer({antialias: true, canvas: this.canvas});
this.renderer.setPixelRatio(window.devicePixelRatio);
this.scene = new THREE.Scene();
this.camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 1, 10);
this.camera.position.z = 4;
this.resizeObserver = new ResizeObserver((entries) => { this.resize(); });
this.resizeObserver.observe(this.canvas);
this.textManager = new TextManager(this.scene, this.canvas);
}
init() {
this.textManager.init();
const noTileTexture = AssetManager.getTexture('no_tile');
const tileGeom = new THREE.PlaneGeometry(1, 1);
const noTileMat = new THREE.MeshBasicMaterial({map: noTileTexture, transparent: true});
this.noTileMesh = new THREE.Mesh(tileGeom, noTileMat);
this.scene.add(this.noTileMesh);
this.tileGroup = new THREE.Group();
const tileMat = new THREE.MeshBasicMaterial();
this.tileMesh = new THREE.Mesh(tileGeom, tileMat);
this.tileGroup.add(this.tileMesh);
const vertices = new Float32Array([
-0.515625, -0.515625, 0.0,
0.515625, -0.515625, 0.0,
-0.515625, 0.515625, 0.0,
0.515625, 0.515625, 0.0,
-0.515625, 0.515625, 0.0,
0.515625, -0.515625, 0.0,
]);
const uvs = new Float32Array([
0.0, 0.0,
1.0, 0.0,
0.0, 1.0,
1.0, 1.0,
0.0, 1.0,
1.0, 0.0,
]);
const offset = new Float32Array([
0.0, 0.0, 0.0,
0.0, 0.0, 0.0,
0.0, 0.0, 0.0,
0.0, 0.0, 0.0,
0.0, 0.0, 0.0,
0.0, 0.0, 0.0,
]);
const strengths = new Int32Array([
2, 2, 2, 2,
2, 2, 2, 2,
2, 2, 2, 2,
2, 2, 2, 2,
2, 2, 2, 2,
2, 2, 2, 2,
]);
const outlineGeometry = new THREE.BufferGeometry();
outlineGeometry.setAttribute("position", new THREE.BufferAttribute(vertices, 3));
outlineGeometry.setAttribute("uv", new THREE.BufferAttribute(uvs, 2));
outlineGeometry.setAttribute("offset", new THREE.BufferAttribute(offset, 3));
outlineGeometry.setAttribute("strengths", new THREE.BufferAttribute(strengths, 4));
const outlineTexture = AssetManager.getTexture("outlines").clone();
outlineTexture.magFilter = THREE.NearestFilter;
outlineTexture.minFilter = THREE.LinearFilter;
outlineTexture.needsUpdate = true;
const outlineMaterial = new THREE.ShaderMaterial();
outlineMaterial.uniforms = {
map: { value: outlineTexture },
};
outlineMaterial.vertexShader = AssetManager.getFile("outline_vs");
outlineMaterial.fragmentShader = AssetManager.getFile("outline_fs");
outlineMaterial.transparent = true;
this.outlineMesh = new THREE.Mesh(outlineGeometry, outlineMaterial);
this.tileGroup.add(this.outlineMesh);
this.tileGroup.visible = false;
this.scene.add(this.tileGroup);
}
selectTile(tileType) {
if (!tileType) {
this.noTileMesh.visible = true;
this.tileGroup.visible = false;
this.textManager.clearText();
} else {
this.tileMesh.material.color = new THREE.Color(tileType.color.getHexString());
const strengthsAttrib = this.outlineMesh.geometry.attributes.strengths.array;
const dirs = ['north', 'east', 'south', 'west'];
for (let i = 0; i < dirs.length; i++) {
const dir = dirs[i];
if (tileType.glues[dir]) {
for (let j = 0; j < 6; j++) strengthsAttrib[i + 4*j] = tileType.glues[dir].strength;
} else {
for (let j = 0; j < 6; j++) strengthsAttrib[i + 4*j] = 0;
}
}
this.outlineMesh.geometry.attributes.strengths.needsUpdate = true;
this.noTileMesh.visible = false;
this.tileGroup.visible = true;
this.textManager.clearText();
this.textManager.genTileTypeGlyphs(tileType);
this.textManager.addTileGlyphs({coords: new Vector2D(0, 0), type: tileType});
}
}
resize() {
const rect = this.canvas.getBoundingClientRect();
const width = rect.width;
const height = rect.height;
this.renderer.setSize(width, height, false);
const aspect = width / height;
if (width >= height) {
this.camera.left = -aspect;
this.camera.right = aspect;
this.camera.top = 1;
this.camera.bottom = -1;
} else {
this.camera.left = -1;
this.camera.right = 1;
this.camera.top = 1 / aspect;
this.camera.bottom = -1 / aspect;
}
this.camera.updateProjectionMatrix();
this.renderUpdate = true;
}
render() {
this.renderer.setClearColor(this.backgroundColor);
this.textManager.update();
this.renderer.render(this.scene, this.camera);
}
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
// maps tiles to unique string to be used as a map key
function tileKey(tile) {
return `${tile.tid},${tile.x},${tile.y}`;
}
export class EventBucket {
constructor() {
this.tiles = []; // array of tiles currently in the bucket
this.indexMap = new Map(); // maps tile keys to indices
}
// add an event for tile into bucket
addEvent(tile) {
const key = tileKey(tile);
// check if event already exists
if (this.indexMap.has(key)) {
return false; // unable to add already-existing tile
}
this.indexMap[key] = this.tiles.length;
this.tiles.push(tiles);
return true;
}
// remove event for tile from bucket
removeEvent(tile) {
const key = tileKey(tile);
// check if event does not exist
if (!this.indexMap.has(key)) {
return false; // unable to remove non-existent event
}
const index = this.indexMap.get(key);
// if removed tile is not last in list, removing it will leave a gap
// so we move the last tile in the list to fill the gap
if (index != this.tiles.length - 1) {
const last = this.tiles.at(-1);
this.tiles[index] = last;
this.indexMap[tileKey(last)] = index;
}
// remove last item in list
this.indexMap.delete(key);
this.tiles.pop();
return true;
}
}
// attachment event for fixed concentrations
export class AttachmentEventBucket extends EventBucket {
constructor(Gmc, concentration) {
super();
this.Gmc = Gmc;
this.concentration = concentration;
this.type = 'attachment'
}
getLogProbability() {
return Math.log2(this.tiles.length * this.concentration) - this.Gmc;
}
}
// detachment event for fixed number of glue bonds
export class DetachmentEventBucket extends EventBucket {
constructor(Gse, strength) {
super();
this.Gse = Gse;
this.strength = strength;
this.type = 'detachment'
}
getLogProbability() {
return Math.log2(this.tiles.length) - this.Gse * this.strength;
}
}
export class GumbelDistribution {
constructor(mu=0, beta=1) {
this.mu = mu;
this.beta = beta;
this.epsilon = 1e-7;
}
CDF(x) {
return Math.exp(-Math.exp(-(x-this.mu) / this.beta));
}
inverseCDF(y) {
return this.mu - this.beta * Math.log( Math.log( 1 / y ) );
}
sample() {
// generate a random number [eps, 1)
// should be (0,1), but we want to avoid division by 0
const y = Math.random() * (1 - this.epsilon) + this.epsilon;
// inverse transform sampling converts uniform distribution to gumbel
return this.inverseCDF(y);
}
}
// simulates a poisson process for kinetic tiles
export class StochasticEventSet {
constructor(Gmc, Gse, kf) {
this.Gmc = Gmc; // attachment rate constant
this.Gse = Gse; // detachment rate constant
this.kf = kf; // forward rate to determine time scale
this.eventBuckets = [];
this.attachmentBuckets = new Map(); // maps concentrations to buckets
this.detachmentBuckets = new Map(); // maps strengths to buckets
this.gumbel = new GumbelDistribution();
}
addAttachmentEvent(tile, concentration) {
// no bucket for that concentration exists so make one
if (!this.attachmentBuckets.has(concentration)) {
const bucket = new AttachmentEventBucket(this.Gmc, concentration);
this.attachmentBuckets.set(concentration, bucket);
this.eventBuckets.push(bucket);
}
const bucket = this.attachmentBuckets.get(concentration);
return bucket.addEvent(tile); // true if added, false if unable
}
addDetachmentEvent(tile, strength) {
// no bucket for that strength exists so make one
if (!this.detachmentBuckets.has(strength)) {
const bucket = new DetachmentEventBucket(this.Gse, strength);
this.detachmentBuckets.set(strength, bucket);
this.eventBuckets.push(bucket);
}
const bucket = this.detachmentBuckets.get(strength);
return bucket.addEvent(tile);
}
removeAttachmentEvent(tile, concentration) {
if (!this.attachmentBuckets.has(concentration))
return false;
const bucket = this.attachmentBuckets.get(concentration);
return bucket.removeEvent(tile);
}
removeDetachmentEvent(tile, strength) {
if (!this.detachmentBuckets.has(strength))
return false;
const bucket = this.detachmentBuckets.get(strength);
return bucket.removeEvent(tile);
}
sample() {
// first choose a bucket using Gumbel raparametrization trick
let selectedBucket;
let maxValue, g, lp;
let rateAny = 0;
for (const bucket of this.eventBuckets) {
if (bucket.tiles.length > 0) {
lp = bucket.getLogProbability();
g = lp + this.gumbel.sample();
rateAny += Math.exp(lp);
if (selectedBucket === undefined or g > maxValue) {
maxValue = g;
selectedBucket = bucket;
}
}
}
// if no bucket was selected, then there are no events to sample
if (selectedBucket === undefined) {
return null;
}
// now sample from selected bucket uniformly
const randIdx = Math.floor(Math.random() * selectedBucket.tiles.length)
const tile = selectedBucket.tiles[randIdx];
// generate dt for event
const dt = -Math.log(1 - Math.random()) / rateAny / this.kf;
return { type: selectedBucket.type, tile: tile, dt: dt };
}
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
import os
from http.server import HTTPServer, CGIHTTPRequestHandler
def main(port):
os.chdir('.')
server_object = HTTPServer(server_address=('', port), RequestHandlerClass=CGIHTTPRequestHandler)
try:
print(f'Web server starting on port {port}.')
server_object.serve_forever()
except KeyboardInterrupt:
server_object.socket.close()
print('Web server exiting.')
if __name__ == '__main__':
main(8000)
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment