| 1 | n/a | #!/usr/bin/env python3 |
|---|
| 2 | n/a | """ turtle-example-suite: |
|---|
| 3 | n/a | |
|---|
| 4 | n/a | tdemo_minimal_hanoi.py |
|---|
| 5 | n/a | |
|---|
| 6 | n/a | A minimal 'Towers of Hanoi' animation: |
|---|
| 7 | n/a | A tower of 6 discs is transferred from the |
|---|
| 8 | n/a | left to the right peg. |
|---|
| 9 | n/a | |
|---|
| 10 | n/a | An imho quite elegant and concise |
|---|
| 11 | n/a | implementation using a tower class, which |
|---|
| 12 | n/a | is derived from the built-in type list. |
|---|
| 13 | n/a | |
|---|
| 14 | n/a | Discs are turtles with shape "square", but |
|---|
| 15 | n/a | stretched to rectangles by shapesize() |
|---|
| 16 | n/a | --------------------------------------- |
|---|
| 17 | n/a | To exit press STOP button |
|---|
| 18 | n/a | --------------------------------------- |
|---|
| 19 | n/a | """ |
|---|
| 20 | n/a | from turtle import * |
|---|
| 21 | n/a | |
|---|
| 22 | n/a | class Disc(Turtle): |
|---|
| 23 | n/a | def __init__(self, n): |
|---|
| 24 | n/a | Turtle.__init__(self, shape="square", visible=False) |
|---|
| 25 | n/a | self.pu() |
|---|
| 26 | n/a | self.shapesize(1.5, n*1.5, 2) # square-->rectangle |
|---|
| 27 | n/a | self.fillcolor(n/6., 0, 1-n/6.) |
|---|
| 28 | n/a | self.st() |
|---|
| 29 | n/a | |
|---|
| 30 | n/a | class Tower(list): |
|---|
| 31 | n/a | "Hanoi tower, a subclass of built-in type list" |
|---|
| 32 | n/a | def __init__(self, x): |
|---|
| 33 | n/a | "create an empty tower. x is x-position of peg" |
|---|
| 34 | n/a | self.x = x |
|---|
| 35 | n/a | def push(self, d): |
|---|
| 36 | n/a | d.setx(self.x) |
|---|
| 37 | n/a | d.sety(-150+34*len(self)) |
|---|
| 38 | n/a | self.append(d) |
|---|
| 39 | n/a | def pop(self): |
|---|
| 40 | n/a | d = list.pop(self) |
|---|
| 41 | n/a | d.sety(150) |
|---|
| 42 | n/a | return d |
|---|
| 43 | n/a | |
|---|
| 44 | n/a | def hanoi(n, from_, with_, to_): |
|---|
| 45 | n/a | if n > 0: |
|---|
| 46 | n/a | hanoi(n-1, from_, to_, with_) |
|---|
| 47 | n/a | to_.push(from_.pop()) |
|---|
| 48 | n/a | hanoi(n-1, with_, from_, to_) |
|---|
| 49 | n/a | |
|---|
| 50 | n/a | def play(): |
|---|
| 51 | n/a | onkey(None,"space") |
|---|
| 52 | n/a | clear() |
|---|
| 53 | n/a | try: |
|---|
| 54 | n/a | hanoi(6, t1, t2, t3) |
|---|
| 55 | n/a | write("press STOP button to exit", |
|---|
| 56 | n/a | align="center", font=("Courier", 16, "bold")) |
|---|
| 57 | n/a | except Terminator: |
|---|
| 58 | n/a | pass # turtledemo user pressed STOP |
|---|
| 59 | n/a | |
|---|
| 60 | n/a | def main(): |
|---|
| 61 | n/a | global t1, t2, t3 |
|---|
| 62 | n/a | ht(); penup(); goto(0, -225) # writer turtle |
|---|
| 63 | n/a | t1 = Tower(-250) |
|---|
| 64 | n/a | t2 = Tower(0) |
|---|
| 65 | n/a | t3 = Tower(250) |
|---|
| 66 | n/a | # make tower of 6 discs |
|---|
| 67 | n/a | for i in range(6,0,-1): |
|---|
| 68 | n/a | t1.push(Disc(i)) |
|---|
| 69 | n/a | # prepare spartanic user interface ;-) |
|---|
| 70 | n/a | write("press spacebar to start game", |
|---|
| 71 | n/a | align="center", font=("Courier", 16, "bold")) |
|---|
| 72 | n/a | onkey(play, "space") |
|---|
| 73 | n/a | listen() |
|---|
| 74 | n/a | return "EVENTLOOP" |
|---|
| 75 | n/a | |
|---|
| 76 | n/a | if __name__=="__main__": |
|---|
| 77 | n/a | msg = main() |
|---|
| 78 | n/a | print(msg) |
|---|
| 79 | n/a | mainloop() |
|---|