def test_fork_draws_lines_in_parallel(): assert (do_eval(":F:S", 1) == [ [ Line(Pt(0.0, 0.0), Pt(0.0, 10.0)), Line(Pt(0.0, 0.0), Pt(0.0, 10.0)), ], ])
def test_draw_in_different_size(): assert (do_eval("z=20 S() r=5 S()", 2) == [ [Line(Pt(0.0, 0.0), Pt(0, 10.0), size=20.0)], [ Line( Pt(0.0, 10.0), Pt(0.0, 20.0), size=20.0, color=(5.0, 0.0, 0.0, 100.0), ) ], ])
def test_For_myrange(): assert (do_eval( """ myrange={:(max) i=-1 {i+=1 If(i<max,{i},{endofloop})}} For(myrange(5),{:(i) x=i*10 D()}) """, 5) == [ [Dot(Pt(0.0, 0.0))], [Dot(Pt(10.0, 0.0))], [Dot(Pt(20.0, 0.0))], [Dot(Pt(30.0, 0.0))], [Dot(Pt(40.0, 0.0))], ])
def test_draw_in_different_size(): assert (do_eval("20=z:S5=r:S", 2) == [ [Line(Pt(0.0, 0.0), Pt(0, 10.0), size=20.0)], [ Line( Pt(0.0, 10.0), Pt(0.0, 20.0), size=20.0, color=(5.0, 0.0, 0.0, 100.0), ) ], ])
def test_For_over_double_array(): assert (do_eval( """ For( [[1,1],[2,2]], {:(it) x=Get(it,0) y=Get(it,1) D() } ) S() """, 3) == [[Dot(Pt(1.0, 1.0))], [Dot(Pt(2.0, 2.0))], [Line(Pt(2.0, 2.0), Pt(2.0, 12.0))]])
def test_past_fork_limit_lines_still_move_you(): assert (do_eval(":F:S", n=4, rand=None, max_forks=1) == [ [Line(Pt(0.0, 0.0), Pt(0.0, 10.0))], [Line(Pt(0.0, 10.0), Pt(0.0, 20.0))], [Line(Pt(0.0, 20.0), Pt(0.0, 30.0))], [Line(Pt(0.0, 30.0), Pt(0.0, 40.0))], ])
def step(self): try: parallel_commands = next(self.commands) if len(self.poss) < len(parallel_commands): increase_by = len(parallel_commands) - len(self.poss) self.poss += [Pt(0, 0) for _ in range(increase_by)] for i, command in enumerate(parallel_commands): if command is None: continue if type(command) == Line: self.poss[i] = command.end self.strokes.append(command) elif type(command) == Dot: self.poss[i] = command.pos self.strokes.append(command) elif type(command) == Elided: if type(command.item) == Line: self.poss[i] = command.item.end else: # Dot self.poss[i] = command.item.pos else: raise Exception("Unknown command: " + str(command)) self._prune() return True except StopIteration: return False
def _calc_step(env): th = theta(env) s = step_size(env) old_pos = pos(env) new_pos = Pt( old_pos.x + s * math.sin(th), old_pos.y + s * math.cos(th), ) return old_pos, new_pos
def test_lte_compares_numbers(): assert (do_eval( """ x=0 If(1<=2,{x+=1},{}) If(2<=1,{x+=10},{}) If(1<=1,{x+=100},{}) D() """, n=1, ) == [[Dot(Pt(101, 0))]])
def test_gte_compares_numbers(): assert (do_eval( """ one=1 two=2 x=0 If(one>=two,{x+=1},{}) If(two>=one,{x+=10},{}) If(one>=one,{x+=100},{}) D() """, n=1, ) == [[Dot(Pt(110, 0))]])
def test_double_equals_compares_numbers(): assert (do_eval( """ one=1 two=2 x=0 If(one==2,{x+=1},{}) If(2==one,{x+=10},{}) If(one==one,{x+=100},{}) If(one==two,{x+=1000},{}) D() """, n=1, ) == [[Dot(Pt(100, 0))]])
def test_turn_right_and_jump(): assert (do_eval_debug("90+d25=s:J:S", 4) == [ [( None, { "d": NumberValue(90.0) }, )], [( None, { "d": NumberValue(90.0), "s": NumberValue(25.0) }, )], [( None, { "x": NumberValue(25.0), "d": NumberValue(90.0), "s": NumberValue(25.0), "xprev": NumberValue(0.0), "yprev": NumberValue(0.0) }, )], [( Line(Pt(25.0, 0.0), Pt(50.0, 0.0)), { "x": NumberValue(50.0), "d": NumberValue(90.0), "s": NumberValue(25.0), "xprev": NumberValue(25.0), "yprev": NumberValue(0.0), }, )], ])
def test_repeat_starts_at_beginning_if_no_label(): assert (do_eval("90=d90+d:S", 2) == [ [Line(Pt(0.0, 0.0), Pt(0.0, -10.0))], [Line(Pt(0.0, -10.0), Pt(0.0, -20.0))], ])
def test_go_then_line_modified(): assert (do_eval("10=x15=y10+x1+y:L", 1) == [[Line(Pt(10.0, 15.0), Pt(20.0, 16.0))]])
def test_go_then_line(): assert (do_eval("10=x15=y20=x16=y:L", 1) == [[Line(Pt(10.0, 15.0), Pt(20.0, 16.0))]])
def test_draw_a_dot(): assert do_eval(":D", 1) == [[Dot(Pt(0.0, 0.0))]] assert do_eval("20=x15=y:D", 1) == [[Dot(Pt(20.0, 15.0))]]
def test_move_in_a_circle(): assert (do_eval(":S+d", 36) == [ [Line(Pt(0.0, 0.0), Pt(0.0, 10.0))], [Line(start=Pt(x=0.0, y=10.0), end=Pt(x=1.7, y=19.8))], [Line(start=Pt(x=1.7, y=19.8), end=Pt(x=5.2, y=29.2))], [Line(start=Pt(x=5.2, y=29.2), end=Pt(x=10.2, y=37.9))], [Line(start=Pt(x=10.2, y=37.9), end=Pt(x=16.6, y=45.6))], [Line(start=Pt(x=16.6, y=45.6), end=Pt(x=24.2, y=52.0))], [Line(start=Pt(x=24.2, y=52.0), end=Pt(x=32.9, y=57.0))], [Line(start=Pt(x=32.9, y=57.0), end=Pt(x=42.3, y=60.4))], [Line(start=Pt(x=42.3, y=60.4), end=Pt(x=52.2, y=62.2))], [Line(start=Pt(x=52.2, y=62.2), end=Pt(x=62.2, y=62.2))], [Line(start=Pt(x=62.2, y=62.2), end=Pt(x=72.0, y=60.4))], [Line(start=Pt(x=72.0, y=60.4), end=Pt(x=81.4, y=57.0))], [Line(start=Pt(x=81.4, y=57.0), end=Pt(x=90.1, y=52.0))], [Line(start=Pt(x=90.1, y=52.0), end=Pt(x=97.7, y=45.6))], [Line(start=Pt(x=97.7, y=45.6), end=Pt(x=104.1, y=37.9))], [Line(start=Pt(x=104.1, y=37.9), end=Pt(x=109.1, y=29.2))], [Line(start=Pt(x=109.1, y=29.2), end=Pt(x=112.6, y=19.8))], [Line(start=Pt(x=112.6, y=19.8), end=Pt(x=114.3, y=10.0))], [Line(start=Pt(x=114.3, y=10.0), end=Pt(x=114.3, y=0.0))], [Line(start=Pt(x=114.3, y=0.0), end=Pt(x=112.6, y=-9.8))], [Line(start=Pt(x=112.6, y=-9.8), end=Pt(x=109.1, y=-19.2))], [Line(start=Pt(x=109.1, y=-19.2), end=Pt(x=104.1, y=-27.9))], [Line(start=Pt(x=104.1, y=-27.9), end=Pt(x=97.7, y=-35.6))], [Line(start=Pt(x=97.7, y=-35.6), end=Pt(x=90.1, y=-42.0))], [Line(start=Pt(x=90.1, y=-42.0), end=Pt(x=81.4, y=-47.0))], [Line(start=Pt(x=81.4, y=-47.0), end=Pt(x=72.0, y=-50.4))], [Line(start=Pt(x=72.0, y=-50.4), end=Pt(x=62.2, y=-52.2))], [Line(start=Pt(x=62.2, y=-52.2), end=Pt(x=52.2, y=-52.2))], [Line(start=Pt(x=52.2, y=-52.2), end=Pt(x=42.3, y=-50.4))], [Line(start=Pt(x=42.3, y=-50.4), end=Pt(x=32.9, y=-47.0))], [Line(start=Pt(x=32.9, y=-47.0), end=Pt(x=24.2, y=-42.0))], [Line(start=Pt(x=24.2, y=-42.0), end=Pt(x=16.6, y=-35.6))], [Line(start=Pt(x=16.6, y=-35.6), end=Pt(x=10.2, y=-27.9))], [Line(start=Pt(x=10.2, y=-27.9), end=Pt(x=5.2, y=-19.2))], [Line(start=Pt(x=5.2, y=-19.2), end=Pt(x=1.7, y=-9.8))], [Line(start=Pt(x=1.7, y=-9.8), end=Pt(x=-0.0, y=-0.0))], ])
def test_multiply_by_variable(): assert do_eval("2=aa;aa~s:S", 1) == [[Line(Pt(0.0, 0.0), Pt(0.0, 20.0))]]
def test_define_custom_variable(): assert (do_eval("180=aa;aa~+d:S", 1) == [[Line(Pt(0.0, 0.0), Pt(0.0, -10.0))]])
def test_pass_symbol_to_operator(): assert do_eval("90=s;s~+d:S", 1) == [[Line(Pt(0.0, 0.0), Pt(90.0, 0.0))]]
def test_turn_right_and_move(): assert do_eval("90+d25=s:S", 1) == [[Line(Pt(0, 0), Pt(25, 0))]]
def test_repeat_starts_at_label_if_present(): assert (do_eval("90=d^90+d:S", 2) == [ [Line(Pt(0.0, 0.0), Pt(0.0, -10.0))], [Line(Pt(0.0, -10.0), Pt(-10.0, -10.0))], ])
def test_draw_in_different_colour(): assert (do_eval("0.9=r0.5=g0.1=b0.5=a:S0.1=a:S", 2) == [ [Line(Pt(0.0, 0.0), Pt(0, 10.0), color=(0.9, 0.5, 0.1, 0.5))], [Line(Pt(0.0, 10.0), Pt(0, 20.0), color=(0.9, 0.5, 0.1, 0.1))], ])
def test_turn_random_and_move(): def r(_a, _b): return 90 assert do_eval(":R~+d:S", n=1, rand=r) == [[Line(Pt(0, 0), Pt(10, 0))]]
def test_repeating_commands(): assert (do_eval("3:S", 3) == [ [Line(Pt(0.0, 0.0), Pt(0.0, 10.0))], [Line(Pt(0.0, 10.0), Pt(0.0, 20.0))], [Line(Pt(0.0, 20.0), Pt(0.0, 30.0))], ])
def assert_line(n): assert ( actuals[n] == [Line(Pt(0.0, n * 10.0), Pt(0., (n + 1) * 10.0))] * 20)
def test_parallel_past_fork_limit_lines_still_move_you(): # Fork into 2 lines, then proceed forwards, forking # each time. Should essentially act as if no forking # was happening. assert (do_eval(":F;f~=d90d^:S:F", n=4, rand=None, max_forks=2) == [ [ Line(Pt(0.0, 0.0), Pt(0.0, 10.0)), Line(Pt(0.0, 0.0), Pt(10.0, 0.0)), ], [ Line(Pt(0.0, 10.0), Pt(0.0, 20.0)), Line(Pt(10.0, 0.0), Pt(20.0, 0.0)), ], [ Line(Pt(0.0, 20.0), Pt(0.0, 30.0)), Line(Pt(20.0, 0.0), Pt(30.0, 0.0)), ], [ Line(Pt(0.0, 30.0), Pt(0.0, 40.0)), Line(Pt(30.0, 0.0), Pt(40.0, 0.0)), ], ])
def test_repeating_multiple_commands(): assert (do_eval("3:{:S90+d}", 3) == [ [Line(Pt(0.0, 0.0), Pt(0.0, 10.0))], [Line(Pt(0.0, 10.0), Pt(10.0, 10.0))], [Line(Pt(10.0, 10.0), Pt(10.0, 0.0))], ])
def test_strokes_inside_functions_work(): assert (do_eval(":{:S}", n=1) == [[Line(Pt(0.0, 0.0), Pt(0.0, 10.0))]])
def test_semicolon_to_separate_statements(): assert do_eval("s;s:S", 1) == [[Line(Pt(0.0, 0.0), Pt(0.0, 10.0))]]