Skip to content

Instantly share code, notes, and snippets.

@obelisk68
Last active March 22, 2018 05:00
Show Gist options
  • Save obelisk68/1c3d278cb5fe2778a11ba719d44af743 to your computer and use it in GitHub Desktop.
Save obelisk68/1c3d278cb5fe2778a11ba719d44af743 to your computer and use it in GitHub Desktop.
L-system の実装
require 'oekaki'
class Lsystem
def initialize(width, height, title = "L-system")
@width = width
@height = height
@title = title
@procedure = ""
@command = {}
@rule = {}
@eval = proc {}
@po = [0, 0]
@putout = false
end
attr_accessor :dir, :putout
def move(x, y)
@po = [x, y]
end
def init(st)
@procedure = st
end
def set(st, &block)
@command[st] = block
end
def rule(a, r)
@rule[a] = r
end
def prologue(&block)
@eval = block
end
def generate(n)
n.times do
pr = ""
@procedure.each_char do |c|
pr += @rule[c] || c
end
@procedure = pr
p pr if @putout
end
end
def exec(t)
stack = []
@procedure.each_char do |c|
case c
when "["
stack << t.dup
when "]"
t = stack.pop
else
todo = @command[c]
raise "#{c} not defined." unless todo
t.instance_exec(&todo)
end
end
end
def draw(n)
ob = self
Oekaki.app width: @width, height: @height, title: @title do
t = Oekaki::Turtle.new
ob.generate(n)
draw do
clear
t.instance_exec(&ob.instance_variable_get(:@eval))
t.move(*ob.instance_variable_get(:@po))
t.dir = ob.dir if ob.dir
ob.exec(t)
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment