Python and Turtle animation,Difficulty Level 10,games,list,python,recursion Tower of Hanoi with Python Turtle (Source Code Included)

Tower of Hanoi with Python Turtle (Source Code Included)

Tower of Hanoi is a puzzle where you need to move all the rings from peg 1 to peg 3.

Rules are: 1. You can only move one ring at each step. 2. You can not put a larger ring on top of a smaller ring.

Solve and animate the Tower of Hanoi problem with Python and Turtle.

Code

import turtle
import colorsys
import math

turtle.setup(1000,1000)
turtle.hideturtle()
turtle.title("Tower of Hanoi - PythonTurtle.Academy")
turtle.speed(0)
turtle.tracer(0,0)

n = 5
peg_height = 300
ring_height_max = 10
ring_width_max = 150
ring_width_min = 20
ring_delta = 15
ring_delta_max = 30
ring_height = 20
animation_step = 10

A = [] # List of rings in Peg A
B = []
C = []

T = [] # list of turtles

def draw_line(x,y,heading,length,pensize,color):
    turtle.up()
    turtle.goto(x,y)
    turtle.seth(heading)
    turtle.down()
    turtle.color(color)
    turtle.pensize(pensize)
    turtle.fd(length)
    
def draw_scene():
    turtle.bgcolor('light blue')
    draw_line(-600,-100,0,1200,10,'brown')
    for i in range(-250,251,250):
        draw_line(i,-93,90,peg_height,5,'black')

def initialize():    
    global ring_width_max,ring_width_min,ring_ratio,ring_delta
    for i in range(n):
        A.append(i)
        t = turtle.Turtle()
        t.hideturtle()
        t.speed(0)
        t.pencolor('red')
        t.fillcolor('light green')
        T.append(t)
    ring_delta = min(135/(n-1),ring_delta_max)
    
def draw_single_ring(r, x, k, extra=0):
    global ring_delta
    
    w = ring_width_max - ring_delta*(r-1)
    T[r].up()
    T[r].goto(x-w/2,-95+ring_height*k + extra)
    T[r].down()
    T[r].seth(0)
    T[r].begin_fill()
    for i in range(2):
        T[r].fd(w)
        T[r].left(90)
        T[r].fd(ring_height)
        T[r].left(90)
    T[r].end_fill()
    
def draw_rings():
    for i in range(len(A)):
        draw_single_ring(A[i],-250,i)
    for i in range(len(B)):
        draw_single_ring(B[i],0,i)
    for i in range(len(C)):
        draw_single_ring(C[i],250,i)
  
def move_ring(PP,QQ):
    if PP == "A":
        x = -250
        P = A
    elif PP == "B":
        x = 0
        P = B
    else:
        x = 250
        P = C

    if QQ =="A":
        x2 = -250
        Q = A
    elif QQ == "B":
        x2 = 0
        Q = B
    else:
        x2 = 250
        Q = C

    for extra in range(1,250-(-95+ring_height*(len(P)-1)),animation_step):
        T[P[len(P)-1]].clear()
        draw_single_ring(P[len(P)-1],x,len(P)-1,extra)
        turtle.update()

    T[P[len(P)-1]].clear()
    draw_single_ring(P[len(P)-1],x,len(P)-1,extra)
    turtle.update()
    tp = x
    if x2 > x:
        step = animation_step
    else:
        step = -animation_step
    for tp in range(x,x2,step):
        T[P[len(P)-1]].clear()       
        draw_single_ring(P[len(P)-1],tp,len(P)-1,extra)
        turtle.update()
    T[P[len(P)-1]].clear()
    draw_single_ring(P[len(P)-1],x2,len(P)-1,extra)
    turtle.update()
    Q.append(P[len(P)-1])
    del P[-1]
    for extra in range(250-(-95+ring_height*(len(Q)-1)),0,-animation_step):
        T[Q[len(Q)-1]].clear()
        draw_single_ring(Q[len(Q)-1],x2,len(Q)-1,extra)
        turtle.update()
    T[Q[len(Q)-1]].clear()
    draw_single_ring(Q[len(Q)-1],x2,len(Q)-1)
    turtle.update()   
    return

#move rings in X to Z
def tower_of_hanoi(X,Y,Z,n):
    if n == 1:
        move_ring(X,Z)
        return
    tower_of_hanoi(X,Z,Y,n-1)
    move_ring(X,Z)
    tower_of_hanoi(Y,X,Z,n-1)
    
draw_scene()
turtle.update()
n = int(turtle.numinput('Number of Rings','Please enter number of rings:',5,2,10))
initialize()
draw_rings()
tower_of_hanoi("A","B","C",n)
turtle.update()

Related Post