Bulge Illusion with Python Turtle (Source Code Included)

This is another Akiyoshi illusion. It feels like the center is bulging.

Bulge Illusion

Source Code:

import turtle

screen = turtle.Screen()
screen.setup(800,800)
screen.setworldcoordinates(-8,-8,8,8)
screen.tracer(0,0)
screen.title('Bulge Illusion - PythonTurtle.Academy')
turtle.hideturtle()
turtle.speed(0)

color1 = 'light sky blue'
color2 = 'firebrick'
screen.bgcolor(color2)

def draw_square(x,y,size,c):
    turtle.up()
    turtle.goto(x-size/2,y-size/2)
    turtle.seth(0)
    turtle.color(c)
    turtle.begin_fill()
    for _ in range(4):
        turtle.fd(size)
        turtle.left(90)
    turtle.end_fill()
    
def draw_board():
    for x in range(-7,8,2):
        for y in range(-7,8,2):
            draw_square(x,y,1,color1)
    for x in range(-6,8,2):
        for y in range(-6,8,2):
            draw_square(x,y,1,color1)
            

def draw_diag(x,y):
    c = color2 if (x+y)%2 == 0 else color1
    if x*y > 0:
        draw_square(x-0.3,y+0.3,0.3,c)
        draw_square(x+0.3,y-0.3,0.3,c)
    elif x*y < 0:
        draw_square(x+0.3,y+0.3,0.3,c)
        draw_square(x-0.3,y-0.3,0.3,c)

def draw_straight(x,y):
    c = color2 if (x+y)%2 == 0 else color1
    if y>0:
        draw_square(x-0.3,y-0.3,0.3,c)
        draw_square(x+0.3,y-0.3,0.3,c)
    elif y<0:
        draw_square(x-0.3,y+0.3,0.3,c)
        draw_square(x+0.3,y+0.3,0.3,c)
    elif x>0:
        draw_square(x-0.3,y-0.3,0.3,c)
        draw_square(x-0.3,y+0.3,0.3,c)
    elif x<0:
        draw_square(x+0.3,y-0.3,0.3,c)
        draw_square(x+0.3,y+0.3,0.3,c)
        
def draw_bulge():
    for x in range(-6,7):
        for y in range(-6,7):
            if abs(x)+abs(y)<=7:
                draw_diag(x,y)
                if x==0 or y==0: draw_straight(x,y)
    x,y = -5,-3
    for i in range(3):
        draw_diag(x,y)
        draw_diag(-x,-y)
        draw_diag(x,-y)
        draw_diag(-x,y)
        x += 1
        y -= 1
draw_board()
draw_bulge()
screen.update()

Rolling Illusion with Python Turtle (Source Code Included)

Akiyoshi made this original rolling illusion. It feels like the cylinders are rolling. You may want to how to draw oval or ellipse for this project.

Rolling Illusion with Python Turtle

Source code:

import turtle
import math

