Welcome, guest | Sign In | My Account | Store | Cart

It's a simple solver of the problem of Hanoi Tower with a minimal GUI written in wxPython. It can handle just 10 plates, due to windows size..however it's very simple to modify this and the 'pure' solver is not affected by this limitation

Python, 121 lines
 ``` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121``` ```#author: A. Polino import wx import sys ## make sure the windows is focused than press any button, and the program will move a plate. keep ## pressing until the problem is solved ## by default it will display 5 plates. To change this, you have to call the script with a second ## argument, wich is the number of plates (max 10) def gen_hanoi(stack, start=1, temp=2, goal=3): if stack == 2: yield start, temp yield start, goal yield temp, goal else: for x in gen_hanoi(stack - 1, start, goal, temp): yield x yield start, goal for x in gen_hanoi(stack - 1, temp, start, goal): yield x class Plate(object): def __init__(self, x_len, x_start): self.x_len = x_len self.x_start = x_start def create_plates(num): assert num <= 10 x_start = 10 x_len = 100 plates = [] for x in xrange(num): plates.append(Plate(x_len, x_start)) x_len -= 10 x_start += 5 return plates class HanoiWindow(wx.Window): def __init__(self, parent, num): wx.Window.__init__(self, parent, id=-1, pos = wx.Point(0, 0), size=wx.DefaultSize, style=wx.SUNKEN_BORDER| wx.WANTS_CHARS|wx.FULL_REPAINT_ON_RESIZE) self.SetBackgroundColour(wx.NamedColour('white')) self.Bind(wx.EVT_PAINT, self.OnPaint) self.Bind(wx.EVT_KEY_UP, self.OnKeyUp) self.towers = [create_plates(num), [], []] self.solver = gen_hanoi(num) def OnPaint(self, evt): def draw_rect(x_len, x_start, y_start): dc = wx.PaintDC(self) font = dc.GetFont() font.SetPointSize(15) dc.SetFont(font) size, colour = 2, wx.NamedColour('black') dc.SetPen(wx.Pen(colour, size, wx.SOLID)) point = wx.Point(x_start, y_start) dc.DrawLines([point, point + wx.Point(x_len, 0)]) dc.DrawLines([point - wx.Point(0, 5), point + wx.Point(x_len, 0) - wx.Point(0, 5)]) dc.DrawLines([point, point - wx.Point(0, 5)]) dc.DrawLines([point + wx.Point(x_len, 0), point - wx.Point(0, 5) + wx.Point(x_len, 0)]) w, h = self.GetClientSizeTuple() buffer = wx.EmptyBitmap(w, h) dc = wx.PaintDC(self) font = dc.GetFont() font.SetPointSize(15) dc.SetFont(font) msg = 'Hanoi Towers' w, h = dc.GetTextExtent(msg) dc.DrawText(msg, 200, 20) size, colour = 8, wx.NamedColour('black') dc.SetPen(wx.Pen(colour, size, wx.SOLID)) for num in xrange(len(self.towers)): y_start = 300 tower = self.towers[num] num = num * 200 + 10 point = wx.Point(num, y_start) dc.DrawLines([point, point + wx.Point(120, 0)]) #base ## plates for plate in tower: y_start -= 10 draw_rect(plate.x_len, num + plate.x_start, y_start) def OnKeyUp(self, evt): try: from_, to = self.solver.next() self.towers[to-1].append(self.towers[from_-1].pop()) self.Refresh() except StopIteration: wx.MessageBox('Problem Solved!', 'Problem solved', wx.OK) class HanoiFrame(wx.Frame): def __init__(self, title, num): wx.Frame.__init__(self, parent=None, id=-1, title=title, size=(600, 500), pos=(200, 200)) self.Window = HanoiWindow(self, num) self.Bind(wx.EVT_CLOSE, self.close_frame) def close_frame(self, evt): sys.exit(0) class HanoiApp(wx.App): def OnInit(self): if len(sys.argv) < 2: num = 5 else: num = int(sys.argv[1]) hano = HanoiFrame('Hanoi Towers', num) hano.Show(True) self.SetTopWindow(hano) return True if __name__ == '__main__': fh = HanoiApp(0) fh.MainLoop() ```
 Created by A. Polino on Tue, 21 Dec 2010 (MIT)