# -*- coding: utf-8 -*-
import Tkinter as Tk
import time
import random
import sys
DEFAULTS = {'ymax': 7, 'xmax': 3, 'spc': 4, 'width': 320, 'height': 240,
'disc': '3', 'discs': (('3', 0), ('4', 0), ('5', 0), ('6', 0)),
'clock': '1', 'clocks': (('1', 0), ('5', 0), ('10', 1), ('STOP', 0)),
'text': 'Hello, work!', 'font': ('Helvetica', '24', 'bold'),
'colors': ('#fff', '#ff0', '#f0f', '#f00', '#0ff', '#0f0', '#00f', '#000')}
class MyLabel(Tk.Label):
def __init__(self, parent):
Tk.Label.__init__(self, parent, text=DEFAULTS['text'], font=DEFAULTS['font'])
self.bind_all('<1>', self.myevent)
self.after(1000, self.mytimer)
def myevent(self, event):
self.bg_change()
def mytimer(self):
self.bg_change()
self.fg_change()
self.after(1000, self.mytimer)
def bg_change(self):
self.configure(bg='#%01x%01x%01x' % (
random.randint(0, 15), random.randint(0, 15), random.randint(0, 15)))
def fg_change(self):
t = time.time()
self.configure(text='%s.%09d秒' % (
time.strftime('%Y年%m月%d日\n%H時%M分\n%S', time.localtime(t)),
(t - int(t)) * 1000000000))
class MyFrame(Tk.Frame):
def __init__(self, parent):
Tk.Frame.__init__(self, parent, width=DEFAULTS['width'], height=DEFAULTS['height'])
m = Tk.Menu(parent)
parent.configure(menu=m)
mDisc = Tk.Menu(m, tearoff=False)
self.kwDisc = Tk.StringVar(parent)
self.kwDisc.set(DEFAULTS['disc'])
for l, u in DEFAULTS['discs']:
mDisc.add_radiobutton(label=l, under=u, variable=self.kwDisc, value=l)
m.add_cascade(label='Disc', menu=mDisc, underline=0)
mClock = Tk.Menu(m, tearoff=False)
self.kwClock = Tk.StringVar(parent)
self.kwClock.set(DEFAULTS['clock'])
for l, u in DEFAULTS['clocks']:
mClock.add_radiobutton(label=l, under=u, variable=self.kwClock, value=l)
m.add_cascade(label='Clock', menu=mClock, underline=0)
self.pegs = []
for y in xrange(DEFAULTS['ymax']):
for x in xrange(DEFAULTS['xmax']):
l = Tk.Label(self, text='', font=DEFAULTS['font'], bg=DEFAULTS['colors'][0])
l.grid(row=y, column=x, sticky='news', padx=DEFAULTS['spc'], pady=DEFAULTS['spc'])
self.pegs.append(l)
l = MyLabel(self)
l.grid(row=0, column=DEFAULTS['xmax'], sticky='news', padx=DEFAULTS['spc'], pady=DEFAULTS['spc'])
self.pack()
self.running = False
self.bind('<Button-3>', self.showPopup)
self.callback_start()
def callback_start(self):
disc = self.kwDisc.get()
clock = self.kwClock.get()
if clock == 'STOP':
clock = DEFAULTS['clock']
self.kwClock.set(clock)
print '%s, %s' % (disc, clock)
if not self.running:
self.running = True
self.hanoi = Hanoi(int(disc))
self.after(1000 / int(clock), self.mytimer)
def mytimer(self):
disc = self.kwDisc.get()
clock = self.kwClock.get()
print '%s, %s' % (disc, clock), self.hanoi.stat()
try:
self.showPegs(self.hanoi.stat())
self.hanoi.next()
except StopIteration, e:
self.running = False
self.kwClock.set('STOP')
if clock != 'STOP':
self.after(1000 / int(clock), self.mytimer)
def showPegs(self, pegs):
for x in xrange(DEFAULTS['xmax']):
for i in xrange(DEFAULTS['ymax']):
self.pegs[DEFAULTS['xmax'] * i + x].configure(text=' ', bg=DEFAULTS['colors'][0])
for i, y in enumerate(pegs[x]):
self.pegs[DEFAULTS['xmax'] * (DEFAULTS['ymax'] - i - 1) + x].configure(text=' %d ' % y, bg=DEFAULTS['colors'][y])
def showPopup(self, event):
mPopup = Tk.Menu(self, tearoff=False)
mPopup.add_command(label='Start', under=0, command=self.callback_start)
mPopup.add_command(label='Exit', under=1, command=sys.exit)
mPopup.post(event.x_root, event.y_root)
class Hanoi(object):
def __init__(self, height):
self.pegs = [range(height, 0, -1), [], []]
self.gen = self.move(0, 1, 2, len(self.pegs[0]))
def stat(self):
return self.pegs
def move(self, src, dst, work, discs):
if discs == 0: raise StopIteration()
for m in self.move(src, work, dst, discs - 1): yield m
yield(src, dst)
for m in self.move(work, dst, src, discs - 1): yield m
def next(self):
src, dst = self.gen.next()
self.pegs[dst].append(self.pegs[src].pop())
if __name__ == '__main__':
root = Tk.Tk()
f = MyFrame(root)
root.mainloop()