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:

But I started writing it a good while ago, so It should work with older (and probably newer) versions as well. enjoy!

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()

SudukoGameBoard (last edited 2010-12-07 20:38:40 by 161)