@simontiger/

LSystem

Python (with Turtle)

No description

fork
loading

This Plugin Crashed!

Error: Error: must not create an existing file {"type":"CREATE_FILE","wid":"0.3870930622728035","path":"main.py","file":{"path":"main.py","content":{"asEncoding":{"base64":"ZnJvbSB0dXJ0bGUgaW1wb3J0ICoKc3BlZWQoNSkKCmZ1bmN0aW9uID0gdHlwZShsYW1iZGE6IDApCgpjbGFzcyBMU3lzdGVtOgogIGRlZiBfX2luaXRfXyhzZWxmKToKICAgIHNlbGYuY3VycmVudCA9ICIiCiAgICBzZWxmLnJ1bGVzID0ge30KICAgIHNlbGYuYW5nbGUgPSAtMQogICAgc2VsZi5jb21tYW5kcyA9IHt9CiAgCiAgZGVmIF9fc3RyX18oc2VsZik6CiAgICByZXR1cm4gc2VsZi5jdXJyZW50CgogIGRlZiBhZGRSdWxlKHNlbGYsIG9sZCwgbmV3KToKICAgIHNlbGYucnVsZXNbb2xkXSA9IG5ldwogIAogIGRlZiBhZGRDb21tYW5kKHNlbGYsIG5hbWUsIGFjdGlvbik6CiAgICBzZWxmLmNvbW1hbmRzW25hbWVdID0gYWN0aW9uCiAgCiAgZGVmIHJlY3Vyc2Uoc2VsZik6CiAgICBuZXh0XyA9ICIiCiAgICBmb3IgaSBpbiBzZWxmLmN1cnJlbnQ6CiAgICAgIGlmIGkgaW4gc2VsZi5ydWxlczogbmV4dF8gKz0gc2VsZi5ydWxlc1tpXQogICAgICBlbHNlOiAgICAgICAgICAgICAgIG5leHRfICs9IGkKICAgIHNlbGYuY3VycmVudCA9IG5leHRfCiAgICByZXR1cm4gbmV4dF8KICAKICBkZWYgcmVuZGVyKHNlbGYsIHN0ZXBfc2l6ZSk6CiAgICBhc3NlcnQgc2VsZi5hbmdsZSA+PSAwCgogICAgY29tbWFuZHMgPSBbXQogICAgZm9yIGkgaW4gc2VsZi5jdXJyZW50OgogICAgICBpZiBpIGluIHNlbGYuY29tbWFuZHM6IGNvbW1hbmRzICs9IHNlbGYuY29tbWFuZHNbaV0KICAgIAogICAgc3RhY2sgPSBbeyJwb3NpdGlvbiI6IHBvc2l0aW9uKCksICJhbmdsZSI6IGhlYWRpbmcoKX1dCiAgICBmb3IgaSBpbiBjb21tYW5kczoKICAgICAgYXNzZXJ0IHR5cGUoaSkgaW4gW3N0ciwgZnVuY3Rpb25dCiAgICAgIGlmIHR5cGUoaSkgPT0gZnVuY3Rpb246CiAgICAgICAgaShzdGVwX3NpemUsIHNlbGYuYW5nbGUpCiAgICAgIGVsaWYgaSA9PSAnRic6CiAgICAgICAgcGVuZG93bigpCiAgICAgICAgZm9yd2FyZChzdGVwX3NpemUpCiAgICAgIGVsaWYgaSA9PSAnRyc6CiAgICAgICAgcGVudXAoKQogICAgICAgIGZvcndhcmQoc3RlcF9zaXplKQogICAgICBlbGlmIGkgPT0gJysnOgogICAgICAgIGxlZnQoc2VsZi5hbmdsZSkKICAgICAgZWxpZiBpID09ICctJzoKICAgICAgICByaWdodChzZWxmLmFuZ2xlKQogICAgICBlbGlmIGkgPT0gJ1snOgogICAgICAgIHN0YWNrLmFwcGVuZCh7InBvc2l0aW9uIjogcG9zaXRpb24oKSwgImFuZ2xlIjogaGVhZGluZygpfSkKICAgICAgZWxpZiBpID09ICddJzoKICAgICAgICBzYXZlZCA9IHN0YWNrLnBvcCgpCiAgICAgICAgcGVudXAoKQogICAgICAgIHNldHBvc2l0aW9uKHNhdmVkWyJwb3NpdGlvbiJdKQogICAgICAgIHNldGhlYWRpbmcoc2F2ZWRbImFuZ2xlIl0pCgpkZWYgbWFpbigpOgogICIiImFsZ2FlX2xzeXMgPSBMU3lzdGVtKCkKICBhbGdhZV9sc3lzLmFkZFJ1bGUoJ0EnLCAiQUIiKQogIGFsZ2FlX2xzeXMuYWRkUnVsZSgnQicsICJBIikKICAKICBhbGdhZV9sc3lzLmN1cnJlbnQgPSAiQSIKICBwcmludChhbGdhZV9sc3lzLmN1cnJlbnQpCiAgZm9yIGkgaW4gcmFuZ2UoOCk6CiAgICBwcmludChhbGdhZV9sc3lzLnJlY3Vyc2UoKSkiIiIKCiAgdHJlZV9sc3lzID0gTFN5c3RlbSgpCiAgdHJlZV9sc3lzLmFkZFJ1bGUoJzEnLCAiMTEiKQogIHRyZWVfbHN5cy5hZGRSdWxlKCcwJywgIjFbMF0wIikKICB0cmVlX2xzeXMuYW5nbGUgPSA0NQogIHRyZWVfbHN5cy5hZGRDb21tYW5kKCcwJywgbGFtYmRhIGEsIGI6IGZvcndhcmQoYS8yKSkKICB0cmVlX2xzeXMuYWRkQ29tbWFuZCgnMScsIGxhbWJkYSBhLCBiOiBmb3J3YXJkKGEpKQogIHRyZWVfbHN5cy5hZGRDb21tYW5kKCdbJywgIlsrIikKICB0cmVlX2xzeXMuYWRkQ29tbWFuZCgnXScsICJdLSIpCgogIHRyZWVfbHN5cy5jdXJyZW50ID0gIjAiCiAgcHJpbnQodHJlZV9sc3lzLmN1cnJlbnQpCiAgZm9yIGkgaW4gcmFuZ2UoNik6CiAgICBwcmludCh0cmVlX2xzeXMucmVjdXJzZSgpKQogIGxlZnQoOTApCiAgcGVudXAoKQogIGJhY2soMzAwKQogIHBlbmRvd24oKQogIHRyZWVfbHN5cy5yZW5kZXIoMTIpCgogICIiImNhbnRvcl9sc3lzID0gTFN5c3RlbSgpCiAgY2FudG9yX2xzeXMuYWRkUnVsZSgnQScsICJBQkEiKQogIGNhbnRvcl9sc3lzLmFkZFJ1bGUoJ0InLCAiQkJCIikKICBjYW50b3JfbHN5cy5hbmdsZSA9IDAKICBjYW50b3JfbHN5cy5hZGRDb21tYW5kKCdBJywgIkYiKQogIGNhbnRvcl9sc3lzLmFkZENvbW1hbmQoJ0InLCAiRyIpCiAgCiAgY2FudG9yX2xzeXMuY3VycmVudCA9ICdBJwogIHByaW50KGNhbnRvcl9sc3lzLmN1cnJlbnQpCiAgZm9yIGkgaW4gcmFuZ2UoNSk6CiAgICBwcmludChjYW50b3JfbHN5cy5yZWN1cnNlKCkpCiAgcGVudXAoKQogIGJhY2soMzAwKQogIGNhbnRvcl9sc3lzLnJlbmRlcigyKSIiIgoKICAiIiJrb2NoX2xzeXMgPSBMU3lzdGVtKCkKICBrb2NoX2xzeXMuYWRkUnVsZSgnRicsICJGK0YtRi1GK0YiKQogIGtvY2hfbHN5cy5hbmdsZSA9IDkwCiAga29jaF9sc3lzLmFkZENvbW1hbmQoJ0YnLCAiRiIpCiAga29jaF9sc3lzLmFkZENvbW1hbmQoJysnLCAiKyIpCiAga29jaF9sc3lzLmFkZENvbW1hbmQoJy0nLCAiLSIpCgogIGtvY2hfbHN5cy5jdXJyZW50ID0gJ0YnCiAgcHJpbnQoa29jaF9sc3lzLmN1cnJlbnQpCiAgZm9yIGkgaW4gcmFuZ2UoNCk6CiAgICBwcmludChrb2NoX2xzeXMucmVjdXJzZSgpKQogIHBlbnVwKCkKICBiYWNrKDMwMCkKICBrb2NoX2xzeXMucmVuZGVyKDcpIiIiCgogICIiImFycm93aGVhZF9sc3lzID0gTFN5c3RlbSgpCiAgYXJyb3doZWFkX2xzeXMuYWRkUnVsZSgnQScsICJCLUEtQiIpCiAgYXJyb3doZWFkX2xzeXMuYWRkUnVsZSgnQicsICJBK0IrQSIpCiAgYXJyb3doZWFkX2xzeXMuYW5nbGUgPSA2MAogIGFycm93aGVhZF9sc3lzLmFkZENvbW1hbmQoJ0EnLCAiRiIpCiAgYXJyb3doZWFkX2xzeXMuYWRkQ29tbWFuZCgnQicsICJGIikKICBhcnJvd2hlYWRfbHN5cy5hZGRDb21tYW5kKCcrJywgIisiKQogIGFycm93aGVhZF9sc3lzLmFkZENvbW1hbmQoJy0nLCAiLSIpCgogIGFycm93aGVhZF9sc3lzLmN1cnJlbnQgPSAiQSIKICBwcmludChhcnJvd2hlYWRfbHN5cy5jdXJyZW50KQogIGZvciBpIGluIHJhbmdlKDUpOgogICAgcHJpbnQoYXJyb3doZWFkX2xzeXMucmVjdXJzZSgpKQogIHBlbnVwKCkKICBiYWNrKDMwMCkKICByaWdodCg5MCkKICBmb3J3YXJkKDEwMCkKICBsZWZ0KDkwKQogIGFycm93aGVhZF9sc3lzLnJlbmRlcigzMCkiIiIKCiAgIiIiZHJhZ29uX2xzeXMgPSBMU3lzdGVtKCkKICBkcmFnb25fbHN5cy5hZGRSdWxlKCdYJywgIlgrWUYrIikKICBkcmFnb25fbHN5cy5hZGRSdWxlKCdZJywgIi1GWC1ZIikKICBkcmFnb25fbHN5cy5hbmdsZSA9IDkwCiAgZHJhZ29uX2xzeXMuYWRkQ29tbWFuZCgnRicsICJGIikKICBkcmFnb25fbHN5cy5hZGRDb21tYW5kKCcrJywgIi0iKQogIGRyYWdvbl9sc3lzLmFkZENvbW1hbmQoJy0nLCAiKyIpCgogIGRyYWdvbl9sc3lzLmN1cnJlbnQgPSAiRlgiCiAgcHJpbnQoZHJhZ29uX2xzeXMuY3VycmVudCkKICBmb3IgaSBpbiByYW5nZSg4KToKICAgIHByaW50KGRyYWdvbl9sc3lzLnJlY3Vyc2UoKSkKICBwZW51cCgpCiAgYmFjaygzMDApCiAgcmlnaHQoOTApCiAgZHJhZ29uX2xzeXMucmVuZGVyKDExKSIiIgoKbWFpbigpCmhpZGV0dXJ0bGUoKQ=="},"asBuffer":null},"loaded":true}}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
from turtle import *
speed(5)