screen = turtle.Screen()
screen.setup(1100,1000)
screen.setworldcoordinates(-620,-550,680,550)
screen.tracer(0,0)
screen.title('Roller Illusion - PythonTurtle.Academy')
turtle.hideturtle()
turtle.speed(0)
n=100
# parametric equation to draw ellipses
def ellipse(cx,cy,a,b,c1,c2,c3):
    t = -math.pi/2
    x = cx+a*math.cos(t)
    y = cy+b*math.sin(t)
    turtle.up()
    turtle.goto(x,y)
    turtle.down()
    turtle.pencolor(c1)
    turtle.fillcolor(c3)
    turtle.begin_fill()
    for i in range(n//2):
        x = cx+a*math.cos(t)
        y = cy+b*math.sin(t)
        turtle.goto(x,y)    
        t += 2*math.pi/n
    turtle.pencolor(c2)
    for i in range(n//2):
        x = cx+a*math.cos(t)
        y = cy+b*math.sin(t)
        turtle.goto(x,y)    
        t += 2*math.pi/n
    turtle.end_fill()

def rolling_column(x,size):
    for y in range(-400,500,100):
        ellipse(x,y,size,35,'white','black','dark orange')
        
def rolling_column2(x,size):
    for y in range(-400,500,100):
        ellipse(x,y,size,35,'black','white','dark orange')

def rolling():
    rolling_column(-450,10)
    rolling_column(-410,13)
    rolling_column(-360,16)
    rolling_column(-300,19)
    rolling_column(-240,16)
    rolling_column(-190,13)
    rolling_column(-150,10)

    rolling_column2(-130,10)
    rolling_column2(-90,13)
    rolling_column2(-40,16)
    rolling_column2(20,19)
    rolling_column2(80,16)
    rolling_column2(130,13)
    rolling_column2(170,10)

    rolling_column(190,10)
    rolling_column(230,13)
    rolling_column(280,16)
    rolling_column(340,19)
    rolling_column(400,16)
    rolling_column(450,13)
    rolling_column(490,10)
    
turtle.color('steel blue')
turtle.up()
turtle.goto(-1000,-1000)
turtle.down()
turtle.begin_fill()
turtle.seth(0)
for _ in range(4):
    turtle.fd(2000)
    turtle.left(90)
turtle.end_fill()
turtle.pensize(3)
rolling()
screen.update()
# the following generates high quality image
filename="rolling_illusion.eps" 
ts = turtle.getscreen()
ts.getcanvas().postscript(file=filename)

24 Game Solver with Python Turtle (Source Code Included)

24 Game is a mathematical puzzle that make 4 numbers make evaluate to 24 with basic arithmetical operators ( +, -, ×, ÷). For example, given 4 numbers 1,5,5,5, we can make expression (5-(1÷5))×5, which equals to 24.

We can use brute force to solve this problem with a Python Program. There are at most 24×5×4×4×4 = 7,680 different expressions can be made with 4 numbers. It may appear to be hard for us to do by hand, it should be very easy for computer program to solve. The following is the source code for this project:

import turtle
screen = turtle.Screen()
screen.setup(500,500)
screen.title("24 Game Solver - PythonTurtle.Academy")
turtle.hideturtle()
turtle.speed(0)
turtle.up()

def permutation(a):
    if len(a) == 1: return [[a[0]]]
    res = permutation(a[1:])
    r = []
    for x in res:
        # need to insert n into x: into all possible position
        for i in range(len(x)+1):
            y = x.copy()
            y.insert(i,a[0])
            if y not in r:
                r.append(y)
    return r

op = ['+', '−', '×', '÷']
def evaluate(a):
    v = []
    for x in a:
        if type(x) is int:
            v.append(x)
        else:
            num2 = v.pop()
            num1 = v.pop()
            if x=='+': v.append(num1+num2)
            elif x=='−': v.append(num1-num2)
            elif x=='×': v.append(num1*num2)
            else:
                if num2 != 0: v.append(num1/num2)
                else: return 0
    return v[0]


class tree_node:
    def __init__(self,value,left,right):
        self.value = value
        self.left = left
        self.right = right

def inorder(root):
    if type(root.value) is int: return str(root.value)
    if type(root.left.value) is not int: left = '('+inorder(root.left)+')'
    else: left = inorder(root.left)
    if type(root.right.value) is not int: right = '('+inorder(root.right)+')'
    else: right = inorder(root.right)    
    return left + root.value + right
    
def convert_to_infix(a):
    # convert to infix
    # convert to tree first
    v = list()
    for x in a:
        if type(x) is int:
            v.append(tree_node(x,None,None))
        else:
            t2 = v.pop()
            t1 = v.pop()
            v.append(tree_node(x,t1,t2))
    return inorder(v[0])
            
def twentyfour(a):
    # postfix
    # try n,n,n,n, p,p,p
    for i in range(4):
        for j in range(4):
            for k in range(4):
                b = a.copy()
                b.append(op[i])
                b.append(op[j])
                b.append(op[k])
                v = evaluate(b)
                if v==24.0:
                    return(convert_to_infix(b))

    # try n,n,n,p,p,n,p
    for i in range(4):
        for j in range(4):
            for k in range(4):
                b = a[:3]
                b.append(op[i])
                b.append(op[j])
                b.append(a[3])
                b.append(op[k])
                v = evaluate(b)
                if v==24.0:
                    return(convert_to_infix(b))

    # try n,n,n,p,n,p,p
    for i in range(4):
        for j in range(4):
            for k in range(4):
                b = a[:3]
                b.append(op[i])
                b.append(a[3])
                b.append(op[j])
                b.append(op[k])
                v = evaluate(b)
                if v==24.0:
                    return(convert_to_infix(b))

    # try n,n,p,n,p,n,p
    for i in range(4):
        for j in range(4):
            for k in range(4):
                b = a[:2]
                b.append(op[i])
                b.append(a[2])
                b.append(op[j])
                b.append(a[3])
                b.append(op[k])
                v = evaluate(b)
                if v==24.0:
                    return(convert_to_infix(b))
    # try n,n,p,n,n,p,p
    for i in range(4):
        for j in range(4):
            for k in range(4):
                b = a[:2]
                b.append(op[i])
                b.append(a[2])
                b.append(a[3])
                b.append(op[j])
                b.append(op[k])
                v = evaluate(b)
                if v==24.0:
                    return(convert_to_infix(b))
    return ''            

while True:
    fournumbers = []
    while len(fournumbers) != 4:
        numbers = screen.textinput("24 Game Solver", "Enter four numbers separated by spaces: ")
        fournumbers = list(map(int,numbers.split()))
    p = permutation(fournumbers)
    foundsolution = False
    turtle.clear()
    for a in p:
        r = twentyfour(a)
        if len(r)>0:
            turtle.goto(0,0)
            turtle.color('royal blue')
            turtle.write(r,font=('Courier', 45, 'bold'), align='center')
            foundsolution = True
            break
    if not foundsolution:
        turtle.color('red')
        turtle.write("No solution",font=('Courier', 45, 'bold'), align='center')