17db96d56Sopenharmony_ci#!/usr/bin/env python3
27db96d56Sopenharmony_ci"""       turtle-example-suite:
37db96d56Sopenharmony_ci
47db96d56Sopenharmony_ci         tdemo_minimal_hanoi.py
57db96d56Sopenharmony_ci
67db96d56Sopenharmony_ciA minimal 'Towers of Hanoi' animation:
77db96d56Sopenharmony_ciA tower of 6 discs is transferred from the
87db96d56Sopenharmony_cileft to the right peg.
97db96d56Sopenharmony_ci
107db96d56Sopenharmony_ciAn imho quite elegant and concise
117db96d56Sopenharmony_ciimplementation using a tower class, which
127db96d56Sopenharmony_ciis derived from the built-in type list.
137db96d56Sopenharmony_ci
147db96d56Sopenharmony_ciDiscs are turtles with shape "square", but
157db96d56Sopenharmony_cistretched to rectangles by shapesize()
167db96d56Sopenharmony_ci ---------------------------------------
177db96d56Sopenharmony_ci       To exit press STOP button
187db96d56Sopenharmony_ci ---------------------------------------
197db96d56Sopenharmony_ci"""
207db96d56Sopenharmony_cifrom turtle import *
217db96d56Sopenharmony_ci
227db96d56Sopenharmony_ciclass Disc(Turtle):
237db96d56Sopenharmony_ci    def __init__(self, n):
247db96d56Sopenharmony_ci        Turtle.__init__(self, shape="square", visible=False)
257db96d56Sopenharmony_ci        self.pu()
267db96d56Sopenharmony_ci        self.shapesize(1.5, n*1.5, 2) # square-->rectangle
277db96d56Sopenharmony_ci        self.fillcolor(n/6., 0, 1-n/6.)
287db96d56Sopenharmony_ci        self.st()
297db96d56Sopenharmony_ci
307db96d56Sopenharmony_ciclass Tower(list):
317db96d56Sopenharmony_ci    "Hanoi tower, a subclass of built-in type list"
327db96d56Sopenharmony_ci    def __init__(self, x):
337db96d56Sopenharmony_ci        "create an empty tower. x is x-position of peg"
347db96d56Sopenharmony_ci        self.x = x
357db96d56Sopenharmony_ci    def push(self, d):
367db96d56Sopenharmony_ci        d.setx(self.x)
377db96d56Sopenharmony_ci        d.sety(-150+34*len(self))
387db96d56Sopenharmony_ci        self.append(d)
397db96d56Sopenharmony_ci    def pop(self):
407db96d56Sopenharmony_ci        d = list.pop(self)
417db96d56Sopenharmony_ci        d.sety(150)
427db96d56Sopenharmony_ci        return d
437db96d56Sopenharmony_ci
447db96d56Sopenharmony_cidef hanoi(n, from_, with_, to_):
457db96d56Sopenharmony_ci    if n > 0:
467db96d56Sopenharmony_ci        hanoi(n-1, from_, to_, with_)
477db96d56Sopenharmony_ci        to_.push(from_.pop())
487db96d56Sopenharmony_ci        hanoi(n-1, with_, from_, to_)
497db96d56Sopenharmony_ci
507db96d56Sopenharmony_cidef play():
517db96d56Sopenharmony_ci    onkey(None,"space")
527db96d56Sopenharmony_ci    clear()
537db96d56Sopenharmony_ci    try:
547db96d56Sopenharmony_ci        hanoi(6, t1, t2, t3)
557db96d56Sopenharmony_ci        write("press STOP button to exit",
567db96d56Sopenharmony_ci              align="center", font=("Courier", 16, "bold"))
577db96d56Sopenharmony_ci    except Terminator:
587db96d56Sopenharmony_ci        pass  # turtledemo user pressed STOP
597db96d56Sopenharmony_ci
607db96d56Sopenharmony_cidef main():
617db96d56Sopenharmony_ci    global t1, t2, t3
627db96d56Sopenharmony_ci    ht(); penup(); goto(0, -225)   # writer turtle
637db96d56Sopenharmony_ci    t1 = Tower(-250)
647db96d56Sopenharmony_ci    t2 = Tower(0)
657db96d56Sopenharmony_ci    t3 = Tower(250)
667db96d56Sopenharmony_ci    # make tower of 6 discs
677db96d56Sopenharmony_ci    for i in range(6,0,-1):
687db96d56Sopenharmony_ci        t1.push(Disc(i))
697db96d56Sopenharmony_ci    # prepare spartanic user interface ;-)
707db96d56Sopenharmony_ci    write("press spacebar to start game",
717db96d56Sopenharmony_ci          align="center", font=("Courier", 16, "bold"))
727db96d56Sopenharmony_ci    onkey(play, "space")
737db96d56Sopenharmony_ci    listen()
747db96d56Sopenharmony_ci    return "EVENTLOOP"
757db96d56Sopenharmony_ci
767db96d56Sopenharmony_ciif __name__=="__main__":
777db96d56Sopenharmony_ci    msg = main()
787db96d56Sopenharmony_ci    print(msg)
797db96d56Sopenharmony_ci    mainloop()
80