function = type(lambda: 0)

class LSystem:
  def __init__(self):
    self.current = ""
    self.rules = {}
    self.angle = -1
    self.commands = {}
  
  def __str__(self):
    return self.current

  def addRule(self, old, new):
    self.rules[old] = new
  
  def addCommand(self, name, action):
    self.commands[name] = action
  
  def recurse(self):
    next_ = ""
    for i in self.current:
      if i in self.rules: next_ += self.rules[i]
      else:               next_ += i
    self.current = next_
    return next_
  
  def render(self, step_size):
    assert self.angle >= 0

    commands = []
    for i in self.current:
      if i in self.commands: commands += self.commands[i]
    
    stack = [{"position": position(), "angle": heading()}]
    for i in commands:
      assert type(i) in [str, function]
      if type(i) == function:
        i(step_size, self.angle)
      elif i == 'F':
        pendown()
        forward(step_size)
      elif i == 'G':
        penup()
        forward(step_size)
      elif i == '+':
        left(self.angle)
      elif i == '-':
        right(self.angle)
      elif i == '[':
        stack.append({"position": position(), "angle": heading()})
      elif i == ']':
        saved = stack.pop()
        penup()
        setposition(saved["position"])
        setheading(saved["angle"])

def main():
  """algae_lsys = LSystem()
  algae_lsys.addRule('A', "AB")
  algae_lsys.addRule('B', "A")
  
  algae_lsys.current = "A"
  print(algae_lsys.current)
  for i in range(8):
    print(algae_lsys.recurse())"""

  tree_lsys = LSystem()
  tree_lsys.addRule('1', "11")
  tree_lsys.addRule('0', "1[0]0")
  tree_lsys.angle = 45
  tree_lsys.addCommand('0', lambda a, b: forward(a/2))
  tree_lsys.addCommand('1', lambda a, b: forward(a))
  tree_lsys.addCommand('[', "[+")
  tree_lsys.addCommand(']', "]-")

  tree_lsys.current = "0"
  print(tree_lsys.current)
  for i in range(6):
    print(tree_lsys.recurse())
  left(90)
  penup()
  back(300)
  pendown()
  tree_lsys.render(12)

  """cantor_lsys = LSystem()
  cantor_lsys.addRule('A', "ABA")
  cantor_lsys.addRule('B', "BBB")
  cantor_lsys.angle = 0
  cantor_lsys.addCommand('A', "F")
  cantor_lsys.addCommand('B', "G")
  
  cantor_lsys.current = 'A'
  print(cantor_lsys.current)
  for i in range(5):
    print(cantor_lsys.recurse())
  penup()
  back(300)
  cantor_lsys.render(2)"""

  """koch_lsys = LSystem()
  koch_lsys.addRule('F', "F+F-F-F+F")
  koch_lsys.angle = 90
  koch_lsys.addCommand('F', "F")
  koch_lsys.addCommand('+', "+")
  koch_lsys.addCommand('-', "-")

  koch_lsys.current = 'F'
  print(koch_lsys.current)
  for i in range(4):
    print(koch_lsys.recurse())
  penup()
  back(300)
  koch_lsys.render(7)"""

  """arrowhead_lsys = LSystem()
  arrowhead_lsys.addRule('A', "B-A-B")
  arrowhead_lsys.addRule('B', "A+B+A")
  arrowhead_lsys.angle = 60
  arrowhead_lsys.addCommand('A', "F")
  arrowhead_lsys.addCommand('B', "F")
  arrowhead_lsys.addCommand('+', "+")
  arrowhead_lsys.addCommand('-', "-")

  arrowhead_lsys.current = "A"
  print(arrowhead_lsys.current)
  for i in range(5):
    print(arrowhead_lsys.recurse())
  penup()
  back(300)
  right(90)
  forward(100)
  left(90)
  arrowhead_lsys.render(30)"""

  """dragon_lsys = LSystem()
  dragon_lsys.addRule('X', "X+YF+")
  dragon_lsys.addRule('Y', "-FX-Y")
  dragon_lsys.angle = 90
  dragon_lsys.addCommand('F', "F")
  dragon_lsys.addCommand('+', "-")
  dragon_lsys.addCommand('-', "+")

  dragon_lsys.current = "FX"
  print(dragon_lsys.current)
  for i in range(8):
    print(dragon_lsys.recurse())
  penup()
  back(300)
  right(90)
  dragon_lsys.render(11)"""

main()
hideturtle()
result
console