Sudoko Game Board
This is a little Suduko game I wrote -- it doesn't solve the puzzle for you, but it does give you a game board you can edit and it will flag rows, columns, or boxes that are not valid. I originally wrote it in response to a question on the wxPython mailing list about how to draw a Suduko board. While doing that, I needed a data structure to hold the game, so I built one with numpy.
It comes with a bunch of puzzles I found on the web. The File->New Game menu will bring up a new game.
This is a demo of both how to do custom drawing with wxPython, and how to use some of numpy's nifty features for storing and manipulating a 2-dimensional array and various views on that array.
It also uses a nifty "about" dialog class for wxPython, and shows some features for developing multi-platform apps with wx.
I've just tested it with:
- Python 2.6.6
- numpy 1.5.1
- wxPython 2.8.11
But I started writing it a good while ago, so It should work with older (and probably newer) versions as well. enjoy!
- -- Chris Barker
code
1 #!/usr/bin/env python
2 """
3 Yet another Sudoku Puzzle program.
4
5 This one does not provide puzzles, nor does it help you solve them.
6
7 However, it does display them, and will highlight the appropriate row, column,
8 or box if there is an error in the puzzle at any time, as you add numbers, etc.
9
10 What's unique about this one is the use of numpy arrays. Numpy arrays have two
11 properties that make them handy for this problem:
12
13 1) n-d arrays (in this case 2-d)
14 2) slices as views on the data
15
16 The whole puzzle is a 9x9 array
17 each box is a 3x3 sub-array
18 each row is a length 9 sub-array
19 each column is a length 9 sub-array
20
21 These all share the same memory
22
23 -Chris.Barker@noaa.gov
24
25 """
26 license="""This code is released under the creative commons Public Domain dedication:
27
28 I have dedicated this work to the public domain by waiving all of my rights to
29 the work worldwide under copyright law, including all related and neighboring
30 rights, to the extent allowed by law.
31
32 You can copy, modify, distribute and perform the work, even for commercial
33 purposes, all without asking permission
34
35 http://creativecommons.org/publicdomain/zero/1.0/
36 """
37
38 import random
39 import wx
40 import numpy as np
41
42 class PuzzleGrid:
43 def __init__(self):
44 self.Grid = np.zeros((9,9), np.uint8)
45 Boxes = []
46 for i in range(3):
47 for j in range(3):
48 Boxes.append(self.Grid[3*i:3*i+3, 3*j:3*j+3])
49
50 self.Boxes = Boxes
51
52 def SetValue(self, (r,c), v):
53 self.Grid[r,c] = v
54
55 def GetValue(self, (r, c)):
56 return self.Grid[r,c]
57
58 def Solved(self):
59 """
60 returns True is the puzzle is solved, False otherwise
61 """
62 raise NotImplementedError
63
64 def CheckRows(self):
65 """
66 returns a values for each row:
67 0 -- repeated values
68 1 -- valid, but not solved
69 2 -- solved
70
71 """
72 results = np.zeros((9,), np.uint8 )
73 for i in range(9):
74 results[i] = self.CheckValid(self.Grid[i,:])
75 return results
76
77 def CheckColumns(self):
78 """
79 returns a values for each row:
80 0 -- repeated values
81 1 -- valid, but not solved
82 2 -- solved
83
84 """
85 results = np.zeros((9,), np.uint8 )
86 for i in range(9):
87 results[i] = self.CheckValid(self.Grid[:,i])
88 return results
89
90 def CheckBoxes(self):
91 """
92 returns a values for each row:
93 0 -- repeated values
94 1 -- valid, but not solved
95 2 -- solved
96
97 """
98 results = np.zeros((9,), np.uint8 )
99 for i in range(9):
100 results[i] = self.CheckValid(self.Boxes[i])
101 return results
102
103
104 def CheckValid(self, A):
105 """
106 CheckValid(A) -- checks if A has any digits repeated.
107
108 returns 0 is there are any digits repeated (invalid)
109 returns 1 if none are repeated, but there are zeros (valid, but not solved)
110 returns 2 if all digits, 1-9 are there (solved)
111
112 A should be a numpy array that has 9 elements
113 """
114
115 there = []
116 for i in A.flat:
117 if i>0 and i in there:
118 return 0
119 else:
120 there.append(i)
121 if 0 in there:
122 return 1
123 return 2
124
125 def LoadFromString(self, str):
126 """
127 loads a puzzle from a single "flat" ascii string of all the entries
128 """
129 self.Grid.flat[:] = np.fromstring(str, dtype=np.uint8)-48
130
131 def __str__(self):
132 msg = []
133 for i in range(9):
134 if not i%3:
135 msg.append("|-----------------------|\n")
136 msg.append("| %i %i %i | %i %i %i | %i %i %i |\n"%tuple(self.Grid[i]))
137 msg.append("|-----------------------|\n")
138 return "".join(msg)
139
140
141 class Grid:
142 def __init__(self, w, h):
143 size = min(w,h)
144 self.d = d = (size - 20) / 9
145 self.x0 = (w - (self.d * 9)) / 2
146 self.y0 = (h - (self.d * 9)) / 2
147 self.font_size = int(11 * d/16.0)
148 ##figure out the text offset
149 dc = wx.ScreenDC()
150 dc.SetFont(wx.FontFromPixelSize((self.font_size, self.font_size),
151 wx.FONTFAMILY_SWISS,
152 wx.FONTSTYLE_NORMAL,
153 wx.FONTWEIGHT_BOLD,
154 )
155 )
156 w,h = dc.GetTextExtent("5")
157 self.text_off_x = ( d - w )/2+2 # I don't know why I need to add the 2!
158 self.text_off_y = ( d - h )/2+2
159
160 class GridWindow(wx.Window):
161 def __init__(self, parent, *args, **kwargs):
162 wx.Window.__init__(self, parent, *args, **kwargs)
163 self.SetBackgroundColour("White")
164
165 self.Puzzle = PuzzleGrid()
166
167 self.InvalidRows = []
168 self.InvalidColumns = []
169 self.InvalidBoxes = []
170
171 self.Selected = (0,0)
172
173 self.Bind(wx.EVT_PAINT, self.OnPaint)
174 self.Bind(wx.EVT_SIZE, self.OnSize)
175 self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
176 self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
177
178 self.OnSize()
179 def NewPuzzle(self, str):
180 """
181 sets up a new puzzle from the given ascii string
182 """
183 self.Puzzle.LoadFromString(str)
184 self.DrawNow()
185
186 def InitBuffer(self):
187 w, h = self.GetClientSize()
188 self.buffer = wx.EmptyBitmap(w, h)
189 self.DrawNow()
190
191 def OnSize(self, event=None):
192 size = self.GetClientSize()
193 if size[0] > 0 and size[1] > 1:
194 self.Grid = Grid(*size)
195 self.InitBuffer()
196
197 def DrawNow(self):
198 dc = wx.BufferedDC(wx.ClientDC(self), self.buffer)
199 self.Draw(dc)
200
201 def Draw(self, dc):
202 # Make grid info local:
203 d = self.Grid.d
204 x0 = self.Grid.x0
205 y0 = self.Grid.y0
206 font_size = self.Grid.font_size
207 text_off_x = self.Grid.text_off_x
208 text_off_y = self.Grid.text_off_y
209
210 # draw the background:
211 dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
212 dc.Clear()
213 dc.SetBrush(wx.Brush(wx.Color(128,128,255)))
214 dc.SetPen(wx.TRANSPARENT_PEN)
215 dc.DrawRectangle(x0, y0, d*9, d*9 )
216
217 #draw The invalid rows
218 for i in self.InvalidRows:
219 dc.SetBrush(wx.Brush("Purple", wx.SOLID))
220 dc.SetPen(wx.TRANSPARENT_PEN)
221 dc.DrawRectangle(x0, y0 + i*d, 9*d, d )
222
223 #draw The invalid columns
224 for i in self.InvalidColumns:
225 dc.SetBrush(wx.Brush("Purple", wx.SOLID))
226 dc.SetPen(wx.TRANSPARENT_PEN)
227 dc.DrawRectangle(x0 + i*d, y0, d, 9*d )
228
229 #draw The invalid boxes
230 for i in self.InvalidBoxes:
231 dc.SetBrush(wx.Brush("Purple", wx.SOLID))
232 dc.SetPen(wx.TRANSPARENT_PEN)
233 r = i//3
234 c = i%3
235 dc.DrawRectangle(x0 + c*3*d, y0 + r*3*d, 3*d, 3*d )
236
237 # draw the selected cell:
238 dc.SetBrush(wx.Brush("Red", wx.SOLID))
239 dc.DrawRectangle(x0 + d*self.Selected[1], y0 + d*self.Selected[0], d, d)
240
241 # draw the white lines:
242 dc.SetPen(wx.Pen("White", 2, wx.SOLID) )
243 for i in range(10):
244 dc.DrawLine(x0, y0 + d*i, x0 + d*9, y0 + d*i)
245 dc.DrawLine(x0 + d*i, y0, x0 + d*i, y0 + d*9)
246
247 # draw the numbers:
248 dc.SetFont(wx.FontFromPixelSize((font_size,font_size),
249 wx.FONTFAMILY_SWISS,
250 wx.FONTSTYLE_NORMAL,
251 wx.FONTWEIGHT_BOLD))
252 for i in range(9):
253 for j in range(9):
254 val = self.Puzzle.Grid[i,j]
255 if val > 0:
256 dc.DrawText('%i'%val, x0 + d*j + text_off_x, y0 + d*i + text_off_y)
257
258 # Draw the Big Grid
259 dc.SetPen(wx.Pen("Black", 3, wx.SOLID))
260 dc.SetBrush(wx.TRANSPARENT_BRUSH)
261
262 d*=3
263 for i in range(4):
264 dc.DrawLine(x0, y0 + d*i, x0 + d*3, y0 + d*i)
265 dc.DrawLine(x0 + d*i, y0, x0 + d*i, y0 + d*3)
266
267
268 def OnPaint(self, event):
269 dc = wx.BufferedPaintDC(self, self.buffer)
270
271 def CheckValid(self):
272 self.InvalidRows = np.nonzero(self.Puzzle.CheckRows() == 0)[0]
273 self.InvalidColumns = np.nonzero(self.Puzzle.CheckColumns() == 0)[0]
274 self.InvalidBoxes = np.nonzero(self.Puzzle.CheckBoxes() == 0)[0]
275
276 def OnLeftDown(self, e):
277 """called when the left mouse button is pressed"""
278 x, y = e.GetPositionTuple()
279 i = (y - self.Grid.y0) / self.Grid.d
280 j = (x - self.Grid.x0) / self.Grid.d
281 if i >= 0 and i < 9 and j >= 0 and j < 9:
282 self.Selected = (i,j)
283 self.DrawNow()
284
285 def OnKeyDown(self, e):
286 keycode = e.GetKeyCode()
287 i, j = self.Selected
288 if (keycode == wx.WXK_TAB or
289 keycode == wx.WXK_RIGHT or
290 keycode == wx.WXK_RETURN or
291 keycode == wx.WXK_SPACE):
292 j += 1
293 elif keycode == wx.WXK_UP:
294 i -= 1
295 elif keycode == wx.WXK_DOWN:
296 i += 1
297 elif keycode == wx.WXK_LEFT:
298 j -= 1
299 elif (keycode == wx.WXK_DELETE or
300 keycode == wx.WXK_BACK):
301 self.Puzzle.Grid[self.Selected] = 0
302 self.CheckValid()
303 elif keycode >= ord("0") and keycode <= ord("9"):
304 self.Puzzle.Grid[self.Selected] = (keycode - ord("0"))
305 self.CheckValid()
306 j += 1
307 if j > 8:
308 j = 0
309 i += 1
310 if j < 0:
311 j = 8
312 i -= 1
313 if i > 8:
314 i = 0
315 if i < 0:
316 i = 8
317
318 self.Selected = (i,j)
319 self.DrawNow()
320
321 def SetValue(self, value):
322 self.Puzzle.Grid[self.Selected] = value
323
324 def test_PuzzleGrid():
325 P = PuzzleGrid()
326 print P
327 print "These should all be true:"
328 # all valid, butnot solved
329 print P.CheckValid(np.array( (1,2,0,4,0,6,0,8,9), dtype=np.uint8 ) ) == 1
330 print P.CheckValid(np.array( (0,0,0,0,0,0,0,0,0), dtype=np.uint8 ) ) == 1
331 print P.CheckValid(np.array( (1,2,0,4,5,6,7,8,9), dtype=np.uint8) ) == 1
332
333 # solved
334 print P.CheckValid(np.array( (1,2,3,4,5,6,7,8,9), dtype=np.uint8) ) == 2
335 print P.CheckValid(np.array( (1,2,9,4,5,6,7,8,3), dtype=np.uint8) ) == 2
336 print P.CheckValid(np.array( (9,8,7,6,5,4,3,2,1), dtype=np.uint8) ) == 2
337
338 # all not valid
339 print P.CheckValid(np.array( (1,1,0,4,0,6,0,8,9), dtype=np.uint8 ) ) == 0
340 print P.CheckValid(np.array( (1,0,0,4,0,6,0,9,9), dtype=np.uint8 ) ) == 0
341 print P.CheckValid(np.array( (1,1,1,4,4,6,0,1,1), dtype=np.uint8 ) ) == 0
342
343
344 class MainFrame(wx.Frame):
345 def __init__(self, parent):
346 wx.Frame.__init__(self, parent, title="Sudoku Machine", size=(500, 500))
347 self.grid = GridWindow(self)
348 wx.CallAfter(self.OnNewGame)# so that the grid is fully initialized
349 ## Build the menu
350 MenuBar = wx.MenuBar()
351
352 FileMenu = wx.Menu()
353 item = FileMenu.Append(wx.ID_ANY, text = "&New Game")
354 self.Bind(wx.EVT_MENU, self.OnNewGame, item)
355 item = FileMenu.Append(wx.ID_EXIT, text = "&Exit")
356 self.Bind(wx.EVT_MENU, self.OnQuit, item)
357 MenuBar.Append(FileMenu, "&File")
358
359 HelpMenu = wx.Menu()
360 item = HelpMenu.Append(wx.ID_HELP, "&Help",
361 "Help for this simple test")
362 self.Bind(wx.EVT_MENU, self.OnHelp, item)
363 item = HelpMenu.Append(wx.ID_ABOUT, "&About",
364 "More information About this program")
365 self.Bind(wx.EVT_MENU, self.OnAbout, item)
366 MenuBar.Append(HelpMenu, "&Help")
367
368 self.SetMenuBar(MenuBar)
369
370 def OnNewGame(self,evt=None):
371 """
372 Sets up a new randomly chosen game
373 """
374 i = random.randint(0, len(Puzzles)-1)
375 self.grid.NewPuzzle(Puzzles[i])
376
377 def OnQuit(self,evt=None):
378 self.Destroy()
379
380 def OnHelp(self, event):
381 dlg = wx.MessageDialog(self, "This would be help\n"
382 "If there was any\n",
383 "Test Help", wx.OK | wx.ICON_INFORMATION)
384 dlg.ShowModal()
385 dlg.Destroy()
386
387 def OnAbout(self, event):
388 dlg = AboutDialog(None,
389 #icon1=wx.Bitmap("Images/GNOME64.png"),
390 #icon2=wx.Bitmap("Images/NOAA.png"),
391 short_name='Suduko',
392 long_name='A Sudoko Puzzle demo program',
393 version = "1.0",
394 description="This is a simple Sudoku puzzle program, written in Python, designed to demonstrate some features of the wxPython and numpy packages",
395 urls = ["http://www.seapig.org/SudukoGameBoard",
396 "mailto:Chris.Barker@noaa.gov"],
397 licence=licence,
398 developers = ["Chris Barker"])
399 dlg.ShowModal()
400 dlg.Destroy()
401
402
403 ## this is a bunch of puzzles I found here:
404 ## http://mapleta.maths.uwa.edu.au/~gordon/sudokumin.php
405 ## there are a LOT there, this is just a few of them
406 ##
407 ## they are licenced under a Creative Commons Attribution 2.5 License.
408 ## http://creativecommons.org/licenses/by/2.5/
409 Puzzles = """000000010400000000020000000000050407008000300001090000300400200050100000000806000
410 000000010400000000020000000000050604008000300001090000300400200050100000000807000
411 000000012000035000000600070700000300000400800100000000000120000080000040050000600
412 000000012003600000000007000410020000000500300700000600280000040000300500000000000
413 000000012008030000000000040120500000000004700060000000507000300000620000000100000
414 000000012040050000000009000070600400000100000000000050000087500601000300200000000
415 000000012050400000000000030700600400001000000000080000920000800000510700000003000
416 000000012300000060000040000900000500000001070020000000000350400001400800060000000
417 000000012400090000000000050070200000600000400000108000018000000000030700502000000
418 000000012500008000000700000600120000700000450000030000030000800000500700020000000
419 000000012700060000000000050080200000600000400000109000019000000000030800502000000
420 000000012800040000000000060090200000700000400000501000015000000000030900602000000
421 000000012980000000000600000100700080402000000000300600070000300050040000000010000
422 000000013000030080070000000000206000030000900000010000600500204000400700100000000
423 000000013000200000000000080000760200008000400010000000200000750600340000000008000
424 000000013000500070000802000000400900107000000000000200890000050040000600000010000
425 000000013000700060000508000000400800106000000000000200740000050020000400000010000
426 000000013000700060000509000000400900106000000000000200740000050080000400000010000
427 000000013000800070000502000000400900107000000000000200890000050040000600000010000
428 000000013020500000000000000103000070000802000004000000000340500670000200000010000
429 000000013040000080200060000609000400000800000000300000030100500000040706000000000
430 000000013040000080200060000906000400000800000000300000030100500000040706000000000
431 000000013040000090200070000607000400000300000000900000030100500000060807000000000
432 000000013040000090200070000706000400000300000000900000030100500000060807000000000
433 000000013200800000300000070000200600001000000040000000000401500680000200000070000
434 000000013400200000600000000000460500010000007200500000000031000000000420080000000
435 000000013400800000200000070000400900001000000060000000000501600380000200000070000
436 000000014000000203800050000000207000031000000000000650600000700000140000000300000
437 000000014000020000500000000010804000700000500000100000000050730004200000030000600
438 000000014000708000000000000104005000000200830600000000500040000030000700000090001
439 000000014008005000020000000000020705100000000000000800070000530600140000000200000
440 000000014008005000020000000000020805100000000000000700070000530600140000000200000
441 000000014008009000020000000000020805100000000000000700070000930600140000000200000
442 000000014700000000000500000090014000050000720000600000000900805600000900100000000
443 000000014790000000000200000000003605001000000000000200060000730200140000000800000
444 000000014970000000000200000000003605001000000000000200060000730200140000000800000
445 000000015000400070300060000800000200000104000400500000000023600010000000070000000
446 000000015000400070400000000609000300000100800000700000500030200000060040010000000
447 000000015000800070300000000408000300000100400000700000500040200000090060010000000
448 000000015000800070400000000609000300000100800000700000500030200000060040010000000
449 000000015000830000000000200023000800000001000080000000105040000000600720900000000
450 000000015000830000000000200026000800000001000080000000105040000000300720900000000
451 000000015000900070400000000608000300000100800000700000500030200000060040010000000
452 000000015000900070400000000609000300000100800000700000500030200000060040010000000
453 000000015000900080300000000704000300000100400000800000500040200000070060010000000
454 000000015000900080400000000704000300000100900000800000500030200000070060010000000
455 000000015020060000000000408003000900000100000000008000150400000000070300800000060
456 000000015040080000000000300000040260500107000900000000300500000080000400000900000
457 000000015300600000000000080600050200000001000000000040010200700000760300008000000
458 000000015790000000000200000000008706001000000000000900070000830400150000000300000
459 000000016000500040300070000900000200000408000700600000000023700040000000010000000
460 000000016000708000000000050501200000300000800600000000040000200000053000080010000
461 000000016000900080500000000405000300000100500000800000600040200000030070010000000
462 000000016040005000000020000000600430200010000300000500000003700100800000002000000
463 000000016070000040050200000400060300000005200000041000000900780100000000000000000
464 000000016070000040050200000400060300000008200000041000000500790100000000000000000
465 000000016200000000000300000601700002000900500400000000030000800000060040050040000
466 000000016200080000009000000000420500010000000000000200000106030500000780000900000
467 000000017090600000000000030400500200001000000000080000720000600000410500000003000
468 000000017090600000000000050200000803000050400000001000600200300041070000000000000
469 000000017090800000000000040007060300050000200000001000600300800401000000000050000
470 000000017300080000000000000007100006000040300085000000200000840010700000000500000
471 000000017600020000000000000153000000000080200007000000400301500020000600000700000
472 000000018020500000000000000040000700600000500000041000000700260108300000400000000
473 000000018050600000000000030400500200001000000000090000820000600000410700000003000
474 000000018200400000000000070000008003000500200010000000502000600000040300000017000
475 000000018320000000400000000008051000040000300000070000706000090000300700000200000
476 000000018700040000000000030420000700000001000000300000500070200601800000040000000
477 000000019000250000000000000091000030000400700030000000400000208200060500000001000
478 000000019030050000000000020109000000000400700000870000000102000060000800500000300
479 000000019030050000000000020109000000000400800000870000000102000060000700500000300
480 000000019070000030200800000050600200001000000000200000000019500600000400000030000
481 000000019300600000000000000600080500040000300000010000480000070000200400010900000
482 000000019500600000000000000600080500040000300000010000380000040000200700010900000
483 000000019500600000000000000600080500040000300000010000480000070000200400010900000
484 000000019500800000000000000300070500040000300000010000470000060000200400010900000
485 000000019800500000000000000300070500040000300000010000470000060000200400010900000
486 000000021000030070040080000100207000050000400000000003200100000000040500000600000
487 000000021000083000000040000500200070080000400030900000000060800100500000200000000
488 000000021000083000000040000500200070080000400030900000000060800100700000200000000
489 000000021000306000000800000400010600000700300200000000000090040530000000086000000
490 000000021000407000000008000031060000000000750020000000500210000400000800000300000
491 000000021000500030400600000000021000800000007500000600000400800010070000030000000
492 000000021004090000070000030100203000500800000006000000200000600000060400030000000
493 000000021005080000600000000000670300120000500400000000000201040003000000080000000
494 000000021006800000000000070070021000020000400000005000500430600100000000000600000
495 000000021030400000700000000100082000000000540000000000000560300290000000004700000
496 000000021030600000000080000201000050500400000000370000700002000080000300000000600
497 000000021040500000700000000100082000000000650000000000000610400320000000005700000
498 000000021040500000800000000700092000000000650000000000000610400320000000005800000
499 000000021040600000000000000201000050500800000000400300700020000060000800000300400
500 000000021050030000000800000102000070700300000000540000600002000030000400000000500
501 000000021060300000000708000100050040070000300000020000200040000000600800500000000
502 000000021060500000000090000400002000070000300000600000102400000000030640800000000
503 000000021060700000000000000402000000000600300500000700000340050080000600100002000
504 000000021070030000000040000100205040030000800000100000200600000000070300600000000
505 000000021070030000000090000100205040030000800000100000200600000000070300600000000
506 000000021070300000000000000402000000000700300600000800000540060090000500100002000
507 000000021070300000000408000100060050030000400000020000200050000000700800600000000
508 000000021080300000000409000100060050030000400000020000200070000000800900500000000
509 000000021090300000000000000402000000000700300600000700000540060080000500100002000
510 000000021090300000000060000201000050500400000000970000600002000080000300000000900
511 000000021090700000000000000000514000630000000000002000000600930001040000200000800
512 000000021300050000000000000500630000010000080000000500704000600600200000000108000
513 000000021300050000000000000500630000010000080000000900704000600600200000000108000
514 000000021300050000000000000500830000010000090000000500704000600600200000000109000
515 000000021300090000000000000500630000010000080000000500704000600600200000000108000
516 000000021300090000000000000500630000010000080000000900704000600600200000000108000
517 000000021300700000000000000060500300020000070000000800100040700500012000000006000
518 000000021300800000000000000060500700020000040000000300100040800500012000000006000
519 000000021300900000000000070200000400000060300000001000071040000000200508090000000
520 000000021400300000000000000000010600080000300020007000600000470500120000000800000
521 000000021400600000000000000000012800609000000000030000510000030000709600020000000
522 000000021400600000000000000000012900706000000000030000510000030000807600020000000
523 000000021430000000600000000201500000000006370000000000068000400000230000000070000
524 000000021500040000000000070000300600000020500010000000600000203003107000000008000
525 000000021500040000000600000031000080000070000020000000600300400405000700000200000
526 000000021500400000000000000300000570600080000000010000010605000082000000000007400
527 000000021500400000000800000021500000070000600000000030400000800300070000006020000
528 000000021503000000600000000000104060700000500000200000000480300010070000200000000
529 000000021600000030070900000000043700100000000000020000000600008002100000040000500
530 000000021700060000490000000000070900003800000020000000960000800000302000000100000
531 000000021700600000300500000000082000040010000500000000020040000000300700000000650
532 000000021750000000000000000070000890000201000000400000030090500100030000400000600
533 000000021800040000000000060090200000700000400000501000015000000000030900602000000
534 000000021800400000009000000600570040300000800000020000070900400021000000000000000
535 000000021800500000000060000030102000500000840000000000000780500620000000004000000
536 000000021800600000000050000030102000500000840000000000000780500620000000004000000
537 000000021800700000400005000023000060000800500010000000600000700000081000000030000
538 000000023000500080000100000020000900000400100580000000600009500000020070001000000
539 000000023000800010800400000032500000000000100070000000600070004100000500000003000
540 000000023010040000500000000100000400000200080000803000000050160040000700003000000
541 000000023010040000500000000100000400000200080000903000000050160040000700003000000
542 000000023010040000500000000100000400000600090000203000000050170040000800003000000
543 000000023010800000000000060300020000050000700000400000000507100002010000600000400
544 000000023080000070400020000030002000000000401000060500100000600000807000000300000
545 000000023080000070500090000030002000000000401000060500100000600000807000000300000
546 000000023300010000000500060400000700000106000000200000092000100000040800060000000
547 000000023400800000100000900050032000000000400000060000000401800030000050000900000
548 000000023400800000100000900050032000000000400000070000000401800030000060000900000
549 000000023480000000010000000503000060000010800000000000170000400000602000000300005
550 000000023600010000000400000000080700502000000000000100080203000010000640000500000
551 000000023600700000000000080000038500200000800000010000000200640003400000010000000
552 000000023800000050000100000010600400507030000000000000300052000064000100000000000
553 000000024000010000000000080107000900300800100000200000020400060500070300000000000
554 000000024000010000000000080307000100100800500000200000020400060500070300000000000
555 000000024000080010600005000000300700040700000010000000000040501300600000200000000
556 000000024007000000006000000500090100000300600020000000940000050000607300000800000
557 000000024010008000000070000600201500400000003000000000070000810500430000000000000
558 000000024010300000060000000050000300000082000700000000400100500200000063008000000
559 000000024010300000070000000060000300000029000800000000400100600200000075009000000
560 000000024010300000070000000060000300000082000500000000400100600200000075008000000
561 000000024100000000000600000000180700020000009030500000500070600004002000000000030
562 000000024100000000000700000000560800020000009030100000600080700004002000000000030
563 000000024100800000000000003000400500700000100000030000000510600002000050030007000
564 000000024600800000100000000000040010070000300040600000520004000000000806000070000
565 000000024700000060000900000004001000020050000000030700000400800300000500600200000
566 000000024900700000000000000800000730000041000000000000002500800046000300010020000
567 000000025000000070800000000600000103000070400000020000053100000020005000000600300
568 000000025000800010400000000050000700000300600010000000600020400800007000000015000
569 000000025000800010900000000050000700000300900010000000600020400800007000000015000
570 000000025030006000000090000000740000600500000020000700000208300504000000000000100
571 000000025050000040000100000207000000300000070000800600089000100000002700000040000
572 000000025080000600000001000300400700000050008000000000000280400107000030000500000
573 000000025190000000000600000006030700000000100002000000400205000060000340000800000
574 000000026000080040000500000100600700300000080000020000000703100042000000000000500
575 000000026000080040000500000100600700300000080000020000000903100042000000000000500
576 000000026040700000000000001000900800400000500001000000000012050070000300300060000
577 000000026080003000000070000100400800605200000007000300030000900000050000000600000
578 000000026501000000000000000070206000300000150000800000020700000000000540000010300
579 000000026800500000000000704300070100000040000000000030000300810040900000060000000
580 000000026800700000000000005700030100000006500000020000026400000000000810030000000
581 000000027000051000000000600504000100000200000300000000020740000060000039000000500
582 000000027010900000500000060000300400600000050000000008049000100000026000000000300
583 000000027010900000500000060000300400600000050000000008094000100000026000000000300
584 000000027040800000000000001000400900600000500001000000000012050080000300300070000
585 000000027300000040100000000000605100000100500040000000070020030008000600000040000
586 000000027300000040100000000000605100000100500040000000070040030008000600000020000
587 000000028000050000000040000708200000040000300000600000600801000030000450000000900
588 000000028000070040000300000074000050000600300000001000630000100200040000000000600
589 000000028000500060010000000506020000400000300000000100000100700000403000680000000
590 000000028000800030100000000000070400080600000035000000700060100000000705000300000
591 000000028030000050600000000100050604000062000000000700028000000000700300000100000
592 000000028070009000000000003000302000040000500000000000800050100000040760300600000
593 000000028300000070000100000000080030049000000050000600000604100000500400200000000
594 000000029000306000000000008060000500053000000000020000000600150200070400900000000
595 000000029000600070010000000507020000400000300000000100000100800000403000790000000
596 000000029000730000000050080000600700082000000000000100400100600000002050100000000
597 000000029000730000000400060203000400000100300600000000080050100000002000010000000
598 000000029000730000000400060208000300000100500600000000070050100000002000010000000
599 000000029000830000000400070203000600000100300700000000040050100000002000010000000
600 000000029000830000000400070203000600000100300700000000080050100000002000010000000
601 000000029300600000000080070800000600000021000000000100029000000000800030000400500
602 000000029300700000000800040600000700000042000000000100049000000000010050000300600
603 000000031000079000000000000013200000004000700000100000500040670280000000000300000
604 000000031000407000000600000600300000407000000500080000030010000020000700000000450
605 000000031000602000000700000007000600010080000400030000000500270140000000800000000
606 000000031004020000080000000100300000000008200600000000020000740300510000000600000
607 000000031004020000080000000600300000000008200100000000020000740300510000000600000
608 000000031004020000090000000700300000000008200100000000050000840300610000000700000
609 000000031005020000080000000700300000000008400100000000040000250300610000000700000
610 000000031007020000080000000100300000000008200600000000020000740300510000000600000
611 000000031007020000080000000600300000000008200100000000020000740300510000000600000
612 000000031007020000080000000600300000000008200100000000040000720300510000000600000
613 000000031008020000070000000600300000000008200100000000020000740300510000000600000
614 000000031008020000090000000600300000000009200100000000040000720300510000000600000
615 000000031008020000090000000700300000000009400100000000050000240300610000000700000
616 000000031020500000000000000301070000000400200700000500070200600800010000000000080
617 000000031020700000008500000000016200400030000050000000300000050000200700000040000
618 000000031028000000000000000000208400730000060000500000160070000000400200300000000
619 000000031040060000000009000060005200000300070500000000308100000000020400000000700
620 000000031050060000000007000070004600000300050600000000403100000000020500000000800
621 000000031050070000000009000070006400000300050600000000403100000000020500000000800
622 000000031050080000000000000600307000040000500000100020100000800000050400003200000
623 000000031060040000000000000002801400500300010000007000000050600730000000100000000
624 000000031060200000000708000300050040070000200000010000100040000000600800500000000
625 000000031060400000000000000500037000090000200000001000700840000000600490100000000
626 000000031060500000000020000000460500300007000800000000000700080100003000020000600
627 000000031080000070000920000401000000000200800300000000090000250000080600000001000
628 000000031080040000070000000106300070300000000000080000540000800000600200000100000
629 000000031080400000600000000000200840700600000100000000500073000090000200000010000
630 000000031080600000000070000000700290500400000300000000020050800000031000400000000
631 000000031200040000000000000031700080000020500400000000000803000500000200000100600
632 000000031200070000000009000000301040600400000708000000000060200030500000000000700
633 000000031200080000000400000031005060000720800000000000000603000400000200700000000
634 000000031200700000400000000038000060000400300010000000000514000700000200000080000
635 000000031280000000000000000003610000000004270000000000420000800500070400000300000
636 000000031280000000500100000000037800600000200000040000030000040100500000000600000
637 000000031400020000000007000000301050700500000206000000000080200030600000000000400
638 000000031400020000000009000000301050600500000208000000000070200030600000000000400
639 000000031400020000000009000000301050700500000204000000000080200030600000000000400
640 000000031400020000000009000000301050700500000206000000000080200030600000000000400
641 000000031400020000010500000000300060200006000800000000000700800060000200039000000
642 000000031400070000208000000700000200000300000000900000630000090000580400000020000
643 000000031500070000000006000700000560001400000020000700600000800030100000000200000
644 000000031600008000000050000000370020580000000060000000200000600007100000000400800
645 000000031600020000000070000050108000200000600000300070000040200030500000700000000
646 000000031600200000000090000000080290310000000400000000049000500000603000000700000
647 000000031600800000000000000030000850020010000000400000804000600006030000700005000
648 000000031700020000000006000040100050030080000000000200600400900200005000000300000
649 000000031700200000000480000000700800030000000060000000000039060520000400800000000
650 000000031700200000040000000502700060000800700030000000000093000200000500000010000
651 000000031740000000000000009000003460200000500000090000000570800030800000001000000
652 000000031800020000200000000037100060010080500000000000500400800060300000000000000
653 000000031800060000000000000600000470000100600500200000023500000000070800010000000
654 000000031800900000000000040400000800000060200000001000031050000000200407090000000
655 000000032000100000050000000040000800000310000000602000300000760000080500802000000
656 000000032000100000060000000803000000000600900000007500000580070040000100200030000
657 000000032010000000000300000309700000000060100800000400200000080000540000000016000
658 000000032010040000000000000000307020084000000600000000000080104700100500300000000
659 000000032010040000000000000000703020084000000600000000000080104700100500300000000
660 000000032040000000900000000302700050000100800600000000070000100080060000000030006
661 000000032480000000010000000503000060000010800000000000170000400000602000000300005
662 000000034000100000000000060070000200005003000040050000000740100300000800600200000
663 000000034000100007800000090980000200600040000000700000000009800007030000010000000
664 000000034060200000000000070000960800301000000700800000070003000900000200000010000
665 000000034080100000000000060000039000000040800001000000360200000400000700000700500
666 000000034100000000000000050020050700043000000000010000900600800000400100000302000
667 000000034500000010000070000405310000000000200100000000000600700087000000020400000
668 000000034500900000000000000004700100060000200038000000200000507000036040000000000
669 000000034600900000000000000004700100050000200038000000200000607000043050000000000
670 000000034700005000000000010000087200000020500010000000200300060001400000000000900
671 000000034800600000000100000605000100000040070200090000043000000000000201090000000
672 000000035000020070000010000000240000800000600100000000020507000000300800070000100
673 000000035040000080100000000007000200000085000600000000000400106030100700008000000
674 000000035200100000080000000040000700000200040005003000300070006000040200000000100
675 000000035490000000010000000603000070000010900000000000180000400000502000000300006
676 000000036000000020800000000700000104000030500000020000064100000030006000000700400
677 000000036000500040000700000000200705108000000600000000340060000050000200000010000
678 000000036000500040000700000000200705108000000600000000340060000070000200000010000
679 000000036007100000000040050405003000000700200000000100010200800300000000090000000
680 000000036030000050200000000000060800700000400000053000000700210060900000001000000
681 000000036040200000010000000000004019008000200600030000700050000000100800300000000
682 000000036200030000500000001400070200010000000000000080308000400000501000000600000
683 000000036200030000500000001700080200010000000000000080309000400000501000000600000
684 000000036800010000000020000030602000000000190000500800100000900060000070000300000
685 000000036800700000000000090090000001060000020000500400000039000004000800700000500
686 000000036840000000000000020000203000010000700000600400000410050003000200600000000
687 000000036900040000000000010000103000200000400000600050007500200000060800010000000
688 000000037002000050010000000000200104000001600300400000700063000000000200000080000
689 000000037004600000000000010078000200000007500000010000310000020000800600400000000
690 000000037040600000000000010096000200000005800000010000107000050000400600300000000
691 000000037060000040500000000100040502000083000000000600037000000000500100000200000
692 000000037400200000000000000107000040000800200300500000000031000080000500060000400
693 000000037500000040090000000000510200003000900060000000200000160000703000000800000
694 000000037900040000000000010000103000200000400000700060006500200000070800010000000
695 000000038000000710900400000000017000600000900000003000000650200003000060010000000
696 000000038000009001000500020000460500800200000100000000040000600000021000700000000
697 000000038000020000000090000800000200000600100007300000000701060290000500040000000
698 000000038060020000007000050500400000000060700000000100100508000040000600000300000
699 000000038090200000000000510740000600000003070000010000005600200003000000100000000
700 000000038200050000000400010800000600000001000000200000041000500000620700030000000
701 000000038200400000000070010800000500000001000000200000071000400000520600030000000
702 000000038600001000000000050100200700800000004000750000025030000000000100030000000
703 000000038700040000000000010000108000200000600000300040006500200000060700010000000
704 000000039000070080000140000600000500200600000000003070000200600083000000000000100
705 000000039000140000000060080000500200083000000000000100500200700000003060200000000
706 000000039000140000000080070000500200037000000000000100500200600000003040200000000
707 000000039000140000000080070000600200037000000000000100500200600000003040600000000
708 000000039000600040800100000500000600000020070000004000000280700043000000000000100
709 000000039000740000000050080000600700083000000000000100100200600000003050200000000
710 000000039000740000000050080000600700083000000000000100100200600000003050600000000
711 000000039500070000000000010000503000400000200000600000003000860000240700010000000
712 000000039700400000003000010480000200000030700000001000040600500000000020000090000
713 000000039700400000003000010680000200000030700000001000040600500000000020000090000
714 000000039700400000003000010840000200000030700000001000080600500000000020000090000
715 000000041000062000000000000000710030602000500500000000310400000000008200040000000
716 000000041000700000300000000000045060700000300020010000000800200045000000601000000
717 000000041000700000300000000000045060700000800020010000000900200045000000601000000
718 000000041005080000600000000000670200410000500300000000000104030002000000080000000
719 000000041007300000000000520000800300420000000500000007060004200000010000008000000
720 000000041009300000000000520000800300420000000500000007060004200000010000008000000
721 000000041020000050800000000000280700060030000001000000300000807000501600000000000
722 000000041020060000800070000300400600000002000000100000000030700010500000005000030
723 000000041020500000000000000000084060570000000000000200000120300804000000600700000
724 000000041020500000000000000000094070580000000000000200000620300904000000700800000
725 000000041020700000000000000400013000070000200600000000000270500103000060000800000
726 000000041050080000000000000600107000030000500000400020400000800000050300001600000
727 000000041050800000090000000000007020000041000000000503700260800100000000000300000
728 000000041050900000070000000000008020000041000000000503800760900100000000000300000
729 000000041060800000000300000200054070080000000000001000000630800700000200400000000
730 000000041060900000070000000000008020000041000000000305800720600100000000000300000
731 000000041070060000030000000400201050060000700000800000000050300100400000200000000
732 000000041070200000000308000400060050020000300000010000100050000000700800600000000
733 000000041080030000200000000500060700002000300400008000000500020010400000000000800
734 000000041080070000030000000600201050070000800000900000000050300100400000200000000
735 000000041090700000000080000000800290600500000400000000030060900000041000500000000
736 000000041200500000000007000500000200000040600000036000034000000010000030000800500
737 000000041200600000530000000700080300000041000000000060008300000000500200040000000
738 000000041200700000000000006000300800090000500060040000700000230300060000000001000
739 000000041300020000000500000015000000000070600080000000600000370200104000000800000
740 000000041320000000500000000600300200004000080000500000200000300000081000000740000
741 000000041500020000000800000018000000000030600090000000600000350700104000000900000
742 000000041500300000200000000000260300010000060700500000080041000000080200000000000
743 000000041500900000070600000000350600402000000800000000000040080090000300030000000
744 000000041520000000000030000000070530100800000400000000600105000030000200000400000
745 000000041600000000000800000500600200040000070000300000000071600002000300070040000
746 000000041600300000000020000040100080000506000700000000300000500000070300010004000
747 000000041630000000000800000010000070070030000000020500500104000200000600000700000
748 000000041700050000200000000000801030650000700000400000081600000000020900000000000
749 000000041700090000200000000030104000040200000008000500100050600000000080000000700
750 000000041700600000200500000000081000030040000500000000010030000000200700000000650
751 000000041800020000000000000040509000007000200000000800600000390200410000000700000
752 000000041800050000200000000000701030650000200000400000071600000000080900000000000
753 000000041800500000000000000200000860070140000000030000600008200000300500040000000
754 000000041900300000000000000300200800000010060200000000067040000010050000000800200
755 000000041900300000000000000300200900000010060200000000067040000010050000000800300
756 000000041900500000000000000200000960080140000000030000600009700000300500040000000
757 000000041900600000000200000000810300540000000002000000031040000700000600000000020
758 000000041900700000000000000200000960080140000000030000600009700000300500040000000
759 000000042000500080000001000000900300200000100400080000090060050010000700000800000
760 000000042100700000000000080600300500040000020000100000000060105090040000000000300
761 000000042100800000000000070600300500070000020000100000000060105090040000000000300
762 000000042500090000000000000006100700000030800024000000390000000000004006000200050
763 000000042600900000000000030500000800007600000020040000000508100034000000000000700
764 000000042650000000000800000100000600000045000700002000000100780002030000040000000
765 000000043000015000000200000000420000050000600000900000000008170403000000200000800
766 000000043000015000000200000000420000090000500000800000000007160403000000200000700
767 000000043000080050000001000700500600000304000100000000040200000000070100030000900
768 000000043000800070000020000060500800000304000001000000370000200000010900400000000
769 000000043010050000000000000000408030095000000700000000000090105800200600400000000
770 000000043010050000000000000000804030095000000700000000000090105800200600400000000
771 000000043050200000080009000060000800100030000000000000307510000000800200400000000
772 000000043100200000000000000000600700030000200005080000270100000000030065900000000
773 000000043200700000000000080600200500040000030000100000000060205090040000000000100
774 000000043200800000000000070600200500070000030000100000000060205090040000000000100
775 000000043500080000000000010000370500010000000000000200000104020005700000800000600
776 000000043800050000000000010007600200000080700010000000000104020600000500000300000
777 000000045000800020100000000005620000700000004000000700086000100000045000030000000
778 000000045700200000000100000106000200000050060300080000054000000000000302080000000
779 000000045800200000000100000106000200000050070300090000054000000000000302090000000
780 000000046000070010060020000108000000000500300400000500030000200000108000000400000
781 000000046000500010500000000709000300000100800000400000600030200000070050010000000
782 000000046000500010500000000709000300000100800000400000600030200000090050010000000
783 000000046000800010500000000709000300000100800000400000600030200000070050010000000
784 000000046000800010500000000709000300000100800000400000600030200000090050010000000
785 000000046005800000000000020160000300000300500020000000000267000309000000000040000
786 000000046020000300001000000000001730600000008000000000030000210400680000000500000
787 000000046020000700001000000000001830600000009000000000080000210400690000000500000
788 000000046050010000000000000000408030017000000600000000000070102300200500400000000
789 000000046100000000000000080000130200084005000000700000060084000300000100000200000
790 000000046700010000000030000040603000000000190000800700100000900020000080000400000
791 000000047010050000000000000000408030065000000700000000000060102300200500400000000
792 000000047300500000000000010709000600000010000000000200000200705041008000030000000
793 000000048600200000000700010000040060500000300002001000000350700010000000000000200
794 000000049000050060000030000400900000700800000000000300503000100060000200000702000
795 000000049700200000000800010000040070500000300002001000000360800010000000000000200
796 000000051000036000000000000040500080200000600000001000000020340010400700600000000
797 000000051000083000000040000600500020080000400030900000000070800500600000200000000
798 000000051000203000000400000050080060094000000000000300302000600700000200000050000
799 000000051000307000000008000021060000000000740050000000400150000300000800000200000
800 000000051000307000000800000500010700000600300200000000000090020430000000087000000
801 000000051000308000000100000090050040020000100000000000601700800400020000500000000
802 000000051000308000000100000090050060020000100000000000601700800400020000500000000
803 000000051000309000000100000080050040020000100000000000601700300400020000500000000
804 000000051000309000000100000080050060020000100000000000601700300400020000500000000
805 000000051000402000800070000200600400700000030000500000000030200016000000050000000
806 000000051000402000800070000200600400700000080000500000000030200016000000050000000
807 000000051000702000000400000050080030084000000000000700302000600700000200000050000
808 000000051020060000700040000640000300000105080200000000001800000300000600000000000
809 000000051020070000000000000000145000040000890000300000109500000000060200300000000
810 000000051020400000000000000000390200500080000000000400040600700100050080000200000
811 000000051020600000000000000000300780400900000100000000070005200600010000000040600
812 000000051020600000000000000070000200300050000000040800501000030400008000000200600
813 000000051030800000000000000000400830100700000200000000040006300700020000000010900
814 000000051040006000000300000105030000000000820700000000620000400000750000000100000
815 000000051040700000000000000000013700500020000060000400000600840100800000200000000
816 000000051040700000000000000090000700000051000000060030000406200300000800506000000
817 000000051040900000000300080107050000030000200000000000000209300605000000800000000
818 000000051060007000000030000000006200700000030500100000014000600000850700000000000
819 000000051060007000000030000000006200700000030500100000024000600000850700000000000
820 000000051060020000000000000000145000040000780000300000108500000000060200300000000
821 000000051060020000100700000000500030020030000040000000300000200000800400509000000
822 000000051060400000000000000000380600500070000000000400040600300100050070000200000
823 000000051060400000000000000000390600500080000000000400040600700100050080000200000
824 000000051070030000800000000000501040030000600000800000500420000001000300000000700
825 000000051080200000000000000930000800000014000000500000401000070000600200000380000
826 000000051080400000000000000000031009507000000040000000000700460100200000300000800
827 000000051090030000000000000070400620000501000000800000000070300504000000200000400
828 000000051090700000000000000000400930100500000200000000080006300700010000000020700
829 000000051200030000000000000000070620050400000000000300004501000600000830000700000
830 000000051200060000000000000000080720050400000000000600004501000600000230000800000
831 000000051200080000040030000017200000000000630000000400000507000600000300000100000
832 000000051200600000000800000071050000040300200000000600000010040600000300800000000
833 000000051200600000000800000071050000040300600000000200000010040600000300800000000
834 000000051200800000400000000010057000300000200000060400057000060000200300000000000
835 000000051260000000008600000000071020040050000000000300000300400500900000700000000
836 000000051300020000000800000042000000000090600010000000600000390700501000000400000
837 000000051300040000200000000056100000070600000000030800010500060400000300000000000
838 000000051400030000000800000250100000300000740000006000000040300060007000010000000
839 000000051400070000200000000037006400008000000000500000000020780510300000000000000
840 000000051400200000000000000000406200050300000070000000000075030608000400000010000
841 000000051400800000200000000010057000300000200000060400057000060000200300000000000
842 000000051460000000080000000000050670001020000300000000050000400200300000000109000
843 000000051600003000090040000012500000000007900400000000500000780000020000000100000
844 000000051600030000000000000000504090802600000000001000000020800700000300050100000
845 000000051600200000000000000000406200050300000070000000000075030408000600000010000
846 000000051700200000003000000004058000000010600600000200010000080260000000000300000
847 000000051700200000800000000054010030010030000000000200200700600030000000000000700
848 000000051800020000300000000017600000000030200050000090400700800060500000000000000
849 000000051800070000300000000040080700000400000005000000006501000030000870000000200
850 000000051800070000300000000040080700000600000005000000006501000030000870000000200
851 000000051800200000000000000040070300000051000090000000000309200507000060100000000
852 000000051800200000400000000010095000000000840030000000000760300250000000000800000
853 000000051800300000000000000520010000300000790000006000067000400000400300010000000
854 000000051800700000300600000000012000090050000600000000010040000000300800000000760
855 000000051803000000000000000250400000010000700000020300000506040007000200000100000
856 000000051900200000000000000451060000000400380000000000240000700000003200000050000
857 000000052000700040100000000010600000000030800024000000000200100000405000300000600
858 000000052000700040100000000010600000000030800042000000000200100000405000300000600
859 000000052003400000070000000030005600000020010000081000200000008000600700100000000
860 000000052005400000070000000030005600000020010000081000200000008000600700100000000
861 000000052009400000070000000030005600000020010000081000200000008000600700100000000
862 000000052400060000000000010070200000600000400000108000018000000000030700502000000
863 000000053000008010300400000000015020700000400006000000000720600010000000000000200
864 000000053000400006080000000506000700000010400300000020010000200000305000000700000
865 000000053160000000000000000400000607000305000000800000000024100003000020070010000
866 000000053600700000000000020000039500200000800000010000000200640003400000010000000
867 000000053700600000000000040024000000008050000000300000010040200600007000300000600
868 000000053800060000000000070000200800000705000100000000072003000000610400050000000
869 000000054000803000000000000105040000000200930600000000500007000000010002030000800
870 000000054010700000200000000000056000030000700080000000600100300004000072500000000
871 000000054010900000200000000000056000030000900070000000600100700004000082500000000
872 000000054070300000200000000010000700000045000000208000000670100800000300500000000
873 000000054100300000000000000000700300040000200006080000320100000000040076900000000
874 000000054200070000000010000060000730005400000000000000710000200800300000000500009
875 000000054300020000000000010003700200000080600010000000000105030600000800000400000
876 000000054300800000000000010041000060030008000000900700905000800000010000000000200
877 000000054700020000000010000060000730005400000000000000170000200200300000000500008
878 000000054700030000000000000000400016380070000020000000000500800105000000006000300
879 000000054900700000000000060006052000800000300000000700020300100040070000005000000
880 000000056003800000400000000000062000000000410000000300000450100060100000720000000
881 000000056080010000002000030000203000300600000010000900600700000000080400000000100
882 000000057000040000000000003000307060800500400100000000000080100070000200030600000
883 000000057000080010070020000301000000000600400500000600040000200000103000000500000
884 000000059000130000000000000340000020050009000000800600800000307000054000000000100
885 000000059700600000000300000059001000020040000000000130807000300000050000400000000
886 000000061000027000000000000704000200000100040300000000510000700000048000090600000""".split('\n')
887
888
889 """
890 Simple about Dialog class -- I like it better than the one that wxPython comes with
891
892 -Chris Barker
893
894
895
896 """
897
898 import wx
899 from wx.lib.hyperlink import HyperLinkCtrl
900
901 class AboutDialog(wx.Dialog):
902 """
903
904 """
905 def __init__(self, parent, icon1=None,
906 icon2=None,
907 short_name=None,
908 long_name=None,
909 version=None,
910 description=None,
911 urls=None,
912 licence=None,
913 developers = []):
914 wx.Dialog.__init__(self, parent)
915
916 self.icon1 = icon1
917 self.icon2 = icon2
918 self.short_name = short_name
919 self.long_name = long_name
920 self.version = version
921 self.version = version
922 self.description = description
923 self.urls = urls
924 self.licence = licence
925 self.developers = developers
926
927 self.Build()
928
929 def Build(self):
930
931 # Build the header
932 Header = wx.BoxSizer(wx.HORIZONTAL)
933 if self.icon1:
934 Header.Add(wx.StaticBitmap(self, bitmap=self.icon1), 0)
935 else:
936 Header.Add((64,64))
937 Header.Add((20,1),1)
938 if self.short_name:
939 Label = wx.StaticText(self, label=self.short_name)
940 of = Label.GetFont()
941 Font = wx.Font(int(of.GetPointSize() * 2), of.GetFamily(), wx.NORMAL, wx.FONTWEIGHT_BOLD)
942 Label.SetFont(Font)
943 Header.Add(Label, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5)
944 else:
945 Header.Add((1,1), 1)
946 Header.Add((20,1),1)
947 if self.icon2:
948 Header.Add(wx.StaticBitmap(self, bitmap=self.icon2), 0)
949 else:
950 Header.Add((64,64))
951 width = Header.MinSize[0]
952
953 # Now the rest;
954 MainSizer = wx.BoxSizer(wx.VERTICAL)
955
956 MainSizer.Add(Header, 0, wx.EXPAND|wx.ALIGN_CENTER|wx.ALL, 5)
957
958 if self.long_name:
959 Label = wx.StaticText(self, label=self.long_name)
960 of = Label.GetFont()
961 Font = wx.Font(int(of.GetPointSize() * 1.5), of.GetFamily(), wx.NORMAL, wx.NORMAL)
962 Label.SetFont(Font)
963 MainSizer.Add(Label, 0, wx.TOP|wx.RIGHT|wx.LEFT|wx.ALIGN_CENTER, 5)
964 width = max(width, Label.Size[0])
965
966 if self.version:
967 Label = wx.StaticText(self, label="version: "+self.version)
968 #of = Label.GetFont()
969 #Font = wx.Font(int(of.GetPointSize() * 1.5), of.GetFamily(), wx.NORMAL, wx.NORMAL)
970 #Label.SetFont(Font)
971 MainSizer.Add(Label, 0, wx.BOTTOM|wx.ALIGN_CENTER, 5)
972
973 if self.description:
974 Label = wx.StaticText(self, label=self.description)
975 #of = Label.GetFont()
976 #Font = wx.Font(int(of.GetPointSize() * 1.5), of.GetFamily(), wx.NORMAL, wx.NORMAL)
977 #Label.SetFont(Font)
978
979 Label.Wrap(max(250, 0.9*width))
980 MainSizer.Add(Label, 0, wx.ALL|wx.ALIGN_CENTER, 5)
981
982
983 if self.licence:
984 Label = wx.StaticText(self, label="License:")
985 of = Label.GetFont()
986 Font = wx.Font(of.GetPointSize(), of.GetFamily(), wx.NORMAL, wx.BOLD)
987 Label.SetFont(Font)
988 MainSizer.Add(Label, 0, wx.ALL|wx.ALIGN_LEFT, 5)
989 Label = wx.StaticText(self, label=self.licence)
990 Label.Wrap(max(250, 0.9*width))
991 MainSizer.Add(Label, 0, wx.ALL|wx.ALIGN_CENTER, 2)
992
993 if self.developers:
994 Label = wx.StaticText(self, label="Developed by:")
995 of = Label.GetFont()
996 Font = wx.Font(of.GetPointSize(), of.GetFamily(), wx.NORMAL, wx.BOLD)
997 Label.SetFont(Font)
998 MainSizer.Add(Label, 0, wx.ALL|wx.ALIGN_LEFT, 5)
999
1000 for developer in self.developers:
1001 Label = wx.StaticText(self, label=" "+developer)
1002 MainSizer.Add(Label, 0, wx.ALL|wx.ALIGN_LEFT, 0)
1003
1004 if self.urls:
1005 Label = wx.StaticText(self, label="For more information:")
1006 of = Label.GetFont()
1007 Font = wx.Font(of.GetPointSize(), of.GetFamily(), wx.NORMAL, wx.BOLD)
1008 Label.SetFont(Font)
1009 MainSizer.Add(Label, 0, wx.ALL|wx.ALIGN_LEFT, 5)
1010 for url in self.urls:
1011 Link = HyperLinkCtrl(self,
1012 label=url,
1013 URL=url)
1014 MainSizer.Add(Link, 0, wx.ALL|wx.ALIGN_CENTER, 2)
1015
1016 MainSizer.Add((1,5),1)
1017 MainSizer.Add(wx.Button(self, id=wx.ID_OK, label="Dismiss"), 0, wx.ALL|wx.ALIGN_RIGHT,5)
1018 SpaceSizer = wx.BoxSizer(wx.VERTICAL)
1019 SpaceSizer.Add(MainSizer, 0, wx.ALL, 10)
1020 self.SetSizerAndFit(SpaceSizer)
1021
1022
1023 if __name__ == '__main__':
1024 import sys
1025 if len(sys.argv) > 1 and sys.argv[1].lower() == 'test':
1026 test_PuzzleGrid()
1027 else:
1028 app = wx.App(0)
1029 frame = MainFrame(None)
1030 frame.Show(True)
1031 app.MainLoop()