Toggle Navigation
Hatchery
Eggs
BABA draw
__init__.py
Users
Badges
Login
Register
__init__.py
raw
Content
# Draws stuff based on user input and grammar rules import display import buttons import random import mch22 from machine import Timer animate = False tim1 = Timer(-1) # animate tim2 = Timer(-2) # randomize tim3 = Timer(-3) # clean screen # Weighted randomization for random rulesets rnd_ltr_A = lambda : random.choice("BBBBBDBBBCCCCDDDDaaaabbbccd") rnd_ltr_B = lambda : random.choice("AAAAAAAAACCCCDDDDaaaabbbccd") rnd_ltr_C = lambda : random.choice("AAAABDBBBDDDaaaaaaabbbbbbccccccddddd") rnd_ltr_D = lambda : random.choice("AABBCCCCDDDDDDaaaabbbccccccccdddddddddd") rnd_ltr_CAPS = lambda : random.choice("AABBCCCCDDDDDD") rnd_ltr_TERM = lambda : random.choice("aaabbbccd") def random_rule(): return([ ("AA", rnd_ltr_A() + rnd_ltr_A() + rnd_ltr_A()), ("BB", rnd_ltr_B() + rnd_ltr_B() + rnd_ltr_B()), ("CC", rnd_ltr_C() + rnd_ltr_C()), ("DD", rnd_ltr_D() + rnd_ltr_D()), (rnd_ltr_CAPS() + rnd_ltr_CAPS(), rnd_ltr_TERM() + rnd_ltr_TERM()), ("A", "a"), ("B", "b"), ("C", "c"), ("D", "d") ]) seed = "" # USER INPUT result = "" # INTERMEDIATE RULE draw_result = [] # END RESULT RULE FOR GRAPHICS # The ruleset, first 4 are constant and the rest are random each time rulesets = [ [("AA", "C"), ("BB", "AbA"), ("B", "ACA"), ("A", "a"), ("C", "c")], [("AA", "C"), ("BB", "AbA"), ("CC", "D"), ("B", "ACA"), ("A", "a"), ("C", "c"), ("D", "d")], [("AA", "B"), ("BB", "AcA"), ("CC", "BDB"), ("B", "ACA"), ("A", "a"), ("C", "c"), ("D", "d")], [("AAA", "AD"), ("AA", "CA"), ("CC", "AB"), ("BB", "BDB"), ("B", "ACA"), ("A", "a"), ("C", "c"), ("D", "d")] , random_rule(), random_rule(), random_rule(), random_rule(), random_rule(), random_rule(), random_rule(), random_rule() ] rules_selection = 0 rules = rulesets[rules_selection] # X direction, Y direction, color, position X, poisition Y start_vec = [(1, 0, 0xffa822, (display.width() - 40) / 2 / 5 , display.height() / 2 / 5)] vec = start_vec # The different operations a rule can get identity = lambda v : (v[0], v[1], v[2], v[3]+v[0], v[4]+v[1]) rot_L = lambda v : (v[1], -v[0], v[2], v[3]+v[0], v[4]+v[1]) rot_R = lambda v : (-v[1], v[0], v[2], v[3]+v[0], v[4]+v[1]) rot_F = lambda v : (-v[0], -v[1], v[2], v[3]+v[0], v[4]+v[1]) #rot_C = lambda v : (v[0], v[1], v[2] * 255 % 4228250370, v[3]+v[0], v[4]+v[1]) # A nicer colours rot_C: def rot_C(v): if(v[2] == 0xffa822): return((v[0], v[1], 0x134e6f, v[3]+v[0], v[4]+v[1])) elif(v[2] == 0x134e6f): return((v[0], v[1], 0xff6150, v[3]+v[0], v[4]+v[1])) elif(v[2] == 0xff6150): return((v[0], v[1], 0x1ac0c6, v[3]+v[0], v[4]+v[1])) elif(v[2] == 0x1ac0c6): return((v[0], v[1], 0xdee0e6, v[3]+v[0], v[4]+v[1])) else: return((v[0], v[1], 0xffa822, v[3]+v[0], v[4]+v[1])) # What drawing rules output is assigned with vrules = [("a", identity), ("b", rot_C), ("c", rot_L), ("d", rot_R)] # THE HORROR BEGINS BELOW def draw_rule_text(): display.drawRect(10, 110, 30, 30, True, display.WHITE) display.drawText(10, 110, "Rule\n" + str(rules_selection+1), display.MAGENTA, "roboto_regular12") def draw_bottom_text(): global animate if animate: display.drawText(100, 220, "ANIMATE", display.RED, "roboto_regular12") else: display.drawText(100, 220, "ANIMATE", display.GREEN, "roboto_regular12") display.drawText(30, 220, "QUIT CLEAN DRAW", display.BLACK, "roboto_regular12") def draw_input_text(): global seed display.drawText(8, 8, "Set seed sequence with A & B, delete with <-", display.BLACK, "roboto_regular12") display.drawText(10, 25, seed, display.BLUE, "roboto_regular18") def init_screen(): display.drawFill(display.WHITE) draw_input_text() draw_rule_text() draw_bottom_text() display.flush() # The rules both for parsing the input and converting it to drawing rules # Enrich the user input by feeding it through parser (with some of rules randomly generated) def apply_rules(s): global rules_selection global rulesets for r in rulesets[rules_selection]: if(s.startswith(r[0])): return((r[1], len(r[0]))) return(s[0], 1) # Match the parsed output with corresponding drawing rule def find_draw_rule(s): global vrules for vr in vrules: if(s.startswith(vr[0])): return(vr[1]) def apply_draw_rules(acc, s): if(len(s) == 0): return(acc) r = find_draw_rule(s) # Associate the next drawing rule based on parsed output last = r(acc[-1]) acc.append(last) apply_draw_rules(acc, s[1:]) return(acc) def draw_figure(points): for p in points: display.drawRect(p[3] * 5 % 320, p[4] * 5 % 240, 5, 5, True, p[2]) #display.drawPixel(p[3] * 5 % 320, p[4] * 5 % 240, p[2]) display.flush() def calc_origin_vec(): global vec xorgigin = ( min(vec,key=lambda item:item[3]) + max(vec,key=lambda item:item[3]) ) / 2 xorgigin = ( min(vec,key=lambda item:item[4]) + max(vec,key=lambda item:item[4]) ) / 2 return(xorigin, yorigin) def acc_rules(acc_next): racc = acc_next[0] rnext = acc_next[1] if(rnext != ""): ar = apply_rules(rnext[0:]) return(racc + ar[0], rnext[ar[1]:]) return(racc,"") def run_rules(s_str): acc = "" counter = 0 res = (acc, s_str) while res[1] != "" and counter < 100: counter += 1 res = acc_rules(res) return(res[0]) def iter_rules(s_str): counter = 0 cyc = run_rules(s_str) while cyc.lower() != cyc and counter < 100: counter += 1 cyc = run_rules(cyc) return(cyc) def parse_result(): global result global draw_result global seed global vec result = iter_rules(seed) draw_result = apply_draw_rules(vec, result) # keep only latest ones vec = vec[-10:] # Animation randomization def randomize_state(): global vec global rules_selection #vec[-1][3] = random.randint(10, 54) #vec[-1][4] = random.randint(10, 38) rules_selection = random.randint(0, len(rulesets)) draw_rule_text() display.flush() # Drawing frames def draw_frame(): global draw_result draw_figure(draw_result) display.flush() def animate_frame(): global animate if animate: parse_result() draw_frame() # Button presses def DRAW_btn_press(pressed): if(pressed): parse_result() draw_frame() def ANIM_btn_press(pressed): if(pressed): global animate animate = not animate draw_bottom_text() if animate: tim1.init(period=79, mode=Timer.PERIODIC, callback=lambda t:animate_frame()) tim2.init(period=1151, mode=Timer.PERIODIC, callback=lambda t:randomize_state()) tim3.init(period=71119, mode=Timer.PERIODIC, callback=lambda t:init_screen()) else: tim1.deinit() tim2.deinit() tim3.deinit() display.flush() def A_btn_press(pressed): if pressed: global seed parse_result() seed = seed + "A" draw_input_text() display.flush() def B_btn_press(pressed): if pressed: global seed parse_result() seed = seed + "B" draw_input_text() display.flush() def CLEAN_btn_press(pressed): if(pressed): init_screen() def BCKSPC_btn_press(pressed): if(pressed): global seed seed = seed[0:-1] parse_result() display.drawRect(10 + display.getTextWidth(seed, "roboto_regular18"), 23, 13, 25, True, display.WHITE) display.drawText(10, 25, seed, display.BLUE, "roboto_regular18") display.flush() def RULEUP_btn_press(pressed): if(pressed): global rules_selection global start_vec global vec rules_selection = (rules_selection + 1) % len(rulesets) parse_result() draw_rule_text() display.flush() def RULEDOWN_btn_press(pressed): if(pressed): global rules_selection global start_vec global vec rules_selection = (rules_selection - 1) % len(rulesets) parse_result() draw_rule_text() display.flush() def EXIT_btn_press(pressed): if(pressed): tim1.deinit() tim2.deinit() tim3.deinit() mch22.exit_python() # Attach button functions buttons.attach(buttons.BTN_UP, RULEUP_btn_press) buttons.attach(buttons.BTN_DOWN, RULEDOWN_btn_press) buttons.attach(buttons.BTN_LEFT, BCKSPC_btn_press) buttons.attach(buttons.BTN_SELECT, CLEAN_btn_press) buttons.attach(buttons.BTN_START, DRAW_btn_press) buttons.attach(buttons.BTN_MENU, ANIM_btn_press) buttons.attach(buttons.BTN_A, A_btn_press) buttons.attach(buttons.BTN_B, B_btn_press) buttons.attach(buttons.BTN_HOME, EXIT_btn_press) # Init screen display.drawFill(display.WHITE) draw_input_text() draw_rule_text() draw_bottom_text() display.flush()