#JustForFun i created this Hilbert space-filling curve using #Python's #turtle module | #maths #math #programming

import logging
import random
import turtle
import time

SPEED_INT = 5  # 1-10 where 0 is as fast as possible
UNIT_DISTANCE = 30
logging.basicConfig(level=logging.DEBUG)

# Turtle setup
screen = turtle.getscreen()
t = turtle.getturtle()
turtle.title("Hilbert Space-filling Curve")
t.shape("turtle")
t.speed(SPEED_INT)
t.pensize(5)
t.pencolor((0, 0, 0))
t.penup()
turtle.setx(-500)
turtle.sety(-450)
t.pendown()
start_pos = t.pos()

time.sleep(1)

CW = 1
CCW = -1


def get_angle():
    fuzzyness = random.choice(range(0, 2))
    # degrees = 90 + fuzzyness
    degrees = 90
    return degrees


color_ = (0, 0, 0)

DIRECTION_UP = True
DIRECTION_DOWN = False

color_change_direction = (DIRECTION_UP, DIRECTION_UP, DIRECTION_UP)


def change_color():
    global color_
    global color_change_direction
    index_to_change = random.choice(range(0, 3))
    channel = color_[index_to_change]
    if color_change_direction:
        channel += 0.05
    else:
        channel -= 0.05
    if channel > 1.0:
        color_change_direction = not color_change_direction
        channel = 1.0
    elif channel < 0.0:
        color_change_direction = not color_change_direction
        channel = 0.0
    new_color = turtle.pencolor()
    new_color_list = list(new_color)
    new_color_list[index_to_change] = channel
    color_ = tuple(new_color_list)
    turtle.pencolor(color_)


def draw_recursive(i_direction: int, i_level: int):
    """Level 1 is the starting level (0 doesn't exist)"""
    if i_level == 1:
        change_color()

    def right_forward():
        t.right(i_direction * get_angle())
        t.forward(UNIT_DISTANCE)

    def forward_right():
        t.forward(UNIT_DISTANCE)
        t.right(i_direction * get_angle())

    if i_level > 1: draw_recursive(-i_direction, i_level - 1)
    if i_level % 2 == 0:
        right_forward()
    else:
        forward_right()
    if i_level > 1: draw_recursive(i_direction, i_level - 1)
    if i_level % 2 == 0:
        t.right(-i_direction * get_angle())
        t.forward(UNIT_DISTANCE)
        t.right(-i_direction * get_angle())
    else:
        t.forward(UNIT_DISTANCE)
    if i_level > 1: draw_recursive(i_direction, i_level - 1)
    if i_level % 2 == 0:
        forward_right()
    else:
        right_forward()
    if i_level > 1: draw_recursive(-i_direction, i_level - 1)


turtle.setheading(90)
draw_recursive(CW, 5)

t.hideturtle()
turtle.done()