User:Pseudosphere
| Pseudosphere | |
|---|---|
![]() | |
| Discord name | Pseudosphere |
| Wiki name | Pseudosphere |
| A.K.A. | Pseudosphere |
| Gender | Unspecified |
| Pronouns | they/them |
| Voice of | Pseudosphere |
| Episodes worked on | Challenge 10: Episodes (indirectly, via Template:Fandom) |
| YouTube | https://www.youtube.com/@user_pseudosphere |
| More information | |
| Timezone | Currently UTC-08:00 |
| Date joined | January 16, 2024 |
| Favorite character | Either 9150625 or [THE ZEITGEIST] |
| Favorite episode | Either Challenge 1: Competitors or Challenge 2: Teams |
| Favorite color | #0094FF |
| Favorite letter | þ |
| Favorite number | 196883 |
| Favorite shape | 24-cell |
| Occupation | Unemployed |
| Status | Extant |
| Death count | 0 |
| Kill count | Unknown |
| Greatest fear | Forgetting |
| First appearance | Rotating CSS Tesseract |
| Created by | Pseudosphere |
| Voiced by | Pseudosphere |
| Favorite minecraft block | Six-sided Piston |
| Preferred minecraft tool order | Bow, Sword, Fortune Pickaxe, Silk Touch Pickaxe, Food |
| Efficiency | Ⅴ |
| Daily sleep | Indeterminate |
| Orientation | West |
| ― | ◻︎ | ✕ |
| 100% | Windows (CRLF) | UTF-8 |
- WC2 Youtube playlist: https://www.youtube.com/playlist?list=PLZDfUzxeXG73cEbN6TwTQOHyJvhvUVhUB
- Girl Host remade for DOS: general‑3
Pages (or parts of pages) I made which are actually good, or took some time/effort to make
- Rotating CSS Tesseract
- Other shapes
- Hyperrotating CSS Order-5 Square Tiling but it's actually muscle man getting dragged through a forest orbifolded by the (2,4,5) triangle group
- The Cycle of Life
- Notepad (old version)
- Brainfuck (no longer works unless graphs get fixed)
- Make your own kaleidoscope
- /dev
- The Wiki Camp/Main Page
- Nether Portal
- Nim
- Balanced ternary
- Φιnary
- Calculator 2.0
- Notakto
- Discord/general
- /
- /home
- ℝ²
- ℘ (the formula took a lot of math to derive; it's the ℘ for Λ=ℤ)
- Game of Life
- Amiga
- Infinite matter generator
- Windows 98
- Windows 7
- Voting
- Title Screen
- O (group)
- Squircle
- Connect Four
- XHTML
- Clock 2.0
- Windows 3.1
- Webdriver Torso
- Rule 150
- 5a/Timer (I made just the timer part)
- 3-sphere
- What beats rock?
- Rotating SVG Cube
- Okinchest
- Okinchess
- Rule 110
- Dwarf Fortress
- DVD in a triangle
- C_(programming_language)#Example_Program
- Exterior
- Text Mode
- Rotating CSS Cube but every line is a Rotating CSS Square
- Rotating CSS Square but every point is a Rotating CSS Line Segment
- Smell#Computability
- Acid1
- Teapot
- Baked fluid simulation (I made the talk page; it may cause computer problems.)
- ASCII Maze
- 10 PRINT CHR$(205.5+RND(1)); : GOTO 10
- Yoyle Building
- Chomp
- Program Manager
Templates
- Template:Tesseract CSS
- Template:Tesseract
- Template:Mono Dark
- Template:Windows 3.1
- Template:Select
- Template:CDD
- Template:Discord reply
- Template:Discord quote
- Template:Discord thread
- Template:Discord codeblock
- Template:Discord edited
- Template:Discord pfp
- Template:Drag CSS
- Template:Dimensional
- Template:Chrome sheen
- Template:Random page title
- Template:Random page link
- Template:Discord divider
- Template:Content only
- Template:Cubemap
- Template:Windows 98
- Template:Windows 7
- Template:VR Cubemap
- Template:Fandom
- Template:MCText
- Template:WBR
- Template:Text Cuboid
- Template:Disputedly imaginary number
- Template:Transclude guard
- Template:Unique number
- Template:Text Mode
- Template:Philosophical argument
- Template:House of Leaves
- Template:Windows Standard
- Template:CSS nonsense
- Template:Metro app
- Template:CSSCountdownClock
- Template:Random float
- Template:Random integer
- Template:Image macro
- Template:HSL2RGB vardefine
Scripts I made for pages
Licensing
- Anyone can use or modify these scripts for whatever, except for evil doings.
- Anyone can distribute any of these scripts or derivative works thereof, as long as they specify which of my scripts was used or modified, and link back to their source.
- These scripts can also be relicensed under any GPL-compatible license, as long as line 2 is still obeyed.
THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL I BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Bad Coding Practices Warning
Unfortunately, I usually don't comment my code. I might fix this at some point...
Tesseract CSS generator
#!/bin/python3
from math import tau, cos, sin
#Transform of v-w plane for w=1
# v w
#|A -B*100|
#|nC/100 -nD+n+1|
def S(x):
y = int(x)
if x == y:
return str(y)
r = str(x)
if r.find("e") != -1:
return "0"
return r
#def genTransform(theta, n):
# c = cos(theta)
# s = sin(theta)
# return ("transform:matrix3d(", S(c), ",0,0,", S(n * s * 0.01), ",0,1,0,0,0,0,1,0,", S(s * 100), ",0,0,", S(n - n * c + 1), ");")
def genTransform2(theta, n, A, B, C, D):
c = cos(theta)
s = sin(theta)
return ("transform:matrix3d(", S(c), ",0,0,", S(n * s * 0.01), ",0,", A, ",", C, ",0,0,", B, ",", D, ",0,", S(s * 100), ",0,0,", S(n - n * c + 1), ");")
#for n in range(64):
# k = n / 64
# print(k * 100, "%{", sep="")
# print(*genTransform(k * tau, 0.5), "}", sep="")
def genTransforms(name, offset, A, B, C, D):
print("@keyframes ", name, "{100%,", sep="", end="")
for n in range(256):
k = n / 256
print(S(k * 100), "%{", *genTransform2((k + offset) * tau, 0.5, A, B, C, D), "}", sep="", end="")
print("\n}", end="")
genTransforms("cell-front", 0, "1", "0", "0", "1")
genTransforms("cell-right", 0.25, "0", "1", "-1", "0")
genTransforms("cell-back", 0.5, "-1", "0", "0", "-1")
genTransforms("cell-left", 0.75, "0", "-1", "1", "0")
Brainfuck Rot13 Demo
----------[
[++++++++++<<,.----------] get str
>>[>>]<< go to start
[
---------------------------------------------------- to position plus 13
>++++++++++++++++++++++++++< d = 26
[>->+<[>]>[<+>-]<<[<]>-] modulo
>[-] clear junk
>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.[-] print character & clear cell
<<<< next char
]
++++++++++.---------- newline
----------]
Φιnary animation generator
#!/bin/python3
s="""0000000.000000
0000001.000000
0000010.010000
0000100.010000
0000101.010000
0001000.100100
0001010.000100
0010000.000100
0010001.000100
0010010.010100
0010100.010100
0010101.010100
0100000.101001
0100001.101001
0100100.001001
0100101.001001
0101000.100001
0101010.000001
1000000.000001
1000001.000001
1000010.010001
1000100.010001
1000101.010001
1001000.100101
1001010.000101
1010000.000101
1010001.000101
1010010.010101
1010100.010101
1010101.010101""".replace(".", "").split("\n")
for n in range(len(s[0])):
z.clear()
o.clear()
print("@keyframes flippyphi", n, " {", sep="")
for k in range(len(s)):
if s[k][n] == "1":
o.append(k * 100 / len(s))
else:
z.append(k * 100 / len(s))
print(*z, sep="%,", end="%,100% {height: 4px;}\n")
print(*o, sep="%,", end="% {height: 16px;}\n}\n")
Nim generator
#!/bin/python3
turns = 8
firstturn = turns - 1
print(end="<p class=\"nurpons\">")
for n in range(turns):
k = n * 4
print("<span class=\"mw-collapsible\" id=\"mw-customcollapsible-nerpyblock", n, "\">[[File:Nerpawhite.png|64px|link=]]<span class=\"mw-collapsible\" id=\"mw-customcollapsible-nerpy", k + 1, "\">[[File:Nerpawhite.png|64px|link=]]</span><span class=\"mw-collapsible\" id=\"mw-customcollapsible-nerpy", k + 2, "\">[[File:Nerpawhite.png|64px|link=]]</span><span class=\"mw-collapsible\" id=\"mw-customcollapsible-nerpy", k + 3, end="\">[[File:Nerpawhite.png|64px|link=]]</span></span>", sep="")
print("</p>")
print(end="<p class=\"nimbuttons\">")
for n in range(turns):
k = n * 4
print(end="<span class=\"mw-collapsible")
if n != firstturn:
print(end=" mw-collapsed")
print("\" id=\"mw-customcollapsible-turn", n, "\"><span class=\"mw-collapsible mw-collapsed nimbutton mw-customtoggle-nim", k + 1, " mw-customtoggle-nerpy", k + 1, "\" id=\"mw-customcollapsible-nim", k + 1, "\">Remove one</span><span class=\"mw-collapsible mw-collapsed nimbutton mw-customtoggle-nim", k + 1, " mw-customtoggle-nim", k + 2, " mw-customtoggle-nerpy", k + 2, "\" id=\"mw-customcollapsible-nim", k + 2, "\">Remove one</span><span class=\"mw-collapsible nimbutton mw-customtoggle-nim", k + 2, " mw-customtoggle-nim", k + 3, " mw-customtoggle-nerpy", k + 3, " mw-customtoggle-endturn", n, "\" id=\"mw-customcollapsible-nim", k + 3, end="\">Remove one</span><span class=\"nobutton\">Remove one</span></span>", sep="")
print("<span class=\"nobutton\">Remove one</span></p>")
print(end="<p class=\"nimbuttons\">")
for n in range(turns):
print("<span class=\"mw-collapsible mw-collapsed nimbutton mw-customtoggle-endturn", n, end="", sep="")
if n != 0:
print(" mw-customtoggle-turn", n - 1, end="", sep="")
else:
print(end=" mw-customtoggle-loser")
print(" mw-customtoggle-turn", n, " mw-customtoggle-nerpyblock", n, "\" id=\"mw-customcollapsible-endturn", n, end="\">End turn</span>", sep="")
print("<span class=\"nobutton\">End turn</span></p>\n<p style=\"font-size: 500%; font-weight: bold; text-align: center;\" class=\"mw-collapsible mw-collapsed\" id=\"mw-customcollapsible-loser\">YOU LOSE</p>")
mwcollapse.py
A python module for converting finite-state machines into mw-collapsible spaghetti. Works best with tree-like systems; is very inefficient for highly "symmetric" FSMs, since the output size is proportional to the number of state transitions.
class StateNode:
__slots__ = "state", "transitions"
def __init__(self, state, transitions=None):
self.state = tuple(state)
self.transitions = {} if transitions == None else transitions
def __call__(self, var):
return self.state[var]
def __len__(self):
return len(self.transitions)
def __length_hint__(self):
return len(self.transitions)
def __getitem__(self, key):
return self.transitions[key]
def __setitem__(self, key, value):
self.transitions[key] = value
def __delitem__(self, key):
del self.transitions[key]
def __iter__(self):
return iter(self.transitions)
def __reversed__(self):
return reversed(self.transitions)
def __contains__(self, item):
return item in self.transitions
class StateMachine:
__slots__ = "states"
def __init__(self, *states):
self.states = states
def __repr__(self):
return f"<StateMachine object of {len(self.states)} states>"
def __bool__(self):
return bool(self.states)
def __len__(self):
return len(self.states)
def __length_hint__(self):
return len(self.states)
def __getitem__(self, key):
return self.states[key]
def __iter__(self):
return iter(self.states)
def __reversed__(self):
return reversed(self.states)
def __contains__(self, item):
return item in self.states
def index(self, value):
return self.states.index(value)
class ElementContainer:
"""An Element-like sequence of Element-like objects."""
__slots__ = "_children", "_parent"
def __init__(self, *children):
self._children = children
self._parent = None
for c in children:
if isinstance(c, ElementContainer):
c._parent = self
def __str__(self):
return "".join(str(c) for c in self._children)
def compile(self, identifier, statemachine):
for child in self._children:
if isinstance(child, ElementContainer):
child.compile(identifier, statemachine)
def visible(self, state):
return self._parent == None or self._parent.visible(state)
class Element(ElementContainer):
"""An HTML element"""
__slots__ = "_attributes", "_children", "name", "_parent"
@staticmethod
def _gentag(l, name, attributes, children):
l.append("<")
l.append(name)
for k in attributes:
l.append(" ")
l.append(k)
l.append("=\"")
l.append(attributes[k].replace("&", "&").replace('"', """))
l.append("\"")
l.append(">")
l.extend(str(c) for c in children)
l.append("</")
l.append(name)
l.append(">")
def __init__(self, name, *children, attributes=None):
super().__init__(*children)
self._attributes = {} if attributes == None else attributes.copy()
self.name = name
def __str__(self):
l = []
self._gentag(l, self.name, self._attributes, self._children)
return "".join(l)
class Toggleable(Element):
"""An mw-collapsible HTML element; might still be visible when collapsed.
var = index into a boolean tuple of collapsible states;
should not be shared with other elements."""
__slots__ = "var"
def __init__(self, name, var, *children, attributes=None):
super().__init__(name, *children, attributes=attributes)
self.var = var
def compile(self, identifier, statemachine):
self._attributes["id"] = f"mw-customcollapsible-{identifier}-{self.var}"
self._attributes["class"] = self._attributes["class"] + (" mw-collapsible" if statemachine[0](self.var) else " mw-collapsible mw-collapsed") if "class" in self._attributes else ("mw-collapsible" if statemachine[0](self.var) else "mw-collapsible mw-collapsed")
super().compile(identifier, statemachine)
class Collapsible(Toggleable):
"""An mw-collapsible HTML element; should always be hidden while collapsed.
var = index into a boolean tuple of collapsible states;
should not be shared with other elements."""
def visible(self, state):
return state(self._var) and super().visible(state)
class Trigger(Element):
"""A sequence of mw-customtoggle HTML elements."""
__slots__ = "event", "_identifier", "_toggles"
def __init__(self, name, event, content="", attributes=None):
super().__init__(name, content, attributes=attributes)
self.event = event
def __str__(self):
hasclass = "class" in self._attributes
l = []
for i, toggle in enumerate(self._toggles):
if toggle != None:
attributes = self._attributes.copy()
attributes["id"] = f"mw-customcollapsible-{self._identifier}-t{i}-{self.event}"
attributes["class"] = " ".join((attributes["class"], *toggle) if hasclass else toggle)
self._gentag(l, self.name, attributes, self._children)
return "".join(l)
def compile(self, identifier, statemachine):
self._identifier = identifier
self._toggles = tuple(self._gentoggle(statemachine, state, i) for i, state in enumerate(statemachine))
def _gentoggle(self, states, state, index):
if self.event in state and self.visible(state):
s = {"mw-collapsible"}
if index != 0:
s.add("mw-collapsed")
tstate = state[self.event]
if state != tstate:
s.update(f"mw-customtoggle-{self._identifier}-{n}" for n in range(len(state.state)) if state(n) != tstate(n))
s.update(f"mw-customtoggle-{self._identifier}-t{index}-{event}" for event in state)
s.update(f"mw-customtoggle-{self._identifier}-t{states.index(tstate)}-{event}" for event in tstate)
else:
s.add("mw-redundanttoggle")
return s
return None
def _genNode(transitions, d, l, transition, stategen, s):
if s not in d:
node = StateNode(stategen(s))
d[s] = node
l.append(node)
for t in transitions:
newstate = transition(s, t)
if None != newstate:
node[t] = _genNode(transitions, d, l, transition, stategen, newstate)
return node
return d[s]
def genStateMachine(transitions, transition, stategen, initial):
"""Generates a state machine from a transition function.
transitions is an iterable of transition names (the inputs to the state machine).
transition is a function accepting a state (which can be any hashable object) and a transition name;
it returns a new state deterministically and without side effects, or None if the transition name is not applicable for this state.
stategen converts a state to an iterable of boolean values representing the states of collapsibles.
initial is the initial state of the machine."""
l = []
_genNode(transitions, {}, l, transition, stategen, initial)
return StateMachine(*l)
def collapseTrigger(name, event, var, content="", attributes=None):
"""Convenience function to generate a Trigger and Collapsible which can substitute each other."""
return ElementContainer(Trigger(name, event, content, attributes=attributes), Collapsible(name, var, content, attributes=attributes))
def example():
"""An example function generating a simple counter."""
# <!--HTML pseudocode for this example-->
#
# <initial>
# let $COUNTER = 0;
# </initial>
#
# <transition id="increment">
# if $COUNTER != 99 then increment $COUNTER;
# </transition>
# <transition id="decrement">
# if $COUNTER != 0 then decrement $COUNTER;
# </transition>
#
# <stategen>
# display collapsibles with id == ((tens digit of $COUNTER) + 10) or id == (ones digit of $COUNTER);
# </stategen>
#
# <span collapsible-id="10"></span><span collapsible-id="11">1</span><!--...--><span collapsible-id="19">9</span><span collapsible-id="0">0</span><!--...--><span collapsible-id="9">9</span><br/>
# <span trigger-id="increment" style="background-color:#000;border:1px solid;color:#0F0;">+</span><br/>
# <span trigger-id="decrement" style="background-color:#000;border:1px solid;color:red;">-</span>
def transition(state, transition):
if transition == "increment":
return None if state == 99 else state + 1
return None if state == 0 else state - 1
def stategen(state):
l = [n == state % 10 for n in range(10)]
l.extend(n == state // 10 for n in range(10))
return tuple(l)
stateMachine = genStateMachine(("increment", "decrement"), transition, stategen, 0)
elements = [Collapsible("span", 10, "")]
elements.extend(Collapsible("span", n + 10, str(n)) for n in range(1, 10))
elements.extend(Collapsible("span", n, str(n)) for n in range(10))
elements.append("<br/>\n")
elements.append(Trigger("span", "increment", "+", attributes={"style": "background-color:#000;border:1px solid;color:#0F0;"}))
elements.append("<br/>\n")
elements.append(Trigger("span", "decrement", "-", attributes={"style": "background-color:#000;border:1px solid;color:red;"}))
elementContainer = ElementContainer(*elements)
elementContainer.compile("counter", stateMachine)
print(elementContainer)
Calculator 2.0 generator
#!/bin/python3
import mwcollapse
def transition(state, transition):
if transition == "AC" and state[0] != -1:
return (-1, None, -1)
elif transition == "equ":
if state[2] != -1:
if state[1] == "add":
return ((state[0] + state[2]) % 10, None, -1)
if state[1] == "sub":
return ((state[0] - state[2]) % 10, None, -1)
if state[1] == "mul":
return (state[0] * state[2] % 10, None, -1)
return (state[0] // state[2] % 10, None, -1)
elif transition in "0123456789":
if state[0] == -1:
return (int(transition), None, -1)
if state[1] != None and (state[1] != "div" or transition != "0") and state[2] == -1:
return (state[0], state[1], int(transition))
elif transition in ("add", "sub", "mul", "div") and state[1] == None and state[2] == -1:
return (0 if state[0] == -1 else state[0], transition, -1)
return None
def stategen(state):
l = [n == state[0] for n in range(-1, 10)]
l.extend(s == state[1] for s in (None, "add", "sub", "mul", "div"))
l.extend(n == state[2] for n in range(-1, 10))
digits = state[0] != -1 and (state[1] == None or state[2] != -1)
ops = state[1] != None
l.extend(digits for n in range(10))
l.extend(ops for n in range(4))
l.append(state[0] == -1)
l.append(state[2] == -1)
return tuple(l)
table = mwcollapse.Element("table", '<tr><th colspan="4"><span class="display">', *(mwcollapse.Collapsible("span", i, v) for i, v in enumerate(" 0123456789 +-*/ 0123456789")), "</span></th></tr><tr>", *(mwcollapse.Element("td", mwcollapse.collapseTrigger("span", str(n), n + 27, str(n))) for n in range(7, 10)), "<td>", mwcollapse.collapseTrigger("span", "add", 37, "+", attributes={"class": "op"}), "</td></tr><tr>", *(mwcollapse.Element("td", mwcollapse.collapseTrigger("span", str(n), n + 27, str(n))) for n in range(4, 7)), "<td>", mwcollapse.collapseTrigger("span", "sub", 38, "-", attributes={"class": "op"}), "</td></tr><tr>", *(mwcollapse.Element("td", mwcollapse.collapseTrigger("span", str(n), n + 27, str(n))) for n in range(1, 4)), "<td>", mwcollapse.collapseTrigger("span", "mul", 39, "×", attributes={"class": "op"}), "</td></tr><tr><td>", mwcollapse.collapseTrigger("span", "AC", 41, "AC", attributes={"class": "AC"}), "</td><td>", mwcollapse.collapseTrigger("span", "0", 27, "0"), "</td><td>", mwcollapse.collapseTrigger("span", "equ", 42, "=", attributes={"class": "equ"}), "</td><td>", mwcollapse.collapseTrigger("span", "div", 40, "÷", attributes={"class": "op"}), "</td></tr>", attributes={"class": "calculator"})
table.compile("calc", mwcollapse.genStateMachine(("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "add", "sub", "mul", "div", "equ", "AC"), transition, stategen, (-1, None, -1)))
print(table)
Notakto generator
#!/bin/python3
import mwcollapse
boot = (49, 82, 148, 280, 49, 82, 148, 280)
class State:
__slots__ = "state", "bools", "transition"
def __init__(self, state, transition=None):
self.state = state
self.bools = tuple((state & 1 << n) != 0 for n in range(9) if n != 4)
self.transition = transition
def __eq__(self, other):
return self.state == other.state
def __hash__(self):
return self.state
def __len__(self):
return self.bools.count(True)
def __getitem__(self, key):
return True if key == None or key == ... else self.bools[key]
def gameover(self):
return (self.bools[0] and self.bools[1] and self.bools[2]) or (self.bools[0] and self.bools[3] and self.bools[5]) or (self.bools[0] and self.bools[7]) or (self.bools[1] and self.bools[6]) or (self.bools[2] and self.bools[5]) or (self.bools[2] and self.bools[4] and self.bools[7]) or (self.bools[3] and self.bools[4]) or (self.bools[5] and self.bools[6] and self.bools[7])
varToPos = lambda n: n if n < 4 else n + 1
posToVar = lambda n: n if n < 4 else n - 1
def transition(state, transition):
if not state[0].gameover():
if not state[1]:
if transition == None:
if len(state[0]) == 1:
return State(boot[state[0].transition]), True, False
for n in range(9):
if not state[0][n]:
s = State(state[0].state | 1 << varToPos(n))
if not s.gameover():
return s, True, False
elif not state[0][transition]:
s = State(state[0].state | 1 << varToPos(transition), transition)
return s, False, s.gameover()
elif transition == ...:
return (State(0b000010000), True, False)
return None
e = mwcollapse.ElementContainer(
'<p style="text-align: center;">',
mwcollapse.Trigger("span", None, "End turn", attributes={"class": "nimbutton"}),
mwcollapse.Collapsible("span", 8, "End turn", attributes={"class": "nobutton"}),
mwcollapse.Trigger("span", ..., "Try again", attributes={"class": "nimbutton"}),
'</p><table class="tictactoe">',
*(mwcollapse.Element("tr",
*(mwcollapse.Element("td",
'<span class="cell">X</span>' if k == 4 else mwcollapse.ElementContainer(
mwcollapse.Trigger("span", posToVar(k), attributes={"class": "cell"}),
mwcollapse.Collapsible("span", posToVar(k), "X", attributes={"class": "cell"})
),
) for k in range(n, n + 3))
) for n in (0, 3, 6)),
"</table>",
mwcollapse.Collapsible("p", 9, "YOU LOSE", attributes={"style": "font-size: 500%; font-weight: bold; text-align: center;"})
)
e.compile("notakto", mwcollapse.genStateMachine((*range(8), None, ...), transition, lambda state: (*state[0].bools, state[1], state[2]), (State(0b000010000), True, False)))
print(e)
Nim (Easy Mode) generator
#!/bin/python3
import random
import mwcollapse
nurpos = 99
def transition(state, transition):
if state[0] != 0:
if state[1] != 0 and transition != 0:
return (state[0] - 1, state[1] - 1)
elif transition == 0 and state[1] != 3:
if state[0] & 3 == 0:
return (state[0] - random.randrange(1, 4), 3)
return (state[0] & -4, 3)
return None
def stategen(state):
return (*(n < state[0] for n in range(nurpos)), state[0] == 0 and state[1] == 3, state[0] == 0 and state[1] != 3)
stateMachine = mwcollapse.genStateMachine((0, 1), transition, stategen, (nurpos, 3))
elementContainer = mwcollapse.ElementContainer('<p class="nurpons">', *(mwcollapse.Collapsible("span", n, "[[File:Nerpawhite.png|64px|link=]]") for n in range(nurpos)), '</p>\n<p class="nimbuttons">', mwcollapse.Trigger("span", 1, "Remove one", attributes={"class": "nimbutton"}), '<span class="nobutton">Remove one</span></p>\n<p class="nimbuttons">', mwcollapse.Trigger("span", 0, "End turn", attributes={"class": "nimbutton"}), '<span class="nobutton">End turn</span></p>', mwcollapse.Collapsible("p", nurpos, "YOU LOSE", attributes={"class": "bigtexty"}), mwcollapse.Collapsible("p", nurpos + 1, "YOU [[Win|WIN]]", attributes={"class": "bigtexty"}))
elementContainer.compile("nim", stateMachine)
print(elementContainer)
Nim (Pedantic Mode) generator
#!/bin/python3
import math
import mwcollapse
import warnings
class nimstate:
__slots__ = "piles", "prev"
def __init__(self, piles, prev):
self.piles = tuple(piles)
self.prev = prev
def __eq__(self, other):
return False if other == None else self.piles == other.piles and self.prev == other.prev
def __hash__(self):
return hash(self.piles) ^ hash(self.prev)
def parity(iterable):
p = 0
for n in iterable:
p ^= n
return p
nurpos = (2, 4, 3, 5)
offsets = tuple(sum(nurpos[0:n]) for n in range(len(nurpos)))
count = offsets[-1] + nurpos[-1]
def transition(state, transition):
l = list(state.piles)
if transition != None:
if (state.prev == None or transition == state.prev) and l[transition] != 0:
l[transition] -= 1
return nimstate(l, transition)
elif state.prev != None and max(l) != 0:
for n in range(1, max(nurpos) + 1):
for i in range(len(nurpos)):
l[i] -= n
if l[i] >= 0 and parity(l) == 0:
return nimstate(l, None)
l = list(state.piles)
warnings.warn(f"{state.piles}, {state.prev} : {transition}")
def stategen(state):
l = []
for i, n in enumerate(state.piles):
l.extend(k < n for k in range(nurpos[i]))
l.append(max(state.piles) == 0)
return l
stateMachine = mwcollapse.genStateMachine((*range(len(nurpos)), None), transition, stategen, nimstate(nurpos, None))
elementContainer = mwcollapse.ElementContainer(
*(mwcollapse.Element("div",
'<p class="nurpons">',
*(mwcollapse.Collapsible("span", k, "[[File:Nerpawhite.png|64px|link=]]") for k in range(o, o + nurpos[i])),
'</p>\n<p class="nimbuttons">',
mwcollapse.Trigger("span", i, "Remove one", attributes={"class": "nimbutton"}),
'<span class="nobutton">Remove one</span>',
"</p>\n", attributes={"class": "pile"}) for i, o in enumerate(offsets)),
'<p class="nimbuttons">',
mwcollapse.Trigger("span", None, "End turn", attributes={"class": "nimbutton"}),
'<span class="nobutton">End turn</span>',
"</p>\n",
mwcollapse.Collapsible("p", count, "YOU LOSE", attributes={"class": "bigtexty"}))
elementContainer.compile("nim", stateMachine)
print(elementContainer)
radio.c
This is actually the first program I made for the wiki, back in 2023 before I made an account. It's a C program because I hadn't yet gotten back into making Python scripts.
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifdef WHITESPACE
#define LIVECONST_DEFAULT "background-color: red !important;"
#define DEAD_DEFAULT "background-color: #300;"
#define LIVE_DEFAULT "background-color: red;"
#define STR_LIVE "\n.%s%s {\n\t%s\n}"
#define SEP fputs(", ", stdout)
#define STR_100 ", 100%"
#define STR_A "\n.%s%s {\n\tanimation: %s step-end infinite %s%s;\n}\n@keyframes %s%s {\n\t"
#else
#define LIVECONST_DEFAULT "background-color:red!important"
#define DEAD_DEFAULT "background-color:#300"
#define LIVE_DEFAULT "background-color:red"
#define STR_LIVE ".%s%s{%s}"
#define SEP putchar(',')
#define STR_100 ",100%"
#define STR_A ".%s%s{animation:%s step-end infinite %s%s}@keyframes %s%s{"
#endif
typedef struct link {
struct link* next;
unsigned char data[];
} link_t;
static const char base64[] = {
'-', '0', '1', '2', '3', '4', '5', '6',
'7', '8', '9', 'A', 'B', 'C', 'D', 'E',
'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
'V', 'W', 'X', 'Y', 'Z', '_', 'a', 'b',
'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
};
static link_t start;
static void stdout_err() {
fputs("I/O error on stdout\n", stderr);
exit(EXIT_FAILURE);
}
int main(int argc, char* argv[]) {
const char* liveconst = LIVECONST_DEFAULT;
const char* deadprop = DEAD_DEFAULT;
const char* liveprop = LIVE_DEFAULT;
const char* prefix = "X";
const char* time = "1s";
unsigned int framesize = 256;
for (int c; (c = getopt(argc, argv, "L:c:d:l:o:p:s:t:")) != -1;) switch ((char)c) {
case 'L':
liveconst = optarg;
continue;
case 'd':
deadprop = optarg;
continue;
case 'l':
liveprop = optarg;
continue;
case 'o':
if (freopen(optarg, "wb", stdout) != NULL) continue;
perror("Could not create/open output file");
return EXIT_FAILURE;
case 'p':
prefix = optarg;
continue;
case 's':
framesize = atoi(optarg);
if (framesize && framesize <= 65536) continue;
fprintf(stderr, "Frame size must be in range [1,65536], but got \"%s\"\n", optarg);
return EXIT_FAILURE;
case 't':
time = optarg;
}
if (optind < argc && freopen(argv[optind], "r", stdin) == NULL) {
perror("Could not open input file");
return EXIT_FAILURE;
}
size_t len = strlen(deadprop);
#ifdef WHITESPACE
char deadstr[len + 11];
deadstr[0] = ' ';
deadstr[1] = '{';
deadstr[2] = '\n';
deadstr[3] = '\t';
deadstr[4] = '\t';
memcpy(deadstr + 5, deadprop, len);
deadstr[len + 5] = '\n';
deadstr[len + 6] = '\t';
deadstr[len + 7] = '}';
deadstr[len + 8] = '\n';
deadstr[len + 9] = '\t';
deadstr[len + 10] = 0;
#else
char deadstr[len + 3];
deadstr[0] = '{';
memcpy(deadstr + 1, deadprop, len);
deadstr[len + 1] = '}';
deadstr[len + 2] = 0;
#endif
len = strlen(liveprop);
#ifdef WHITESPACE
char livestr[len + 10];
livestr[0] = ' ';
livestr[1] = '{';
livestr[2] = '\n';
livestr[3] = '\t';
livestr[4] = '\t';
memcpy(livestr + 5, liveprop, len);
livestr[len + 5] = '\n';
livestr[len + 6] = '\t';
livestr[len + 7] = '}';
livestr[len + 8] = '\n';
livestr[len + 9] = 0;
#else
char livestr[len + 3];
livestr[0] = '{';
memcpy(livestr + 1, liveprop, len);
livestr[len + 1] = '}';
livestr[len + 2] = 0;
#endif
link_t* end = &start;
unsigned int n = 0;
unsigned int k = 0;
for (int c; (c = getchar()) != EOF;) {
switch ((char)c) {
default:
continue;
case 'X':
end->data[k++] = 1;
break;
case '.':
end->data[k++] = 0;
}
if (k == framesize) {
k = 0;
if (++n == 65536) {
while ((c = getchar()) != EOF) switch ((char)c) {
case 'X':
case '.':
fputs("Too many frames (>65536)\n", stdout);
return EXIT_FAILURE;
}
break;
}
link_t* l = calloc(1, sizeof(link_t*) + framesize);
if (l == NULL) {
fputs("Could not allocate memory\n", stderr);
return EXIT_FAILURE;
}
end->next = l;
end = l;
}
}
if (ferror(stdin)) {
fputs("I/O error on input", stderr);
return EXIT_FAILURE;
}
if (!n || (n == 1 && !k)) {
fputs("EOF on input before second frame\n", stderr);
return EXIT_FAILURE;
}
if (k) n++;
unsigned int buflen = (n + 1) >> 1;
unsigned short dead_buffer[buflen];
unsigned short live_buffer[buflen];
union {unsigned int block; char bytes[4];} buf;
for (unsigned int i = 0; i != framesize; i++) {
end = &start;
unsigned short depth = 0;
unsigned short dead = 0;
unsigned short live = 0;
unsigned char x;
unsigned char prev = 2;
do {
assert(depth < n);
x = end->data[i];
if (x != prev) {
prev = x;
if (x) {
assert(live < buflen);
live_buffer[live++] = depth;
}
else {
assert(dead < buflen);
dead_buffer[dead++] = depth;
}
}
end = end->next;
} while (++depth != n);
buf.block = 0;
assert((i & 0x003f) < 64);
buf.bytes[0] = base64[i & 0x003f];
if (i & 0xffc0) {
assert((i >> 6 & 0x003f) < 64);
buf.bytes[1] = base64[i >> 6 & 0x003f];
if (i & 0xf000) {
assert(i >> 12 < 64);
buf.bytes[2] = base64[i >> 12];
}
}
if (!dead) {
printf(STR_LIVE, prefix, buf.bytes, liveconst);
continue;
}
if (!live) continue;
if (printf(STR_A, prefix, buf.bytes, time, prefix, buf.bytes, prefix, buf.bytes) < 0) stdout_err();
depth = 0;
goto dead_loop;
do {
if (SEP < 0) stdout_err();
dead_loop:
assert(depth < dead);
if (printf("%.55f%%", (float)(dead_buffer[depth++] * 100) / n) < 0) stdout_err();
} while (depth != dead);
if ((x && fputs(STR_100, stdout) < 0) || fputs(deadstr, stdout)) stdout_err();
depth = 0;
goto live_loop;
do {
if (SEP < 0) stdout_err();
live_loop:
assert(depth < live);
if (printf("%.55f%%", (float)(live_buffer[depth++] * 100) / n) < 0) stdout_err();
} while (depth != live);
if ((!x && fputs(STR_100, stdout) < 0) || fputs(livestr, stdout)) stdout_err();
if (putchar('}') < 0) stdout_err();
}
return EXIT_SUCCESS;
}
Game of Life: ./radio -L "background-color:#000!important" -d "background-color:#FFF" -l "background-color:#000" -o biglife.css -s 1444 -t 16s biglife.txt
Amiga Boing Ball facet CSS generation
import math
w = 0.39018064403225655
sin = 0.3826834323650898
sinx = 0.39018064403225655
def height(y):
n = (y * 2 + 1) / 16 * math.pi
return math.hypot(math.sin(n) * sin, math.cos(n) * sinx)
width = lambda y: math.cos(y / 8 * math.pi) * w
def getCSS(y):
wid = width(y)
n = width(y + 1) / wid
print("clip-path: polygon(", (1 - n) / 2 * 100, "% 0, ", (1 + n) / 2 * 100, "% 0, 100% 100%, 0 100%);\nheight: ", height(y) * 50, "%;\ntransform: rotateX(", y / 16, "turn) ", "translateZ(96px) rotateX(0.03125turn) translateY(-50%);\nwidth: ", wid * 50, "%;", sep="")
O (group) generator
import mwcollapse
d = {
"R": (0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 1),
"L": (0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1),
"U": (1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1),
"D": (1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1)
}
n = 0
def transition(state, transition):
s = d[transition]
return tuple(sum(s[row + k * 4] * state[k + col * 4] for k in range(4)) for col, row in (divmod(n, 4) for n in range(16)))
def stategen(state):
global n
s = tuple(i == n for i in range(24))
print("#mw-customcollapsible-O-", n, ":not(.mw-collapsed) ~ * .cube {\n\ttransform: matrix3d", str(state), ";\n}", sep="")
n += 1
return s
elements = mwcollapse.ElementContainer(
*(mwcollapse.Collapsible("div", i) for i in range(24)),
'<table style="margin: auto"><tr><td colspan="3">',
mwcollapse.Trigger("span", "U", "⮝"),
"</td></tr><tr><td>",
mwcollapse.Trigger("span", "L", "⮜"),
"</td><td>{{Cube|[[File:FRONT.BMP.PNG]]|[[File:BACK.BMP.PNG]]|[[File:RIGHT.BMP.PNG]]|[[File:LEFT.BMP.PNG]]|[[File:TOP.BMP.PNG]]|[[File:BOTTOM.BMP.PNG]]|256}}</td><td>",
mwcollapse.Trigger("span", "R", "⮞"),
'</td></tr><tr><td colspan="3">',
mwcollapse.Trigger("span", "D", "⮟"),
"</td></tr></table>"
)
print("\n====== CSS ======\n")
elements.compile("O", mwcollapse.genStateMachine(d.keys(), transition, stategen, (1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)))
print("\n==== WIKITXT ====\n")
print(elements)
Nim (Pedantic Mode) (Easy Mode) generator
#!/bin/python3
import math
import random
import warnings
import mwcollapse
class nimstate:
__slots__ = "piles", "prev"
def __init__(self, piles, prev):
self.piles = tuple(piles)
self.prev = prev
def __eq__(self, other):
return False if other == None else self.piles == other.piles and self.prev == other.prev
def __hash__(self):
return hash(self.piles) ^ hash(self.prev)
def parity(iterable):
p = 0
for n in iterable:
p ^= n
return p
nurpos = (2, 4, 3, 6, 4)
nurposcount = tuple(range(len(nurpos)))
offsets = tuple(sum(nurpos[0:n]) for n in range(len(nurpos)))
count = offsets[-1] + nurpos[-1]
def transition(state, transition):
l = list(state.piles)
if transition != None:
if (state.prev == None or transition == state.prev) and l[transition] != 0:
l[transition] -= 1
return nimstate(l, transition)
elif state.prev != None:
m = max(l)
if m != 0:
moves = []
#Try to find a winning move
for n in range(1, m + 1):
for i in nurposcount:
l[i] -= n
if l[i] >= 0 and parity(l) == 0:
moves.append(nimstate(l, None))
l = list(state.piles)
if len(moves) != 0:
return random.choice(moves)
#If that fails, try to find a move resulting in no duplicate piles
for n in range(1, m + 1):
for i in nurposcount:
if l[i] >= n:
yes = True
l[i] -= n
for j in nurposcount:
if i != j and l[i] == l[j]:
yes = False
break
if yes:
moves.append(nimstate(l, None))
l = list(state.piles)
if len(moves) != 0:
return random.choice(moves)
#If that fails, just do whatever
n = random.choice([i for i in nurposcount if l[i] != 0])
l[n] -= random.randint(1, l[n])
return nimstate(l, None)
def stategen(state):
l = []
for i, n in enumerate(state.piles):
l.extend(k < n for k in range(nurpos[i]))
l.extend((state.prev == None, state.prev != None) if max(state.piles) == 0 else (False, False))
return l
stateMachine = mwcollapse.genStateMachine((*range(len(nurpos)), None), transition, stategen, nimstate(nurpos, None))
elementContainer = mwcollapse.ElementContainer(
*(mwcollapse.Element("div",
'<p class="nurpons">',
*(mwcollapse.Collapsible("span", k, "[[File:Nerpawhite.png|64px|link=]]") for k in range(o, o + nurpos[i])),
'</p>\n<p class="nimbuttons">',
mwcollapse.Trigger("span", i, "Remove one", attributes={"class": "nimbutton"}),
'<span class="nobutton">Remove one</span>',
"</p>\n", attributes={"class": "pile"}) for i, o in enumerate(offsets)),
'<p class="nimbuttons">',
mwcollapse.Trigger("span", None, "End turn", attributes={"class": "nimbutton"}),
'<span class="nobutton">End turn</span>',
"</p>\n",
mwcollapse.Collapsible("p", count, "YOU LOSE<br/>[https://camp2.rectangle.zone/index.php?title=Nim_(Pedantic_Mode)_(Easy_Mode) TRY AGAIN]", attributes={"class": "bigtexty"}),
mwcollapse.Collapsible("p", count + 1, "YOU [[Nim (Pedantic Mode) (Easy Mode)/Wiki Camp 2 Challenge Crystal|WIN]]", attributes={"class": "bigtexty"}))
elementContainer.compile("nim", stateMachine)
print(elementContainer)
Okinchess generator
import sys
alpha = "abcdefgh"
l = ["""{{#css:
#B table{
border-spacing:0;
height:512px;
width:512px
}
#B td:nth-child(2n+1),#B tr:nth-child(2n) td:nth-child(2n){
background-color:#FFF
}
#B td:nth-child(2n),#B tr:nth-child(2n) td:nth-child(2n+1){
background-color:#000;
}#B td{
padding:0;
vertical-align:top
}.D {
background-color:#0F07;
display:none;
height:48px;
margin:8px;
position:absolute;
width:48px
}.P{
align-items:center;
border-radius:50%;
display:flex;
height:64px;
position:absolute;
transition:0.5s ease translate;
width:64px
}.P:nth-child(2n) img{
filter:invert()
}
""".replace("\n", ""), ",".join(f"#mw-customcollapsible-w{x}:not(.mw-collapsed)~#B .w{x},#mw-customcollapsible-b{x}:not(.mw-collapsed)~#B .b{x}" for x in alpha), "{background-color: #0F07}"]
#Piece moving rules
for y in range(1, 9):
for i, x in enumerate(alpha):
L = []
#Rules for when a piece is in range of a destination
for k, z in enumerate(alpha):
if abs(i - k) < y - 1:
#White move up
L.append(f"#mw-customcollapsible-w{z}P{x}{y - 1}.mw-collapsed~#B #w{z}D{x}{y}")
if i != 0 and abs(i - k - 1) < y - 1:
#White capture right
L.extend(f"#mw-customcollapsible-w{z}P{alpha[i - 1]}{y - 1}.mw-collapsed~#mw-customcollapsible-b{c}P{x}{y}.mw-collapsed~#B #w{z}D{x}{y}R{c}" for l, c in enumerate(alpha) if abs(i - l) < 9 - y)
if i != 7 and abs(i - k + 1) < y - 1:
#White capture left
L.extend(f"#mw-customcollapsible-w{z}P{alpha[i + 1]}{y - 1}.mw-collapsed~#mw-customcollapsible-b{c}P{x}{y}.mw-collapsed~#B #w{z}D{x}{y}L{c}" for l, c in enumerate(alpha) if abs(i - l) < 9 - y)
if abs(i - k) < 8 - y:
#Black move down
L.append(f"#mw-customcollapsible-b{z}P{x}{y + 1}.mw-collapsed~#B #b{z}D{x}{y}")
if i != 0 and abs(i - k - 1) < 8 - y:
#Black capture right
L.extend(f"#mw-customcollapsible-w{c}P{x}{y}.mw-collapsed~#mw-customcollapsible-b{z}P{alpha[i - 1]}{y + 1}.mw-collapsed~#B #b{z}D{x}{y}R{c}" for l, c in enumerate(alpha) if abs(i - l) < y)
if i != 7 and abs(i - k + 1) < 8 - y:
#Black capture left
L.extend(f"#mw-customcollapsible-w{c}P{x}{y}.mw-collapsed~#mw-customcollapsible-b{z}P{alpha[i + 1]}{y + 1}.mw-collapsed~#B #b{z}D{x}{y}L{c}" for l, c in enumerate(alpha) if abs(i - l) < y)
l.append(",".join(L))
l.append("{display:block}")
#Rules for blocking motion
l.append(":is(")
l.append(",".join([f"#mw-customcollapsible-w{z}C:not(.mw-collapsed)~#mw-customcollapsible-w{z}P{x}{y}.mw-collapsed" for k, z in enumerate(alpha) if abs(i - k) < y] + [f"#mw-customcollapsible-b{z}C:not(.mw-collapsed)~#mw-customcollapsible-b{z}P{x}{y}.mw-collapsed" for k, z in enumerate(alpha) if abs(i - k) < 9 - y]))
l.append(")~#B :is(")
L = [f"#w{z}D{x}{y}" for k, z in enumerate(alpha) if abs(i - k) < y - 1] + [f"#b{z}D{x}{y}" for k, z in enumerate(alpha) if abs(i - k) < 8 - y]
while "" in L:
L.remove("")
l.append(",".join(L))
l.append("){display:none}")
#Piece positioning
for y in range(1, 9):
for i, x in enumerate(alpha):
l.append(",".join([f"#mw-customcollapsible-w{z}P{x}{y}.mw-collapsed~#B .w{z}" for k, z in enumerate(alpha) if abs(i - k) < y] + [f"#mw-customcollapsible-b{z}P{x}{y}.mw-collapsed~#B .b{z}" for k, z in enumerate(alpha) if abs(i - k) < 9 - y]))
l.append(f" {{translate:{i}00% {8 - y}00%}}")
print(sum(len(s) for s in l) - 7, file=sys.stderr)
l.append("}")
#Piece selection & capture memory
l.extend(f"{{{{Multitarget customcollapsible|w{x}|mw-collapsed|display:none !important}}}}{{{{Multitarget customcollapsible|w{x}C||display:none !important}}}}{{{{Multitarget customcollapsible|b{x}|mw-collapsed|display:none !important}}}}{{{{Multitarget customcollapsible|b{x}C||display: none !important}}}}" for x in "abcdefgh")
#Position memory
for y in range(1, 9):
for i, x in enumerate(alpha):
l.extend(f'<div class="mw-collapsible{" mw-collapsed" if y == 1 and x == z else ""}" id="mw-customcollapsible-w{z}P{x}{y}"></div>' for k, z in enumerate(alpha) if abs(i - k) < y)
l.extend(f'<div class="mw-collapsible{" mw-collapsed" if y == 8 and x == z else ""}" id="mw-customcollapsible-b{z}P{x}{y}"></div>' for k, z in enumerate(alpha) if abs(i - k) < 9 - y)
l.append('<div id="B">')
#The nerpas
l.extend(f'<div class="mw-customcollapsible-w{x}C P w{x} mw-customtoggle-w{x}">[[File:Nerpawhite.png|64x64px|link=]]</div><div class="mw-customcollapsible-b{x}C P b{x} mw-customtoggle-b{x}">[[File:Nerpawhite.png|64x64px|link=]]</div>' for x in alpha)
l.append("<table>")
#Moves
for y in range(8, 0, -1):
l.append("<tr>")
for i, x in enumerate(alpha):
l.append("<td>")
for k, z in enumerate(alpha):
d = abs(i - k)
if d < y - 1:
#White move up
l.append(f'<div class="mw-customcollapsible-w{z} mw-customcollapsible-w{z}C D mw-customtoggle-w{z} mw-customtoggle-w{z}P{x}{y - 1} mw-customtoggle-w{z}P{x}{y}" id="w{z}D{x}{y}"></div>')
if i != 0 and abs(i - k - 1) < y - 1:
#White capture right
l.extend(f'<div class="mw-customcollapsible-w{z} mw-customcollapsible-w{z}C mw-customcollapsible-b{c}C D mw-customtoggle-w{z} mw-customtoggle-b{c}C mw-customtoggle-w{z}P{alpha[i - 1]}{y - 1} mw-customtoggle-w{z}P{x}{y}" id="w{z}D{x}{y}R{c}"></div>' for l, c in enumerate(alpha) if abs(i - l) < 9 - y)
if i != 7 and abs(i - k + 1) < y - 1:
#White capture left
l.extend(f'<div class="mw-customcollapsible-w{z} mw-customcollapsible-w{z}C mw-customcollapsible-b{c}C D mw-customtoggle-w{z} mw-customtoggle-b{c}C mw-customtoggle-w{z}P{alpha[i + 1]}{y - 1} mw-customtoggle-w{z}P{x}{y}" id="w{z}D{x}{y}L{c}"></div>' for l, c in enumerate(alpha) if abs(i - l) < 9 - y)
if d < 8 - y:
#Black move down
l.append(f'<div class="mw-customcollapsible-b{z} mw-customcollapsible-b{z}C D mw-customtoggle-b{z} mw-customtoggle-b{z}P{x}{y + 1} mw-customtoggle-b{z}P{x}{y}" id="b{z}D{x}{y}"></div>')
if i != 0 and abs(i - k - 1) < 8 - y:
#Black capture right
l.extend(f'<div class="mw-customcollapsible-b{z} mw-customcollapsible-b{z}C mw-customcollapsible-w{c}C D mw-customtoggle-b{z} mw-customtoggle-w{c}C mw-customtoggle-b{z}P{alpha[i - 1]}{y + 1} mw-customtoggle-b{z}P{x}{y}" id="b{z}D{x}{y}R{c}"></div>' for l, c in enumerate(alpha) if abs(i - l) < y)
if i != 7 and abs(i - k + 1) < 8 - y:
#Black capture left
l.extend(f'<div class="mw-customcollapsible-b{z} mw-customcollapsible-b{z}C mw-customcollapsible-w{c}C D mw-customtoggle-b{z} mw-customtoggle-w{c}C mw-customtoggle-b{z}P{alpha[i + 1]}{y + 1} mw-customtoggle-b{z}P{x}{y}" id="b{z}D{x}{y}L{c}"></div>' for l, c in enumerate(alpha) if abs(i - l) < y)
l.append("</td>")
l.append("</tr>")
l.append("</table></div>[[Category:Minigames]][[Category:Collapsible minigames]][[Category:Pages which use over 10 kilobytes of CSS]][[Category:Pages which use over 100 kilobytes of CSS]][[Category:Pages which use over 500 kilobytes of CSS]][[Category:Two-player games]]")
print(sum(len(s) for s in l), file=sys.stderr)
print("".join(l))
Rule 110 generator
#!/bin/python3
#output is currently at least around 2x larger than it should be, since all triggers are reversible, but mwcollapse can't optimize for that yet
import mwcollapse
rulenum = 110
rule = tuple((1 << n & rulenum) != 0 for n in range(8))
depth = 8
def transition(state, transition):
return tuple(state[n] != (n == transition) for n in range(8))
def stategen(state):
result = list(state)
for n in range(depth - 1):
state = [rule[int(state[k - 1 & 7]) << 2 | int(state[k]) << 1 | int(state[k + 1 & 7])] for k in range(8)]
result.extend(state)
return (not x for x in result)
elementContainer = mwcollapse.ElementContainer(
f"""{{{{#css:
#w-{rulenum} {{
border-spacing: 0;
margin: auto;
}}
#w-{rulenum} span {{
display: inline-block;
height: 100%;
width: 100%;
}}
#w-{rulenum} td {{
background: #FFF;
display: table-cell !important;
height: 64px;
outline: 1px solid #CCC;
width: 64px;
}}
#w-{rulenum} .mw-collapsed {{
background: #000;
}}
}}}}
Click the top cells!""",
mwcollapse.Element("table",
mwcollapse.Element("tr",
*(mwcollapse.Toggleable("td", n, mwcollapse.Trigger("span", n)) for n in range(8))
),
*(mwcollapse.Element("tr",
*(mwcollapse.Toggleable("td", x + y * 8) for x in range(8))
) for y in range(1, depth)),
attributes={"id": "w-110"}),
"[[Category:Rules]][[Category:Math]][[Category:Cellular automata]][[Category:Pages that don't even remotely resemble a Wikipedia article]]"
)
elementContainer.compile("w", mwcollapse.genStateMachine(range(8), transition, stategen, tuple(False for n in range(8))))
print(elementContainer)
STL model to HTML/CSS converter
Used to make Teapot and Baked fluid simulation; has multiple parts.
stltohtml.c
/*
* stltohtml [-c] {unique html id} {container css} {triangle css} {resolution} {scale} [stl files...] > wikitext
*/
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#define FLT "%0.4e"
typedef struct {
float x;
float y;
float z;
} vector;
typedef union {
uint16_t data[25];
struct {
vector normal;
vector vertices[3];
uint16_t attribute;
};
} triangle;
static void etest(int n) {
if (n < 0) {
fputs("Failed to write to output\n", stderr);
exit(EXIT_FAILURE);
}
}
static void eputs(const char* restrict s) {
etest(puts(s));
}
static void eprintf(const char* restrict format, ...) {
va_list args;
va_start(args, format);
etest(vprintf(format, args));
va_end(args);
}
int main(int argc, char* argv[]) {
if (argc < 6) {
fputs("Too few args\n", stderr);
return EXIT_FAILURE;
}
bool cull = 0;
if (argv[1][0] == '-') {
if (argv[1][1] == 'c') {
cull = 1;
argv++;
argc--;
}
else {
fputs("Unknown option\n", stderr);
return EXIT_FAILURE;
}
}
eprintf("{{#css:#%s>div{height:%spx;width:%spx;transform-style:preserve-3d;%s}#%s div div{clip-path:polygon(50%%50%%,100%%50%%,50%%100%%);height:%spx;position:absolute;width:%spx;%s}\n}}<div id=\"%s\">\n", argv[1], argv[4], argv[4], argv[2], argv[1], argv[4], argv[4], argv[3], argv[1]);
double resolution = strtod(argv[4], NULL);
if (resolution == 0) {
fputs("Invalid resolution\n", stderr);
return EXIT_FAILURE;
}
double scale = strtod(argv[5], NULL);
if (scale == 0) {
fputs("Invalid scale\n", stderr);
return EXIT_FAILURE;
}
double rscale = scale * 2 / resolution;
for (unsigned i = 6; i != argc;) {
eputs("<div>");
FILE* infile = fopen(argv[i++], "rb");
if (infile == NULL) {
perror("Could not open file");
return EXIT_FAILURE;
}
uint32_t numtriangles;
{
struct {
uint8_t header[80];
uint32_t numtriangles;
} header;
if (!fread(&header, sizeof header, 1, infile)) {
if (feof(infile)) fputs("Could not read header: unexpected EOF\n", stderr);
else perror("Could not read header");
return EXIT_FAILURE;
}
if (header.header[0] == 's' && header.header[1] == 'o' && header.header[2] == 'l' && header.header[3] == 'i' && header.header[4] == 'd') {
fputs("STL file is in ASCII format (not supported)\n", stderr);
return EXIT_FAILURE;
}
numtriangles = header.numtriangles;
}
triangle t;
for (uint32_t i = 0; i != numtriangles; i++) {
if (!fread(t.data, sizeof t.data, 1, infile)) {
if (feof(infile)) fputs("Could not read triangle: unexpected EOF\n", stderr);
else perror("Could not read triangle");
return EXIT_FAILURE;
}
if (!cull ||
(t.vertices[0].x != t.vertices[1].x || t.vertices[0].x != t.vertices[2].x) &&
(t.vertices[0].y != t.vertices[1].y || t.vertices[0].y != t.vertices[2].y) &&
(t.vertices[0].z != t.vertices[1].z || t.vertices[0].z != t.vertices[2].z)
) eprintf("<div style=\"transform:matrix3d(" FLT "," FLT "," FLT ",0," FLT "," FLT "," FLT ",0,0,0,1,0," FLT "," FLT "," FLT ",1)\"></div>\n",
(t.vertices[1].x - t.vertices[0].x) * rscale, (t.vertices[1].y - t.vertices[0].y) * rscale, (t.vertices[1].z - t.vertices[0].z) * rscale,
(t.vertices[2].x - t.vertices[0].x) * rscale, (t.vertices[2].y - t.vertices[0].y) * rscale, (t.vertices[2].z - t.vertices[0].z) * rscale,
(t.vertices[0].x) * scale, (t.vertices[0].y) * scale, (t.vertices[0].z) * scale
);
}
eputs("</div>");
}
eputs("</div>");
return EXIT_SUCCESS;
}
randcolor.py
#!/bin/python3
import fileinput
import random
def r():
return random.choice("0123456789ABCDEF")
for line in fileinput.input():
print(end=line.replace('e="', f'e="background:#{r()}{r()}{r()}7;').replace("e+", "e").replace("0.", "$").replace(".0000e", "e").replace("000e", "e").replace("00e", "e").replace("0e", "e").replace("e00", "").replace("e0", "e").replace("e-0", "e-").replace("$", "0"))
Makefile
CFLAGS = -O3 -Wall -Wno-parentheses
stltohtml: stltohtml.c
$(CC) $(CFLAGS) --std=c99 $(LDFLAGS) -o $@ $<
teapot.txt: stltohtml randcolor.py teapotend.txt teapot_small.stl
./stltohtml teapot "animation:5s linear perspectiverotatey infinite;margin:256px" "" 256 32 teapot_small.stl | ./randcolor.py | cat - teapotend.txt > $@
fluid.txt: stltohtml randcolor.py fluidend.txt fluid/0.stl fluid/1.stl fluid/2.stl fluid/3.stl fluid/4.stl fluid/5.stl fluid/6.stl fluid/7.stl fluid/8.stl fluid/9.stl fluid/10.stl fluid/11.stl fluid/12.stl fluid/13.stl fluid/14.stl fluid/15.stl fluid/16.stl fluid/17.stl fluid/18.stl fluid/19.stl fluid/20.stl fluid/21.stl fluid/22.stl fluid/23.stl
./stltohtml -c fluid "transform:perspective(600px)rotateX(-24deg)rotateY(24deg);margin-bottom:768px" "" 256 32 fluid/0.stl fluid/1.stl fluid/2.stl fluid/3.stl fluid/4.stl fluid/5.stl fluid/6.stl fluid/7.stl fluid/8.stl fluid/9.stl fluid/10.stl fluid/11.stl fluid/12.stl fluid/13.stl fluid/14.stl fluid/15.stl fluid/16.stl fluid/17.stl fluid/18.stl fluid/19.stl fluid/20.stl fluid/21.stl fluid/22.stl fluid/23.stl | ./randcolor.py | cat - fluidend.txt > $@
teapotend.txt
{{#css:
@keyframes perspectiverotatey {
0% { transform: perspective(600px) rotate3d(0, 0, 1, 0deg); }
100% { transform: perspective(600px) rotate3d(1, 0, 1, 360deg); }
}
}}[[Category:Pages containing a rotating css utah teapot]][[Category:Rotating css polytopes]][[Category:Shapes]]
fluidend.txt
{{#css:
#fluid {
animation: 4s steps(24, end) filmstrip infinite;
position: relative;
}
@keyframes filmstrip {
0% {
bottom: 0;
}
100% {
bottom: 24576px;
}
}
}}
mwlisp
This is probably the most unreadable program I've ever written (excluding intentionally obfuscated ones like nerpa.c).
This Common Lisp program compiles scripts written in "mwlisp", a lisp dialect I created specifically for generating MediaWiki pages.
#!/usr/bin/cl
; X X XXXXX XXXXX
; X X X X X X X
; XXXXX X X X X X
; X X X X X X
; X X X X X X
;
; XXX XXXXX XXXXX
; X X X X X X X
; X X X X X X X
; X X X X X X X
; XXXXX XXXXX X X X
;
; XXXXX X XXXXX
; X X X X X X
; XXXXX X X X X
; X X X X X
; X X XXXXX
(setf *random-state* (make-random-state t))
(defparameter *vars* (list (make-hash-table)))
(defparameter *funs* (make-hash-table))
(defparameter *toplevel-funs* (make-hash-table))
(defparameter *toplevel* nil)
(defun symbol-name-downcase (symbol) (string-downcase (symbol-name symbol)))
(defun namep (name) (and name (symbolp name) (not (eq name t))))
(defun parserp (str) (and (not (zerop (length str))) (eql (char str 0) #\{)))
(defun constexprp (s) (or (not s) (eq s t) (numberp s) (not (find-if (lambda (c) (or (eql c #\{) (eql c #\}))) s))))
(defun join (args &optional sep)
(if args (progn
(if sep (let* ((outlist (list (car args))) (endlist outlist))
(loop for arg in (cdr args) do (setf endlist (cdr (setf (cdr endlist) (list sep arg)))))
(setf args outlist)
))
(apply #'concatenate (cons 'string args))
) "")
)
(defun btolwrap (fun) (lambda (&rest args) (if (apply fun args) 1 0)))
(defun genvarname () (format nil "_mwl~X" (random 4294967296)))
(defun getmwvar (symbol &optional no-error)
(loop with var for vars in *vars* do (if (setf var (gethash symbol vars)) (return-from getmwvar var)))
(if (not no-error) (error "Error: ~A is not a defined variable name" (symbol-name symbol)))
)
(defun setmwvar (symbol value) (if value
(if (namep symbol) (setf (gethash symbol (car *vars*)) value) (error "Error: variable name must be a symbol (other than NIL and T), not ~S" symbol))
(remhash symbol (car *vars*))
) nil)
(defun getmwfun (symbol &optional toplevel)
(if (not (symbolp symbol)) (error "Error: can't call non-symbol: ~S" symbol))
(or (gethash symbol *funs*) (let ((fun (gethash symbol *toplevel-funs*))) (if fun
(if toplevel (list fun) (error "Error: macro ~A can only be expanded at top-level" (symbol-name symbol)))
(error "Error: ~A is not a defined function/macro name" (symbol-name symbol))
)))
)
(defun setmwfun (symbol value) (setf (gethash symbol *funs*) value))
(defmacro defmwmacro (name args &body form) `(setmwfun ',name (list (lambda ,args (block ,name ,@form)))))
(defmacro defmwfun (name args &body form) `(setmwfun ',name (cons (lambda ,args (block ,name ,@form)) t)))
(defmacro defmwtopmacro (name args &body form) `(setf (gethash ',name *toplevel-funs*) (lambda ,args (block ,name ,@form))))
(defmacro deftag (name &optional self-closing)
(if self-closing
`(defmwmacro ,name (&optional attributes) `(tag ,',(make-symbol (concatenate 'string (symbol-name name) "/")) ,attributes))
`(defmwmacro ,name (&optional attributes &rest content) `(tag ,',name ,attributes ,@content))
)
)
(defmacro defparsertag (name &optional self-closing)
(if self-closing
`(defmwmacro ,name () `(tag ,',(make-symbol (concatenate 'string (symbol-name name) "/"))))
`(defmwmacro ,name (&rest content) `(tag ,',name () ,@content))
)
)
(defun getvarname (var)
(and (consp var) (eq (car var) 'var) (or (and (cdr var) (not (cddr var)) (cadr var)) (error "Error: bad var syntax: ~S" var)))
)
(defun push-vars () (setf *vars* (cons (make-hash-table) *vars*)))
(defun pop-vars (&optional fallthrough) (setf *vars* (cdr *vars*)) fallthrough)
(defun decmwvar (name &optional value) (let (var)
(if (and (consp name) (if (cdr name) t (progn (setf name (car name)) nil)))
(progn
(setf var (mweval (cadr name)))
(if (not (stringp var)) (error "Error: bad variable name syntax (cadr must evaluate to string): ~S" name))
(setf name (car name))
)
(setf var (genvarname))
)
(setmwvar name `(var ,var))
(if value `(ssetf ,name ,value))
))
(defun letbody (vars form &optional pre-eval)
(if (not (listp vars)) (error "Error: var list is not a list: ~S" vars))
(setf vars (mapcar (lambda (var) (if (symbolp var) `(,var) var)) vars))
(if pre-eval (setf vars (mapcar (lambda (var) (apply (lambda (name &optional value) (cons name (if value (list (mweval value))))) var)) vars)))
(push-vars)
(let* ((outlist (list 'cat)) (listend outlist))
(loop for var in vars do
(setf var (apply #'decmwvar var))
(if var (setf listend (setf (cdr listend) (list var))))
)
(rplacd listend `((cat ,@form)))
(pop-vars (mweval outlist))
)
)
(defun parserform (name sep args)
(if args (let* ((outlist (list (if (parserp name) "{{ " "{{") name sep)) (endcons (cddr outlist)))
(loop with arg = args while arg do
(setf endcons (cdr (setf (cdr endcons) (list (car arg) "|"))))
(setf arg (cdr arg))
)
(rplaca endcons "}}")
(join outlist)
) (concatenate 'string (if (parserp name) "{{ " "{{") name "}}"))
)
(defun mwsetf (pre name value)
(concatenate 'string pre
(let ((form (mwmacroexpand name))) (if (and (consp form) (cdr form) (not (cddr form)) (stringp (cadr form)) (eq (car form) 'var))
(cadr form)
(error "Error: invalid target for setf: ~S" name)
))
"|" (mweval value) "}}")
)
(defun exprreduce (form) (if (numberp form) (flatten form) (concatenate 'string "(" (if (and (consp form) (not (cddr form)) (eq (car form) '_expr)) (mweval (cadr form)) (mweval form)) ")")))
(defmacro defmwunop (name fun expr) `(defmwmacro ,name (x)
(setf x (mwmacroexpand x))
(if (numberp x)
(apply ,fun (list x))
(list '_expr (concatenate 'string ,expr (exprreduce x)))
)
))
(defmacro defmwbinop (name fun expr &optional r-default) `(defmwmacro ,name ,(if r-default `(l &optional (r ,r-default)) '(l r))
(setf l (mwmacroexpand l))
(setf r (mwmacroexpand r))
(if (and (numberp l) (numberp r))
(apply ,fun (list l r))
(list '_expr (concatenate 'string (exprreduce l) ,expr (exprreduce r)))
)
))
(defmacro defmwassoccomop (name fun expr identity) `(defmwmacro ,name (&rest args)
(setf args (mapcar #'mwmacroexpand args))
(if (every #'numberp args)
(apply ,fun args)
(list '_expr (join (let ((num (apply ,fun (remove-if-not #'numberp args))) (str (mapcar #'exprreduce (remove-if #'numberp args)))) (if (= num ,identity)
str
(cons (flatten num) str)
)) ,expr))
)
))
(defmacro defmwacomop (name fun afun expr invexpr identity) `(defmwmacro ,name (&optional l &rest r)
(setf l (mwmacroexpand l))
(setf r (mapcar #'mwmacroexpand r))
(if l
(let ((args (cons l r))) (if (every #'numberp args)
(apply ,fun args)
(if r
(list '_expr (join (let ((num (remove-if-not #'numberp args)) (str (mapcar #'exprreduce (remove-if #'numberp args)))) (if (numberp l)
(cons (flatten (if (cdr num)
(apply ,fun num)
l
)) str)
(let ((num (apply ,afun (cons ,identity num)))) (if (= num ,identity)
str
(nconc str (list (flatten num)))
))
)) ,expr))
(list '_expr (concatenate 'string ,invexpr (exprreduce l)))
)
))
,identity
)
))
;TODO: add whitespace on right if ends in exactly one '}'
;TODO: make all parser function macros use (parserfun); make all parser function functions use a common function to gen output
(defmwfun param (index &optional default) (let ((start (if (parserp index) "{{{ " "{{{"))) (if default (concatenate 'string start index "|" default "}}}") (concatenate 'string start index "}}}"))))
(defmwfun transclude (title &rest args) (parserform title "|" args))
(defmwfun parserfun (title &rest args) (parserform title ":" args))
(defmwfun link (title &rest args) (concatenate 'string "[[" (join (cons title args) "|") "]]"))
(defmwmacro file (title &rest args) `(link ,(concatenate 'string "File:" title) ,@args))
(defmwmacro category (title) `(link ,(concatenate 'string "Category:" title)))
(defmwmacro ! () `(transclude "!"))
(defmwfun var (name) (concatenate 'string "{{#var:" name "}}"))
(defmwmacro cat (&rest args) (join (mapcar (lambda (x) (mweval x (car *toplevel*))) args)))
(defmwfun join (sep &rest args) (join args sep))
(defmwfun void (&rest form) (if form (join (append '("{{#if:") (mapcar #'mweval form) '("}}"))) ""))
(defmwmacro progn (&rest form) (list* 'cat (cons 'void (butlast form)) (last form)))
(defmwmacro style (&rest styles)
(list* 'join ";" (mapcar (lambda (style)
(if (not (and (consp style) (symbolp (car style)) (cdr style))) (error "Error: bad argument to STYLE: ~S" style))
(list* 'cat (symbol-name-downcase (car style)) ":" (cdr style))
) styles))
)
(defmwmacro setf (name value) (mwsetf "{{#vardefineecho:" name value))
(defmwmacro ssetf (name value) (mwsetf "{{#vardefine:" name value))
(defmwmacro varname (var)
(if (not (symbolp var)) (error "Error: argument to VARNAME must be a symbol"))
(or
(getvarname (getmwvar var t))
(error "Error: variable ~A is not bound to a MediaWiki #var" (symbol-name var))
)
)
(defmwmacro let (vars &rest form) (letbody vars form t))
(defmwmacro let* (vars &rest form) (letbody vars form))
(defmwmacro loop (varname start-value iterations &rest form)
(if (not (symbolp varname)) (error "Error: LOOP variable must be a symbol, not ~S" varname))
(if (not (numberp (setf start-value (mwmacroexpand start-value)))) (setf start-value (mweval start-value)))
(setf iterations (mwmacroexpand iterations))
(if (and (integerp iterations) (or (zerop iterations) (= (abs iterations) 1) (getmwvar '*mwlisp-allow-loop-unrolling* t)))
;loop unrolling
;*mwlisp-allow-loop-unrolling* is assumed true if |iterations| is 0 or 1
(if (zerop iterations)
;no iterations, return nothing
""
(if (numberp start-value) (progn
;iterations is an integer and start-value is a number, so if *mwlisp-allow-loop-unrolling* the entire loop is unrolled, substituting for varname its numerical value within the current iteration
(push-vars)
(loop with down = (if (< iterations 0) (setf iterations (- iterations))) with outlist = (list 'cat) for i to (decf iterations) do
(setmwvar varname (if down (- start-value i) (+ start-value i)))
(nconc outlist (list (mweval `(cat ,@form))))
finally
(pop-vars)
(return-from loop outlist)
)
)
;iterations is an integer but start-value is not a number, so if *mwlisp-allow-loop-unrolling* the entire loop is unrolled, substituting for varname an accumulator variable which is updated each iteration
(loop with down = (if (< iterations 0) (setf iterations (- iterations))) with outlist = (list 'cat) for i to (decf iterations) do
(nconc outlist (copy-list form) (if (/= i iterations) (list `(ssetf ,varname (,(if down '- '+) ,start-value ,i 1)))))
finally
(return-from loop `(let ((,varname ,start-value)) ,outlist))
)
))
;no loop unrolling, default to using {{#loop}}
`(let (,varname) (parserfun "#loop" (varname ,varname) ,(mweval start-value) ,iterations (cat ,@form)))
)
)
(defmwmacro repeat (iterations &rest form)
(setf iterations (mwmacroexpand iterations))
(if (and (integerp iterations) (or (zerop iterations) (= (abs iterations) 1) (getmwvar '*mwlisp-allow-loop-unrolling* t)))
(if (zerop iterations)
""
(loop with outlist = (list 'cat) for i to (1- (abs iterations)) do
(nconc outlist (copy-list form))
finally
(return-from repeat outlist)
)
)
`(parserfun "#loop" ,(genvarname) 0 ,iterations (cat ,@form))
)
)
(defmwmacro exists (name &optional if-value else-value)
(join (nconc (list* "{{#varexists:" (if (namep name)
(let ((var (getmwvar name t))) (or var (return-from exists (if else-value else-value ""))))
(if (and (consp name) (cdr name) (not (cddr name)) (stringp (cadr name)) (eq (car name) 'var))
(cadr name)
(error "Error: invalid target for exists: ~S" name))) (if if-value (list* "|" (mweval if-value) (if else-value (list "|" (mweval else-value)))))) '("}}")))
)
(defmwfun _expr (x) (concatenate 'string "{{#expr:" x "}}"))
(defmwmacro expr (x) `(_expr ,x))
(defmwassoccomop + #'+ "+" 0)
(defmwacomop - #'- #'+ "-" "-" 0)
(defmwassoccomop * #'* "*" 1)
(defmwacomop / #'/ #'* "/" "1/" 1)
(defmwbinop expt #'expt "^")
(defmwunop floor #'floor "floor")
(defmwunop truncate #'truncate "trunc")
(defmwbinop round (lambda (n e)
(setf e (expt 1/10 e))
(* (round n e) e)
) "round" 0)
(defmwbinop rem #'rem "fmod")
(defmwbinop truncrem (lambda (l r) (truncate (rem l r))) "mod")
(defmwbinop = (btolwrap #'=) "=")
(defmwbinop /= (btolwrap #'/=) "!=")
(defmwbinop < (btolwrap #'<) "<")
(defmwbinop > (btolwrap #'>) ">")
(defmwbinop <= (btolwrap #'<=) "<=")
(defmwbinop >= (btolwrap #'>=) ">=")
(defmwunop lnot (lambda (x) (if (zerop x) 1 0)) "not")
(defmwassoccomop land (lambda (&rest args) (if (apply 'notany (list #'zerop args)) 1 0)) "and" 1)
(defmwassoccomop lor (lambda (&rest args) (if (apply 'notevery (list #'zerop args)) 1 0)) "or" 0)
(defmwmacro 1+ (number) `(+ ,number 1))
(defmwmacro 1- (number) `(- ,number 1))
(defmwmacro min (&rest args)
(if (not args) (error "Error: MIN requires at least one argument"))
(setf args (mapcar #'mwmacroexpand args))
(if (every #'numberp args)
(apply #'min args)
(let ((nums (remove-if-not #'numberp args)))
(append '(transclude "min") (if nums (list (apply #'min nums))) (remove-if #'numberp args))
)
)
)
(defmwmacro max (&rest args)
(if (not args) (error "Error: MAX requires at least one argument"))
(setf args (mapcar #'mwmacroexpand args))
(if (every #'numberp args)
(apply #'max args)
(let ((nums (remove-if-not #'numberp args)))
(append '(transclude "max") (if nums (list (apply #'max nums))) (remove-if #'numberp args))
)
)
)
(defmwmacro mif (test &optional (then "") (else "")) (if test then else))
(defmwmacro if (test &optional then else)
(setf test (mweval test))
;TODO: figure out exactly which characters are "blank" according to mediawiki
(if (find-if-not (lambda (c) (find c "
")) test)
;NOTE: parser tags (like <skin> or <choose>) are read as non-empty by {{#if}}, even if they would return nothing (I assume they are only expanded after all parser functions are)
(if (constexprp test)
(or then "")
;(join (nconc (list* "{{#if:" test (if then (list* "|" (mweval then) (if else (list "|" (mweval else)))))) '("}}")))
(list* 'parserfun "#if" test (if (or then else) (list* (if then (mweval then) "") (if else (list (mweval else))))))
)
(if else else "")
)
)
(defmwmacro ifeq (test value &optional then else)
(setf test (mwmacroexpand test))
(setf value (mwmacroexpand value))
(if (and (numberp test) (zerop test)) (progn
(setf test value)
(setf value 0)
))
(if (and (not (numberp test)) (numberp value) (zerop value))
(list* 'parserfun "#ifexpr" (mweval (if (and (consp test) (eq (car test) '_expr)) (cadr test) test)) (if (or then else) (list* (if else (mweval else) "") (if then (list (mweval then))))))
(progn
(setf test (mweval test))
(setf value (mweval value))
(if (and (constexprp test) (constexprp value))
(if (equal test value)
(or then "")
(or else "")
)
(list* 'parserfun "#ifeq" test value (if (or then else) (list* (if then (mweval then) "") (if else (list (mweval else))))))
)
))
)
(defmwmacro lif (test &optional then else) `(ifeq ,test 0 ,else ,then))
(defmwmacro switch (value &rest args)
(setf value (mweval value))
(let ((const (constexprp value)) (outlist (list 'cat "{{#switch:" value)))
(loop with endlist = (cddr outlist) for argl on args do (let ((arg (car argl)))
(if (and (consp arg) (listp (car arg)))
(if (car arg) (loop for case in (mapcar #'mweval (car arg)) do
;TODO: can a case value of "#default" be done in #switch with HTML entities or transclusion?
(if (equal case "#default") (error "Error: \"#default\" case conflicts with MediaWiki #switch syntax"))
(if (and const (setf const (constexprp case)) (equal case value)) (return-from switch `(cat ,@(cdr arg))))
(setf endlist (cdr (setf (cdr endlist) (list "|" case))))
finally
(setf endlist (last (setf (cdr endlist) (cons "=" (copy-list (cdr arg))))))
))
(if (eq arg 'default) (progn
(if const (return-from switch `(cat ,@(cdr argl))))
(rplacd endlist (cons "|" (copy-list (cdr argl))))
(loop-finish)
) (error "Error: invalid case: ~S" arg))
)
))
(nconc outlist '("}}"))
)
)
(defmwmacro tag (name &optional attributes &rest content)
(if (symbolp name) (setf name (symbol-name-downcase name)) (error "Error: name parameter to TAG must be a symbol, not ~S" name))
(let ((closepos (position #\/ name)))
(if closepos (progn
(if (/= (1+ closepos) (length name)) (error "Error: self-closing / does not end TAG name: ~S" name))
(if content (error "Error: self-closing TAG ~S not empty" name))
))
(if (not (listp attributes)) (error "Error: attributes parameter to TAG must be a list, not ~S" attributes))
(join (nconc (list* "<" (if closepos (subseq name 0 closepos) name) (mapcar (lambda (c)
(if (or (not (consp c)) (and (cdr c) (cddr c))) (error "Error: bad TAG attribute: ~S" c))
(apply (lambda (key &optional value)
(if (not (symbolp key)) (error "Error: TAG attribute key must be a symbol, not ~S" key))
;TODO: escape quotes n stuff in value?
(join (list* " " (symbol-name-downcase key) (if value (list "=\"" (mweval value) "\""))))
) c)
) attributes)) (if closepos '("/>") (nconc (list* ">" (mapcar #'mweval content)) (list "</" name ">")))))
)
)
(deftag div)
(deftag p)
(deftag span)
(deftag br t)
(deftag table)
(deftag thead)
(deftag tbody)
(deftag tr)
(deftag td)
(defparsertag noinclude)
(defparsertag includeonly)
(defparsertag onlyinclude)
(defmwmacro skin (skin) (if (stringp skin)
(concatenate 'string "<skin>" skin "</skin>")
(error "Error: argument to SKIN must be a string, not ~S" skin)
))
(defmwmacro templatestyles (src) (if (stringp src)
(concatenate 'string "<templatestyles src=\"" src "\"/>")
(error "Error: argument to TEMPLATESTYLES must be a string, not ~S" src)
))
(defmwmacro quote (arg) (error "Error: lisp quoting not supported") arg)
(defun mwsubst (from to object)
(if (consp object)
(cons (mwsubst from to (car object)) (mwsubst from to (cdr object)))
(if (symbolp object)
(let ((i (position object from))) (if i (nth i to) object))
object))
)
(defmwtopmacro defmacrovar (name value) (setmwvar name value) "")
(defmwtopmacro defvar (name &optional value)
(let ((var `(var ,(genvarname))))
(setmwvar name var)
(if value `(ssetf ,var ,value) "")
)
)
(defmwtopmacro defconstant (name value)
(setf value (mwmacroexpand value t))
(if (consp value) (setf value (mweval value t)))
`(,(if (constexprp value) 'defmacrovar 'defvar) ,name ,value)
)
(defmwtopmacro defmacro (name args expansion)
(if (not (namep name)) (error "Error: macro name must be a symbol (other than NIL and T), not ~S" name))
(if (not (listp args)) (error "Error: macro args must be an argument list, not ~S" name))
(let* ((optional nil) (argnames (mapcan (lambda (arg)
(if (namep arg)
(if (eq arg '&optional) (progn (setf optional t) nil) (list arg))
(if (and (consp arg) (namep (car arg)) (consp (cdr arg)) (not (cddr arg)))
(if optional (list (car arg)) (error "Error: default arg values can only be specified for optional arguments"))
(error "Error: not a valid argument name: ~S" arg)
)
)
) args)))
(eval `(defmwmacro ,name ,(mapcar (lambda (arg)
(if (consp arg)
(list (car arg) `',(cadr arg))
arg
)
) args) (mwsubst ',argnames ,(cons 'list argnames) ',expansion)))
)
"")
(defun flatten (form) (format nil "~A" (if (and (numberp form) (not (integerp form))) (let ((x (floor form))) (if (= x form) x (float form))) form)))
(defun mwmacroexpand (form &optional toplevel)
(setf *toplevel* (cons toplevel *toplevel*))
(let ((r (loop while form do
(if (listp form)
(let ((fun (getmwfun (car form) toplevel))) (if (cdr fun)
;function
(return-from mwmacroexpand form)
;macro
(setf form (apply (car fun) (cdr form)))
))
(return-from mwmacroexpand (if (symbolp form)
(if (eq form t)
t
(getmwvar form)
)
form)))
)))
(setf *toplevel* (cdr *toplevel*))
r
)
)
(defun mweval (form &optional toplevel)
(setf form (mwmacroexpand form toplevel))
(if form (if (eq form t) (error "Error: evaluating T is forbidden")
(if (listp form) (let ((fun (getmwfun (car form))))
(if (cdr fun)
;function
(apply (car fun) (mapcar #'mweval (cdr form)))
;macro
(error "Illegal Parser State: macro wasn't expanded")
)
) (if (stringp form)
form
(flatten form)))
) (error "Error: evaluating NIL is forbidden"))
)
(defun rep () (princ (mweval (read *standard-input* nil '(exit)) t)))
(block main
(defmwfun exit () (return-from main))
(if (interactive-stream-p *standard-input*) (loop
(princ "* ")
(finish-output)
(rep)
(princ #\Newline)
))
(loop (rep))
)
(princ #\Newline)
Yoyle Building mwlisp script
(p ((style "display: none;")) (tag choose ((uncached "")) (tag option () "a") "b" (tag option ())));for some reason the page caches despite using RNG templates
(transclude "Content only" 0)
(p ((style (style (margin "1em") (position "absolute") (left 0)))) "[https://camp2.rectangle.zone/wiki/Yoyle_Building Refresh the page to view another]")
(p ((style (style (margin "1em") (position "absolute") (right 0)))) (link "Main Page"))
(p ((style (style
(margin 0)
(pointer-events "none")
(position "absolute")
(right 0)
(user-select "none")
(z-index -1)
)))
(file "BFDIA YSun.png" "link=")
)
(defmacro random-integer (&optional (l "") r) (mif r (transclude "Random integer" l r) (transclude "Random integer" l)))
(defmacro random-float (&optional (l "") r) (mif r (transclude "Random float" r l) (transclude "Random float" l)))
(defmacro HSL2RGB (r g b h s l) (transclude "HSL2RGB vardefine" (varname r) (varname g) (varname b) h s l))
(defmacro HSL2RGB-defvar (r g b h s l) (cat (defvar r) (defvar g) (defvar b) (HSL2RGB r g b h s l)))
(defmacro rgb (r g b) (cat "rgb(" (join "," r g b) ")"))
(defmacro len (i) (switch i
((0) 120)
((1) 200)
((2) 300)
))
(defconstant edgeMargin 0.01)
(defconstant lightness (random-float 0.2 1))
(defconstant city (- 1 (expt (random-float) 2)))
(defconstant h (+ 0.1 (random-float (* city city 5))))
(defmacrovar wl-gen (random-float (max 0.05 (* h 0.15)) (min 0.25 (* h 2))))
(defconstant w wl-gen)
(defconstant l wl-gen)
(defmacro wxy-gen (l r n) (max (round (* (random-float l r) n)) 1))
(defconstant wx (wxy-gen 18 40 w))
(defconstant wz (wxy-gen 22 26 h))
(defconstant wm (random-float 0.05 0.18))
(defconstant wb (* (/ (random-float 10 100) 255) 0.8))
(defconstant name (lif (lor (> h 0.5) (< (random-float) 0.7))
(let ((maxLength (min (+ (* (floor (* (max w l) 10)) 40) 40) 120)))
(+ (* (random-integer maxLength) 120) (random-integer maxLength))
)
0
))
(defconstant roof (lif (land (> h 0.5) (< (random-float) 0.1))
0
(let ((roofTmp (random-integer 15)))
(lif (lor (land (= roofTmp 8) (< h 0.4)) (land (= roofTmp 7) (< h 0.3)))
(random-integer 2 4)
roofTmp
)
)
))
(defconstant roof2 (random-float))
(HSL2RGB-defvar c-r c-g c-b (random-float 360) (random-float) lightness)
(HSL2RGB-defvar c2-r c2-g c2-b (random-float 360) (random-float) (lif (< lightness 0.45) (random-float 0.8 1) (random-float 0.2)))
(defvar c3-r) (defvar c3-g) (defvar c3-b)
(lif (<= (truncrem roof 9) 1)
(HSL2RGB c3-r c3-g c3-b (random-float 360) (random-float 0.4) (random-float 0.1 1))
(lif (< (random-float) 0.5)
(cat (ssetf c3-r (* c-r 0.6)) (ssetf c3-g (* c-g 0.6)) (ssetf c3-b (* c-b 0.6)))
(HSL2RGB c3-r c3-g c3-b (random-float 360) (random-float 0.1 0.9) (random-float 0.1 0.7))
)
)
(parserfun "#css" (cat "
body, #mw-head {
background: #FAE664;
}
#content {
background: none;
}
.yoyrBuilding {
color: " (rgb c2-r c2-g c2-b) ";
font-family: \"Nimbus Sans Narrow\", \"Nimbus Sans\", Helvetica, helv, sans-serif;
font-size: 32px;
line-height: 0;
overflow: hidden;
text-align: center;
text-wrap: nowrap;
}
.yoyrBuilding td {
background: " (rgb wb wb wb) ";
padding: 0;
}
.yoyrBuilding .yoyrName {
background: #0000;
}
"))
(defconstant door (truncate (1- (rem (+ c-r c-g) 3))))
(defconstant nb (truncate (/ name 120)))
(defconstant ne (truncrem name 120))
(defconstant nbl (truncate (/ nb 40)))
(defconstant nel (truncate (/ ne 40)))
(defconstant nbn (truncrem nb 40))
(defconstant nen (truncrem ne 40))
(defconstant imgb (switch (cat (1+ nbl) "v" (1+ nbn))
(("1v1") "SUPER")
(("1v2") "KIDZ")
(("1v3") "FOOD")
(("1v4") "LOVE")
(("1v5") "CHEAP")
(("1v6") "SHOE")
(("1v7") "POST")
(("1v8") "PAPER")
(("1v9") "ADULT")
(("1v10") "HAPPY")
(("1v11") "STUPID")
(("1v12") "NICE")
(("1v13") "PENNY")
(("1v14") "STONE")
(("1v15") "MONEY")
(("1v16") "FUN")
(("1v17") "MY")
(("1v18") "YOUR")
(("1v19") "YOYLE")
(("1v20") "GIFT")
(("1v21") "PUBLIC")
(("1v22") "DRESS")
(("1v23") "TOY")
(("1v24") "SUPER")
(("1v25") "FRUIT")
(("1v26") "CANDY")
(("1v27") "FAST")
(("1v28") "MAIL")
(("1v29") "EGG")
(("1v30") "OUR")
(("1v31") "BOOK")
(("1v32") "TILE")
(("1v33") "TOWEL")
(("1v34") "JUICE")
(("1v35") "JEWEL")
(("1v36") "ELITE")
(("1v37") "PET")
(("1v38") "PET'S")
(("1v39") "THE")
(("1v40") "ICED")
(("2v1") "GROCERY")
(("2v2") "50% OFF")
(("2v3") "CLOTHING")
(("2v4") "FURNITURE")
(("2v5") "PRISONER'S")
(("2v6") "MOM & POP")
(("2v7") "CHILDREN'S")
(("2v8") "SCHOOL")
(("2v9") "ITALIAN")
(("2v10") "DOLLAR")
(("2v11") "YUMMY")
(("2v12") "CIRCUIT")
(("2v13") "CAMERA")
(("2v14") "BATTLE")
(("2v15") "CHINESE")
(("2v16") "LEARNING")
(("2v17") "COMPUTER")
(("2v18") "VISITOR'S")
(("2v19") "HARDWARE")
(("2v20") "PRIVATE")
(("2v21") "PRODUCE")
(("2v22") "MEDICAL")
(("2v23") "SOFTWARE")
(("2v24") "INJURED")
(("2v25") "SOOTHING")
(("2v26") "AMAZING")
(("2v27") "GROCERY")
(("2v28") "VEGETABLE")
(("2v29") "DELICIOUS")
(("2v30") "MATCHSTICK")
(("2v31") "JEWELRY")
(("2v32") "MAKE UP")
(("2v33") "BEAUTY")
(("2v34") "LIPSTICK")
(("2v35") "SEAFOOD")
(("2v36") "CREAMY")
(("2v37") "SHREDDED")
(("2v38" "2v39") "WHISKEY")
(("2v40") "BOWLING")
(("3v1") "PRESIDENTIAL")
(("3v2") "WELCOME TO THE")
(("3v3" "3v9") "TECHNOLOGY")
(("3v4") "ANNOUNCER")
(("3v5") "INFORMATION")
(("3v6") "OUT OF ORDER")
(("3v7" "3v8") "COMMERCIAL")
(("3v10") "THE EVERYTHING")
(("3v11") "SHOPPING CENTER")
(("3v12") "RAINFOREST")
(("3v13") "THE MUSEUM OF")
(("3v14") "THE YOYLE CITY")
(("3v15") "FREE FOR ALL")
(("3v16") "CRUSTACEAN")
(("3v17") "WORLD HISTORY")
(("3v18") "THE FRESHEST")
(("3v19") "BOB AND JOHN'S")
(("3v20") "YOYLE TRADE")
(("3v21") "THE AUTHORITY")
(("3v22") "IMPROVEMENT")
(("3v23") "CRYSTAL TOWER")
(("3v24") "ABANDONED")
(("3v25") "NEW & IMPROVED")
(("3v26") "TYPOGRAPHY")
(("3v27") "THE SUPER ELITE")
(("3v28") "THE AQUATIC")
(("3v29") "WATER HOUSING")
(("3v30") "REAL ESTATE")
(("3v31") "TONS & TONS OF")
(("3v32") "ICE CREAM")
(("3v33") "ALL AROUND")
(("3v34") "SKYSCRAPER")
(("3v35") "THE PROUD YOYLE")
(("3v36") "RECREATIONAL")
(("3v37") "THE RELIGION")
(("3v38") "FIREFIGHTER'S")
(("3v39") "PUBLISHING")
(("3v40") "THE DANCING")
default (cat "b[" nbl "][" nbn "]")
))
(defconstant imge (switch (cat (1+ nel) "v" (1+ nen))
(("1v1") "SHOP")
(("1v2") "STORE")
(("1v3") "PLACE")
(("1v4") "PLAZA")
(("1v5") "FOOD")
(("1v6") "FIELD")
(("1v7") "CRIB")
(("1v8") "JAIL")
(("1v9") "HOUSE")
(("1v10") "HOME")
(("1v11") "HOTEL")
(("1v12") "ROCK")
(("1v13") "CAFE")
(("1v14") "INC.")
(("1v15") "GET")
(("1v16") "39")
(("1v17") "ETC.")
(("1v18") "EAT")
(("1v19") "R US")
(("1v20") "4 U")
(("1v21") ".COM")
(("1v22") "TO BUY")
(("1v23") "RELEIF")
(("1v24") "ADVICE")
(("1v25") "OFFICE")
(("1v26") "DOCK")
(("1v27") "POOL")
(("1v28") "GUYS")
(("1v29") "PARK")
(("1v30") "COURT")
(("1v31") "AREA")
(("1v32") "LOOP")
(("1v33") "MOTEL")
(("1v34") "WALL")
(("1v35") "HALL")
(("1v36") "CLUB")
(("1v37") "FISH")
(("1v38") "SPACE")
(("1v39") "ZONE")
(("1v40") "PETS")
(("2v1") "CHURCH")
(("2v2") "PALACE")
(("2v3") "CENTER")
(("2v4") "FOR YOU")
(("2v5") "FOR LIFE")
(("2v6") "SQUARE")
(("2v7") "DUNGEON")
(("2v8") "CORNER")
(("2v9") "BOOKSTORE")
(("2v10") "THEATER")
(("2v11") "APARTMENT")
(("2v12") "FACTORY")
(("2v13") "TOY STORE")
(("2v14") "WORLD")
(("2v15") "OF FUN")
(("2v16") "SCHOOL")
(("2v17") "MARKET")
(("2v18") "DAY CARE")
(("2v19") "BAZAAR")
(("2v20") "LOUNGE")
(("2v21") "HOSPITAL")
(("2v22") "CAFETERIA")
(("2v23") "LIBRARY")
(("2v24") "RESEARCH")
(("2v25") "BUSINESS")
(("2v26") "MUSEUM")
(("2v27") "MEMORIAL")
(("2v28") "CEMETERY")
(("2v29") "CINEMA")
(("2v30") "HELPERS")
(("2v31") "CLEANING")
(("2v32") "DRIVE THRU")
(("2v33") "FAST FOOD")
(("2v34") "KITCHEN")
(("2v35") "BISTRO")
(("2v36") "DREAMS")
(("2v37") "SWEATSHOP")
(("2v38") "SLAMMER")
(("2v39") "AIRPORT")
(("2v40") "STATION")
(("3v1") "COURTHOUSE")
(("3v2") "PLAYGROUND")
(("3v3") "HIGH SCHOOL")
(("3v4") "MIDDLE SCHOOL")
(("3v5") "SUPERMARKET")
(("3v6") "SUPERSTORE")
(("3v7") "RESTAURANT")
(("3v8") "INCORPORATED")
(("3v9") "DOCTOR'S OFFICE")
(("3v10") "HOLE IN THE WALL")
(("3v11") "SHOPPING CENTER")
(("3v12") "IMPROVEMENT")
(("3v13") "SUPERSHOP")
(("3v14") "EXTRAVAGANZA")
(("3v15") "BUSINESSES")
(("3v16") "WEIGHT LOSS")
(("3v17") "HEALTH CENTER")
(("3v18") "HEALTH CLINIC")
(("3v19") "FOR ALL TO ENJOY")
(("3v20") "ASSOCIATION")
(("3v21") "OF BFDI WORLD")
(("3v22") "TRAIN STATION")
(("3v23") "PARKING GARAGE")
(("3v24") "TENNIS COURT")
(("3v25") "GOLF COURSE")
(("3v26") "GELATIN FACTORY")
(("3v27") "FRIDGE FACTORY")
(("3v28") "WEATHER STATION")
(("3v29") "INSTITUTION")
(("3v30") "EMERGENCY")
(("3v31") "FILTRATION PLANT")
(("3v32") "STATIONERY")
(("3v33") "SANCTUARY")
(("3v34") "MEDICAL CENTER")
(("3v35") "OF ICE CREAM")
(("3v36") "STORAGE SPACE")
(("3v37") "TO MUNCH ON")
(("3v38") "FOR ETERNITY")
(("3v39") "ANIMAL SHELTER")
(("3v40") "HOMELESS SHELTER")
default (cat "b[" nel "][" nen "]")
))
(defconstant windowWidth (/ (- w (* edgeMargin 2)) wx))
(defconstant windowHeight (/ (- h (* edgeMargin 3)) wz))
(defconstant rand (truncrem (+ c-r c-g c-b) 4))
(defconstant pb (+ edgeMargin (random-float 1/64)))
(defconstant r (* (max 0.15 (- roof2 0.2)) 0.1))
(defconstant r2 (+ (* roof2 0.1) 0.03))
(defmacro drawRoofBlock (unpositioned directwidth xc xs blockHeight &optional (col (rgb c3-r c3-g c3-b))) (div ((style (cat (style
(margin (mif xc (cat "0 0 0 " (* 1024 (- xc (/ xs 2))) "px") "auto"))
(width (mif directwidth xs (cat (* 1024 xs 2) "px")))
(height (* 1024 blockHeight) "px")
(background col)
) (mif unpositioned ";position:absolute;bottom:0" ""))))))
(div ((style (style
(width "fit-content")
(margin "0 auto")
(padding-top "96px")
)))
(div ((style (style (position "relative"))))
(lif (>= roof 9) (let ((p (truncrem (+ c3-r c3-g c3-b) 8))) (lif (< p 4)
(let ((xs (* (min w l) 0.1))) (drawRoofBlock t nil (* w (+ 0.3 (* 0.4 (truncate (/ p 2))))) xs (* l 0.4)))
)))
(switch (truncrem roof 9)
((2 3 4)
(div ((style (style
(background (rgb c3-r c3-g c3-b))
(width (* 100 (1+ (* r 2))) "%")
(height (* 1024 l 0.4) "px")
(clip-path "polygon(0 100%, 100% 100%, 50% 0)")
(margin-left "calc(-100% * " r ")")
))))
)
((5)
(div ((style (style
(background (rgb c3-r c3-g c3-b))
(width (* 100 (1+ (* r 2))) "%")
(height (* 1024 l 0.4) "px")
(clip-path "polygon(0 100%, 100% 100%, " (* 100 (- 1 (+ r r2))) "% 0, " (* 100 (+ r r2)) "% 0)")
(margin-left "calc(-100% * " r ")")
))))
)
((6)
(drawRoofBlock nil t nil "80%" (* l 0.16))
)
((7)
(drawRoofBlock nil t nil "14%" (* l 0.5))
(drawRoofBlock nil t nil "70%" (* l 0.2))
)
((8)
(drawRoofBlock nil t nil "18%" (* l 0.13) (switch (truncrem (+ c2-r c2-g c2-b) 7)
((0) (rgb 0 0 255))
((1) (rgb 0 255 255))
((2) (rgb 0 255 0))
((3) (rgb 255 255 0))
((4) (rgb 255 0 0))
((5) (rgb 255 0 255))
((6) (rgb 255 255 255))
))
(drawRoofBlock nil t nil "6%" (* l 0.8))
(drawRoofBlock nil t nil "40%" (* l 0.2))
(drawRoofBlock nil t nil "80%" (* l 0.2))
)
)
)
(tag table ((class "yoyrBuilding") (style (style
(width (* 1024 w) "px")
(height (* 1024 h) "px")
(background (rgb c-r c-g c-b))
(border-spacing (* 1024 wm (+ windowWidth windowHeight)) "px")
(padding (* 1024 edgeMargin) "px")
(padding-bottom (* 1024 pb) "px")
)))
;(repeat wz (tag tr ()
; (repeat wx (tag td () "x"))
;))
;We don't use the above code because the inner loop gets re-parsed every time the outer loop iterates, which causes wz * (wx + 1) total loops, often exceeding the mediawiki loop cap. This kind of pre-evaluation to a variable might later be added to the loop macros as an optimization for constant expressions in the loop body.
;(let ((row (tag tr () (repeat wx (tag td ())))))
; (repeat wz row)
;)
;The above code still exceeds the loop cap sometimes, so I've done some Duff-style unrolling
;(let ((row (tag tr () (repeat wx (tag td ())))))
; (repeat (floor (/ wz 2)) row row)
; (lif (truncrem wz 2) row)
;)
;The above code was written before I added doors, signs, and roofs
(let ((windowFloor 0) (multi 0))
(lif (= rand 0)
(ssetf windowFloor 1)
(lif (lor (land (= rand 3) (lnot (land (= nbl 0) (= nel 0)))) (land (= nbl 2) (= nel 2))) (ssetf multi 1))
)
(let (
(row (tag tr () (repeat wx (tag td ()))))
(rwz (- wz (lif (>= name 1) (+ 2 multi) 1)))
)
(lif (land (lnot windowFloor) (>= name 1))
(lif multi
(cat
(tag tr () (tag td ((class "yoyrName") (colspan wx)) imgb))
(tag tr () (tag td ((class "yoyrName") (colspan wx)) imge))
)
(tag tr () (tag td ((class "yoyrName") (colspan wx)) imgb " " imge))
)
)
(repeat (floor (/ rwz 4)) row row row row)
(repeat (truncrem rwz 4) row)
(lif (land windowFloor (>= name 1))
(tag tr () (tag td ((class "yoyrName") (colspan wx)) imgb " " imge))
)
(loop x2 0 wx (lif (lor (land (= x2 0) (= door -1)) (land (= x2 (1- wx)) (= door 1)) (land (= x2 (truncate (/ wx 2))) (= door 0)))
(tag td ((style (style (transform "translateY(-50%) scaleY(" (* (/ (+ windowHeight pb edgeMargin) windowHeight) 16) ") translateY(50%)")))));mul by 16 so it always overflows
(tag td ())
))
)
)
)
)
(div ((style (style
(position "absolute")
(left 0)
(width "100%")
(height "1024px")
(z-index -1)
(background "#832E8D")
))))
(category "XD so random!!!111one")
(category "Pages that don't even remotely resemble a Wikipedia article")
(category "Buildings")
Chomp mwlisp script
(defconstant width 12)
(defconstant height 8)
(defconstant loopw (1- (floor (/ width 2))))
(defmacro loopb (v a b form) (loop v a (- b a) form))
(defmacro nth-child (n) (cat ":nth-child(" (* width 2) "n+" n ")"))
(defmacro nth-child-p (n) (cat ".mw-collapsed" (nth-child (1+ (* n 2))) " ~ div"))
(defmacro nth-child-d (n) (nth-child (* (1+ n) 2)))
(defmacro nth-child-hover (n) (cat "#chomp > " (nth-child-d n) ":hover ~ div"))
(defmacro chomped (ncl) (cat
(ncl 0)
(loopb i 1 loopw (cat
","
(ncl i)
":not("
(nth-child-d 0)
(loopb j 1 i (cat
"," (nth-child-d j)
))
")"
))
(loopb i loopw (1- width) (cat
","
(ncl i)
":is("
(nth-child-d i)
(loopb j (1+ i) width (cat
"," (nth-child-d j)
))
")"
))
","
(ncl (1- width))
(nth-child-d (1- width))
))
(defmacro alpha (n) (switch n ((1) "a") ((2) "b") ((3) "c") ((4) "d") ((5) "e") ((6) "f") ((7) "g") ((8) "h") ((9) "i") ((10) "j") ((11) "k") ((12) "l") ((13) "m") ((14) "n") ((15) "o") ((16) "p") ((17) "q") ((18) "r") ((19) "s") ((20) "t") ((21) "u") ((22) "v") ((23) "w") ((24) "x") ((25) "y") ((26) "z")))
(defconstant *mwlisp-allow-loop-unrolling* t)
(templatestyles "Commonfonts.css")
(parserfun "#css" (cat "
#chompboard {
border-spacing: 0;
font-weight: bold;
line-height: 1;
text-align: center;
}
#chompboard td {
padding: 0;
}
#chompboard tr:first-child td {
padding-bottom: 1ch;
}
#chompboard td:first-child {
padding-right: 1ch;
}
#chompboard td:last-child {
padding-left: 1ch;
}
#chompboard tr:last-child td {
padding-top: 1ch;
}
#chompboard tr:is(:first-child, :last-child) td:not(:first-child, :last-child) {
width: 64px;
}
#chomp {
display: grid;
grid-template-columns:" (repeat width " 1fr") ";
width: fit-content;
}
#chomp p {
display: none;
}
#chomp div {
background: #AE7365;
border: 8px outset #CC8776;
box-sizing: border-box;
height: 64px;
transition: opacity 0.25s ease;
width: 64px;
}
#chomp img {
opacity: 0.25;
}
#chomp > :hover," (chomped nth-child-hover) "{
background-color: #DB5348;
}"
(chomped nth-child-p) "{
opacity: 0;
pointer-events: none;
}
"))
"[[You]] and a [[friend]] are sharing a delectable [[chocolate]] bar. But alas! The top-left [[square]] has been laced with [[okinberries]], and whoever eats it will [[death|lose]].
You must [[alternate worlds|alternate]] turns eating from the chocolate [[bar]], but [[can]] only remove pieces in the [[shapes]] highlighted when [[hovering]] over the bar."
(p ((class "couriernew")) "also youll have to [[Play Buttony|play]] against a [[real life|real]] person because [[User:Pseudosphere|i]] have no idea how [[User:Pseudosphere|i]]'d fit a chomp [[artificial intelligence|ai]] within the [[2]][[Mega Man|M]][[Byte|B]] limit")
(div ((style (style
(position "absolute")
(transform "translate(2ch, calc(1em + 1ch - 50%)) scaleY(" (/ (* height 210) (* width 208)) ") translateY(50%)")
(z-index -1)
))) (file "Niko curse.gif" (cat (* width 64) "px") "link="))
(table ((id "chompboard"))
(tr ()
(td)
(loop i 1 width (td () (alpha i)))
(td)
)
(tr ()
(td () 1)
(td ((colspan width) (rowspan height)) (div ((id "chomp") (style (style (grid-area "2 / 2 / " (+ height 2) " / " (+ width 2)))))
(loop i 0 (* width height)
(p ((id (cat "mw-customcollapsible-c" i)) (class "mw-collapsible")))
(div ((class (cat "mw-customtoggle-c" i))) (ifeq i 0
(file "DiaNiko.png" "48x48px" "link=")
))
)
))
(td () 1)
)
(loop i 2 (1- height) (tr () (td () i) (td () i)))
(tr ()
(td)
(loop i 1 width (td () (alpha i)))
(td)
)
)
(category "Minigames")(category "Multiplayer minigames")(category "Collapsible minigames")(category "Solved games")(category "Impartial games")
Kepler–Poinsot polyhedra
Subpages
:Þ
