How to create a game for wxPython - Part 1 (Phoenix)

Keywords : Tetris, Memory game, Reversi, The Towers of Hanoi, Game, Pygame.


Demonstrating :

Tested py3.x, wx4.x and Win10.

Are you ready to use some samples ? ;)

Test, modify, correct, complete, improve and share your discoveries ! (!)


Tetris

First example

img_tetris_1.png

   1 # tetris.py
   2 
   3 """
   4 ZetCode wxPython tutorial.
   5 
   6 This is Tetris game clone in wxPython.
   7 
   8 Author : Jan Bodnar
   9 Website : www.zetcode.com
  10 Link : http://zetcode.com/wxpython/thetetrisgame/
  11 Last modified : May 2018
  12 """
  13 
  14 import wx
  15 import random
  16 
  17 # class Tetris
  18 # class Board
  19 # class Tetrominoes
  20 # class Shape
  21 
  22 #---------------------------------------------------------------------------
  23 
  24 class Tetris(wx.Frame):
  25     """
  26     ...
  27     """
  28     def __init__(self, parent):
  29         style=wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER ^ wx.MAXIMIZE_BOX
  30         wx.Frame.__init__(self, parent, size=(220, 420), style=style)
  31 
  32         self.initFrame()
  33 
  34     #-----------------------------------------------------------------------
  35 
  36     def initFrame(self):
  37         """
  38         ...
  39         """
  40 
  41         self.statusbar = self.CreateStatusBar()
  42         self.statusbar.SetStatusText('0')
  43         self.board = Board(self)
  44         self.board.SetFocus()
  45         self.board.start()
  46 
  47         #------------
  48 
  49         # Creating the menubar.
  50         menu_bar = wx.MenuBar()
  51 
  52         # Setting up the menu.
  53         file_menu = wx.Menu()
  54 
  55         # wx.ID_ABOUT and wx.ID_EXIT are standard IDs provided by wxWidgets.
  56         item = file_menu.Append(wx.ID_ABOUT, "&About", "Information about Tetris.")
  57         self.Bind(wx.EVT_MENU, self.OnAbout, item)
  58         file_menu.AppendSeparator()
  59         item = file_menu.Append(wx.ID_EXIT, "E&xit", "Exit Tetris.")
  60         self.Bind(wx.EVT_MENU, self.OnQuit, item)
  61 
  62         # Create the "Help" top menu.
  63         help_menu = wx.Menu()
  64         item = help_menu.Append(wx.ID_HELP, "&Shortcuts", "Shortcuts for Tetris.")
  65         self.Bind(wx.EVT_MENU, self.OnHelp, item)
  66 
  67         # Adding the "file_menu" to the menu bar.
  68         menu_bar.Append(file_menu, "&File")
  69         menu_bar.Append(help_menu, "&Help")
  70 
  71         # Adding the menu bar to the frame content.
  72         self.SetMenuBar(menu_bar)
  73 
  74         #------------
  75 
  76         self.SetIcon(wx.Icon(".\icons\wxwin.ico"))
  77         self.SetTitle("Tetris")
  78 
  79         #------------
  80 
  81         self.CenterOnScreen(wx.BOTH)
  82 
  83 
  84     def OnQuit(self, event):
  85         self.Destroy()
  86 
  87 
  88     def OnAbout(self, event):
  89         dlg = wx.MessageDialog(self,
  90                                "This is a small game.\n",
  91                                "About Tetris",
  92                                wx.OK | wx.CENTRE | wx.ICON_INFORMATION)
  93         dlg.ShowModal()
  94         dlg.Destroy()
  95 
  96 
  97     def OnHelp(self, event):
  98         dlg = wx.MessageDialog(self,
  99                                "AZERTY keyboard :\n"
 100                                "--------------------\n"
 101                                "P \t---------> \tPause\n"
 102                                "S \t---------> \tLEFT\n"
 103                                "F \t---------> \tRIGHT\n"
 104                                "D \t---------> \tDOWN (rotated right)\n"
 105                                "E \t----------> \tUP (rotated left)\n"
 106                                "SPACE \t----> \tAccelerate\n"
 107                                "D \t---------> \tOne line down\n",
 108                                "Shortcuts",
 109                                wx.OK | wx.CENTRE | wx.ICON_INFORMATION)
 110         dlg.ShowModal()
 111         dlg.Destroy()
 112 
 113 #---------------------------------------------------------------------------
 114 
 115 class Board(wx.Panel):
 116     """
 117     ...
 118     """
 119 
 120     BoardWidth = 10
 121     BoardHeight = 22
 122     Speed = 300
 123     ID_TIMER = 1
 124 
 125     def __init__(self, *args, **kw):
 126         super(Board, self).__init__(*args, **kw)
 127 
 128         self.initBoard()
 129 
 130         #------------
 131 
 132         # Delete flickers.
 133         if wx.Platform == "__WXMSW__":
 134             self.SetDoubleBuffered(True)
 135 
 136     #-----------------------------------------------------------------------
 137 
 138     def initBoard(self):
 139         """
 140         ...
 141         """
 142 
 143         self.timer = wx.Timer(self, Board.ID_TIMER)
 144         self.isWaitingAfterLine = False
 145         self.curPiece = Shape()
 146         self.nextPiece = Shape()
 147         self.curX = 0
 148         self.curY = 0
 149         self.numLinesRemoved = 0
 150         self.board = []
 151 
 152         self.isStarted = False
 153         self.isPaused = False
 154 
 155         self.Bind(wx.EVT_PAINT, self.OnPaint)
 156         self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
 157         self.Bind(wx.EVT_TIMER, self.OnTimer, id=Board.ID_TIMER)
 158 
 159         self.clearBoard()
 160 
 161 
 162     def shapeAt(self, x, y):
 163         """
 164         ...
 165         """
 166 
 167         return self.board[(y * Board.BoardWidth) + x]
 168 
 169 
 170     def setShapeAt(self, x, y, shape):
 171         """
 172         ...
 173         """
 174 
 175         self.board[(y * Board.BoardWidth) + x] = shape
 176 
 177 
 178     def squareWidth(self):
 179         """
 180         ...
 181         """
 182 
 183         return self.GetClientSize().GetWidth() // Board.BoardWidth
 184 
 185 
 186     def squareHeight(self):
 187         """
 188         ...
 189         """
 190 
 191         return self.GetClientSize().GetHeight() // Board.BoardHeight
 192 
 193 
 194     def start(self):
 195         """
 196         ...
 197         """
 198 
 199         if self.isPaused:
 200             return
 201 
 202         self.isStarted = True
 203         self.isWaitingAfterLine = False
 204         self.numLinesRemoved = 0
 205         self.clearBoard()
 206 
 207         self.newPiece()
 208         self.timer.Start(Board.Speed)
 209 
 210 
 211     def pause(self):
 212         """
 213         ...
 214         """
 215 
 216         if not self.isStarted:
 217             return
 218 
 219         self.isPaused = not self.isPaused
 220         statusbar = self.GetParent().statusbar
 221 
 222         if self.isPaused:
 223             self.timer.Stop()
 224             statusbar.SetStatusText('paused')
 225         else:
 226             self.timer.Start(Board.Speed)
 227             statusbar.SetStatusText(str(self.numLinesRemoved))
 228 
 229         self.Refresh()
 230 
 231 
 232     def clearBoard(self):
 233         """
 234         ...
 235         """
 236 
 237         for i in range(Board.BoardHeight * Board.BoardWidth):
 238             self.board.append(Tetrominoes.NoShape)
 239 
 240 
 241     def OnPaint(self, event):
 242         """
 243         ...
 244         """
 245 
 246         dc = wx.PaintDC(self)
 247 
 248         size = self.GetClientSize()
 249         boardTop = size.GetHeight() - Board.BoardHeight * self.squareHeight()
 250 
 251         for i in range(Board.BoardHeight):
 252             for j in range(Board.BoardWidth):
 253 
 254                 shape = self.shapeAt(j, Board.BoardHeight - i - 1)
 255 
 256                 if shape != Tetrominoes.NoShape:
 257                     self.drawSquare(dc,
 258                         0 + j * self.squareWidth(),
 259                         boardTop + i * self.squareHeight(), shape)
 260 
 261         if self.curPiece.shape() != Tetrominoes.NoShape:
 262 
 263             for i in range(4):
 264 
 265                 x = self.curX + self.curPiece.x(i)
 266                 y = self.curY - self.curPiece.y(i)
 267 
 268                 self.drawSquare(dc, 0 + x * self.squareWidth(),
 269                     boardTop + (Board.BoardHeight - y - 1) * self.squareHeight(),
 270                     self.curPiece.shape())
 271 
 272 
 273     def OnKeyDown(self, event):
 274         """
 275         ...
 276         """
 277 
 278         if not self.isStarted or self.curPiece.shape() == Tetrominoes.NoShape:
 279             event.Skip()
 280             return
 281 
 282         keycode = event.GetKeyCode()
 283         print("Keycode :", keycode)
 284 
 285         if keycode == ord('P') or keycode == ord('p'):
 286             self.pause()
 287             return
 288 
 289         if self.isPaused:
 290             return
 291 
 292         #-----------------
 293         # AZERTY keyboard.
 294         #-----------------
 295         # elif keycode == wx.WXK_LEFT:
 296         elif keycode == ord('S') or keycode == ord('s'):
 297             self.tryMove(self.curPiece, self.curX - 1, self.curY)
 298 
 299         # elif keycode == wx.WXK_RIGHT:
 300         elif keycode == ord('F') or keycode == ord('f'):
 301             self.tryMove(self.curPiece, self.curX + 1, self.curY)
 302 
 303         # elif keycode == wx.WXK_DOWN:
 304         elif keycode == ord('D') or keycode == ord('d'):
 305             self.tryMove(self.curPiece.rotatedRight(), self.curX, self.curY)
 306 
 307         # elif keycode == wx.WXK_UP:
 308         elif keycode == ord('E') or keycode == ord('e'):
 309             self.tryMove(self.curPiece.rotatedLeft(), self.curX, self.curY)
 310 
 311         elif keycode == wx.WXK_SPACE:
 312             self.dropDown()
 313 
 314         elif keycode == ord('R') or keycode == ord('r'):
 315             self.oneLineDown()
 316 
 317         else:
 318             event.Skip()
 319 
 320 
 321     def OnTimer(self, event):
 322         """
 323         ...
 324         """
 325 
 326         if event.GetId() == Board.ID_TIMER:
 327 
 328             if self.isWaitingAfterLine:
 329                 self.isWaitingAfterLine = False
 330                 self.newPiece()
 331 
 332             else:
 333                 self.oneLineDown()
 334 
 335         else:
 336             event.Skip()
 337 
 338 
 339     def dropDown(self):
 340         """
 341         ...
 342         """
 343 
 344         newY = self.curY
 345 
 346         while newY > 0:
 347             if not self.tryMove(self.curPiece, self.curX, newY - 1):
 348                 break
 349             newY -= 1
 350 
 351         self.pieceDropped()
 352 
 353 
 354     def oneLineDown(self):
 355         """
 356         ...
 357         """
 358 
 359         if not self.tryMove(self.curPiece, self.curX, self.curY - 1):
 360             self.pieceDropped()
 361 
 362 
 363     def pieceDropped(self):
 364         """
 365         ...
 366         """
 367 
 368         for i in range(4):
 369 
 370             x = self.curX + self.curPiece.x(i)
 371             y = self.curY - self.curPiece.y(i)
 372             self.setShapeAt(x, y, self.curPiece.shape())
 373 
 374         self.removeFullLines()
 375 
 376         if not self.isWaitingAfterLine:
 377             self.newPiece()
 378 
 379 
 380     def removeFullLines(self):
 381         """
 382         ...
 383         """
 384 
 385         numFullLines = 0
 386 
 387         statusbar = self.GetParent().statusbar
 388 
 389         rowsToRemove = []
 390 
 391         for i in range(Board.BoardHeight):
 392             n = 0
 393             for j in range(Board.BoardWidth):
 394                 if not self.shapeAt(j, i) == Tetrominoes.NoShape:
 395                     n = n + 1
 396 
 397             if n == 10:
 398                 rowsToRemove.append(i)
 399 
 400         rowsToRemove.reverse()
 401 
 402         for m in rowsToRemove:
 403             for k in range(m, Board.BoardHeight):
 404                 for l in range(Board.BoardWidth):
 405                         self.setShapeAt(l, k, self.shapeAt(l, k + 1))
 406 
 407             numFullLines = numFullLines + len(rowsToRemove)
 408 
 409             if numFullLines > 0:
 410 
 411                 self.numLinesRemoved = self.numLinesRemoved + numFullLines
 412                 statusbar.SetStatusText(str(self.numLinesRemoved))
 413                 self.isWaitingAfterLine = True
 414                 self.curPiece.setShape(Tetrominoes.NoShape)
 415                 self.Refresh()
 416 
 417 
 418     def newPiece(self):
 419         """
 420         ...
 421         """
 422 
 423         self.curPiece = self.nextPiece
 424         statusbar = self.GetParent().statusbar
 425         self.nextPiece.setRandomShape()
 426 
 427         self.curX = Board.BoardWidth // 2 + 1
 428         self.curY = Board.BoardHeight - 1 + self.curPiece.minY()
 429 
 430         if not self.tryMove(self.curPiece, self.curX, self.curY):
 431 
 432             self.curPiece.setShape(Tetrominoes.NoShape)
 433             self.timer.Stop()
 434             self.isStarted = False
 435             statusbar.SetStatusText('Game over')
 436 
 437 
 438     def tryMove(self, newPiece, newX, newY):
 439         """
 440         ...
 441         """
 442 
 443         for i in range(4):
 444 
 445             x = newX + newPiece.x(i)
 446             y = newY - newPiece.y(i)
 447 
 448             if x < 0 or x >= Board.BoardWidth or y < 0 or y >= Board.BoardHeight:
 449                 return False
 450 
 451             if self.shapeAt(x, y) != Tetrominoes.NoShape:
 452                 return False
 453 
 454         self.curPiece = newPiece
 455         self.curX = newX
 456         self.curY = newY
 457         self.Refresh()
 458 
 459         return True
 460 
 461 
 462     def drawSquare(self, dc, x, y, shape):
 463         """
 464         ...
 465         """
 466 
 467         colors = ['#000000', '#CC6666', '#66CC66', '#6666CC',
 468                   '#CCCC66', '#CC66CC', '#66CCCC', '#DAAA00']
 469 
 470         light = ['#000000', '#F89FAB', '#79FC79', '#7979FC',
 471                  '#FCFC79', '#FC79FC', '#79FCFC', '#FCC600']
 472 
 473         dark = ['#000000', '#803C3B', '#3B803B', '#3B3B80',
 474                  '#80803B', '#803B80', '#3B8080', '#806200']
 475 
 476         pen = wx.Pen(light[shape])
 477         pen.SetCap(wx.CAP_PROJECTING)
 478         dc.SetPen(pen)
 479 
 480         dc.DrawLine(x, y + self.squareHeight() - 1, x, y)
 481         dc.DrawLine(x, y, x + self.squareWidth() - 1, y)
 482 
 483         darkpen = wx.Pen(dark[shape])
 484         darkpen.SetCap(wx.CAP_PROJECTING)
 485         dc.SetPen(darkpen)
 486 
 487         dc.DrawLine(x + 1, y + self.squareHeight() - 1,
 488             x + self.squareWidth() - 1, y + self.squareHeight() - 1)
 489         dc.DrawLine(x + self.squareWidth() - 1,
 490         y + self.squareHeight() - 1, x + self.squareWidth() - 1, y + 1)
 491 
 492         dc.SetPen(wx.TRANSPARENT_PEN)
 493         dc.SetBrush(wx.Brush(colors[shape]))
 494         dc.DrawRectangle(x + 1, y + 1, self.squareWidth() - 2,
 495         self.squareHeight() - 2)
 496 
 497 #---------------------------------------------------------------------------
 498 
 499 class Tetrominoes(object):
 500     """
 501     ...
 502     """
 503 
 504     NoShape = 0
 505     ZShape = 1
 506     SShape = 2
 507     LineShape = 3
 508     TShape = 4
 509     SquareShape = 5
 510     LShape = 6
 511     MirroredLShape = 7
 512 
 513 #---------------------------------------------------------------------------
 514 
 515 class Shape(object):
 516     """
 517     ...
 518     """
 519 
 520     coordsTable = (
 521         ((0, 0),     (0, 0),     (0, 0),     (0, 0)),
 522         ((0, -1),    (0, 0),     (-1, 0),    (-1, 1)),
 523         ((0, -1),    (0, 0),     (1, 0),     (1, 1)),
 524         ((0, -1),    (0, 0),     (0, 1),     (0, 2)),
 525         ((-1, 0),    (0, 0),     (1, 0),     (0, 1)),
 526         ((0, 0),     (1, 0),     (0, 1),     (1, 1)),
 527         ((-1, -1),   (0, -1),    (0, 0),     (0, 1)),
 528         ((1, -1),    (0, -1),    (0, 0),     (0, 1))
 529     )
 530 
 531     def __init__(self):
 532         self.coords = [[0,0] for i in range(4)]
 533         self.pieceShape = Tetrominoes.NoShape
 534 
 535         self.setShape(Tetrominoes.NoShape)
 536 
 537     #-----------------------------------------------------------------------
 538 
 539     def shape(self):
 540         """
 541         ...
 542         """
 543 
 544         return self.pieceShape
 545 
 546 
 547     def setShape(self, shape):
 548         """
 549         ...
 550         """
 551 
 552         table = Shape.coordsTable[shape]
 553         for i in range(4):
 554             for j in range(2):
 555                 self.coords[i][j] = table[i][j]
 556 
 557         self.pieceShape = shape
 558 
 559 
 560     def setRandomShape(self):
 561         """
 562         ...
 563         """
 564 
 565         self.setShape(random.randint(1, 7))
 566 
 567 
 568     def x(self, index):
 569         """
 570         ...
 571         """
 572 
 573         return self.coords[index][0]
 574 
 575 
 576     def y(self, index):
 577         """
 578         ...
 579         """
 580 
 581         return self.coords[index][1]
 582 
 583 
 584     def setX(self, index, x):
 585         """
 586         ...
 587         """
 588 
 589         self.coords[index][0] = x
 590 
 591 
 592     def setY(self, index, y):
 593         """
 594         ...
 595         """
 596 
 597         self.coords[index][1] = y
 598 
 599 
 600     def minX(self):
 601         """
 602         ...
 603         """
 604 
 605         m = self.coords[0][0]
 606         for i in range(4):
 607             m = min(m, self.coords[i][0])
 608 
 609         return m
 610 
 611 
 612     def maxX(self):
 613         """
 614         ...
 615         """
 616 
 617         m = self.coords[0][0]
 618         for i in range(4):
 619             m = max(m, self.coords[i][0])
 620 
 621         return m
 622 
 623 
 624     def minY(self):
 625         """
 626         ...
 627         """
 628 
 629         m = self.coords[0][1]
 630         for i in range(4):
 631             m = min(m, self.coords[i][1])
 632 
 633         return m
 634 
 635 
 636     def maxY(self):
 637         """
 638         ...
 639         """
 640 
 641         m = self.coords[0][1]
 642 
 643         for i in range(4):
 644             m = max(m, self.coords[i][1])
 645 
 646         return m
 647 
 648 
 649     def rotatedLeft(self):
 650         """
 651         ...
 652         """
 653 
 654         if self.pieceShape == Tetrominoes.SquareShape:
 655             return self
 656 
 657         result = Shape()
 658         result.pieceShape = self.pieceShape
 659 
 660         for i in range(4):
 661             result.setX(i, self.y(i))
 662             result.setY(i, -self.x(i))
 663 
 664         return result
 665 
 666 
 667     def rotatedRight(self):
 668         """
 669         ...
 670         """
 671 
 672         if self.pieceShape == Tetrominoes.SquareShape:
 673             return self
 674 
 675         result = Shape()
 676         result.pieceShape = self.pieceShape
 677 
 678         for i in range(4):
 679             result.setX(i, -self.y(i))
 680             result.setY(i, self.x(i))
 681 
 682         return result
 683 
 684 #---------------------------------------------------------------------------
 685 
 686 def main():
 687     app = wx.App()
 688     ex = Tetris(None)
 689     ex.Show(True)
 690     app.MainLoop()
 691 
 692 #---------------------------------------------------------------------------
 693 
 694 if __name__ == '__main__':
 695     main()


Second example

img_tetris_2.png

   1 # tetris_bis.py
   2 
   3 """
   4 wxPython Tetris game.
   5 
   6 Author : Hanming Zhang
   7 Link : https://github.com/HanmingZhang/Tetris
   8 """
   9 
  10 import wx
  11 import random
  12 
  13 # class SplitterFrame
  14 # class Info
  15 # class Board
  16 # class Tetrominoes
  17 # class Shape
  18 
  19 #---------------------------------------------------------------------------
  20 
  21 class SplitterFrame(wx.Frame):
  22     def __init__(self, parent, id, title):
  23         style=wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER ^ wx.MAXIMIZE_BOX
  24         wx.Frame.__init__(self, parent, id, title, size=(600, 600), style=style)
  25 
  26         #------------
  27 
  28         self.SetIcon(wx.Icon(".\icons\wxwin.ico"))
  29 
  30         #------------
  31 
  32         self.initpos = 600
  33 
  34         #------------
  35 
  36         self.sp = wx.SplitterWindow(self)
  37         self.board = Board(self.sp, style=wx.SUNKEN_BORDER)
  38         self.board.SetBackgroundColour("pink")
  39 
  40         self.info = Info(self.sp, style=wx.SUNKEN_BORDER)
  41         self.info.SetBackgroundColour("sky blue")
  42 
  43         self.sp.SplitVertically(self.board, self.info, self.initpos)
  44         self.sp.SetMinimumPaneSize(210)
  45 
  46         #------------
  47 
  48         self.ShowNextPiece = Shape()
  49         # self.board.SetFocus()
  50 
  51         #------------
  52 
  53         # self.Music = wx.Sound('E:\Lab7\s.mp3')
  54 
  55         #------------
  56 
  57         self.board.Start()
  58 
  59         #------------
  60 
  61         self.CenterOnScreen(wx.BOTH)
  62         self.Show(True)
  63 
  64 #---------------------------------------------------------------------------
  65 
  66 class Info(wx.Panel):
  67     BoardWidth = 6
  68     BoardHeight = 25
  69     def __init__(self, parent, style):
  70         wx.Panel.__init__(self, parent)
  71 
  72         #------------
  73 
  74         self.upspeedButton = wx.Button(self, -1, "Up Speed", pos=(15, 500))
  75         self.lowerButton = wx.Button(self, -1, "Lower Speed", pos=(100, 500))
  76 
  77         if wx.Platform == "__WXMSW__":   ###
  78             colour = self.GetBackgroundColour()
  79             colour.Set(colour.Red(), colour.Green(), colour.Blue(),
  80                            wx.ALPHA_TRANSPARENT)
  81             self.upspeedButton.SetBackgroundColour(colour)
  82             self.lowerButton.SetBackgroundColour(colour)
  83 
  84         self.Bind(wx.EVT_BUTTON, self.OnUpSpeed, self.upspeedButton)
  85         self.Bind(wx.EVT_BUTTON, self.OnLowerSpeed, self.lowerButton)
  86         self.Bind(wx.EVT_PAINT, self.OnPaint)
  87 
  88         #------------
  89 
  90         temp = wx.StaticText(self, -1,"Coming next :", pos=(20, 40))
  91         temp.SetFont(wx.Font(18, wx.SCRIPT, wx.NORMAL, wx.NORMAL, False))
  92         temp.SetForegroundColour(wx.Colour(255, 255, 255))
  93         temp = wx.StaticText(self, -1, "Number of lines removed :", pos=(20, 360))
  94         temp.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, False))
  95         temp = wx.StaticText(self, -1, "Your Score :", pos=(20, 420))
  96         temp.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, False))
  97 
  98     #-----------------------------------------------------------------------
  99 
 100     def OnUpSpeed(self,event):
 101          if Board.Speed >= 100:
 102               Board.Speed = Board.Speed -50
 103               self.GetParent().GetParent().board.timer.Start(Board.Speed)
 104 
 105 
 106     def OnLowerSpeed(self,event):
 107          Board.Speed = Board.Speed +50
 108          self.GetParent().GetParent().board.timer.Start(Board.Speed)
 109 
 110 
 111     def SquareWidth(self):
 112         return self.GetClientSize().GetWidth() / Info.BoardWidth
 113 
 114 
 115     def SquareHeight(self):
 116         return self.GetClientSize().GetHeight() / Info.BoardHeight
 117 
 118 
 119     def OnPaint(self, event):
 120         dc = wx.PaintDC(self)
 121         size = self.GetClientSize()
 122         boardTop = size.GetHeight() - Info.BoardHeight * self.SquareHeight()
 123 
 124         # dc.DrawText("Coming next:", 20, 40)
 125 
 126         # temp = wx.StaticText(self, -1, "Coming next:", pos=(20, 40))
 127         # temp.SetFont(wx.Font(5, wx.SWISS, wx.NORMAL, wx.BOLD, False))
 128 
 129         # dc.DrawText("Number of lines removed:", 5, 380)
 130         dc.DrawText("%d" %(self.GetParent().GetParent().board.numLinesRemoved), 90, 400)
 131         # dc.DrawText("Your Score:", 5, 420)
 132         dc.DrawText("%d" %(self.GetParent().GetParent().board.Score), 90, 460)
 133         #linesRemoved=wx.StaticText(self, -1, "", pos=(100, 400))
 134         #linesRemoved.SetFont(wx.Font(15, wx.SWISS, wx.NORMAL, wx.BOLD, False))
 135         #linesRemoved.SetForegroundColour(wx.Colour(0, 0, 0, 255))
 136         #linesRemoved.SetLabel("%d" %(self.GetParent().GetParent().board.numLinesRemoved))
 137 
 138 
 139         if self.GetParent().GetParent().ShowNextPiece.shape() != Tetrominoes.NoShape:
 140             for i in range(4):
 141                 x = self.GetParent().GetParent().ShowNextPiece.x(i)
 142                 y = self.GetParent().GetParent().ShowNextPiece.y(i)
 143                 self.DrawSquare(dc, int(0 + x * self.SquareWidth()+80),   ###
 144                     int((boardTop + (Info.BoardHeight + y - 1)) * int(self.SquareHeight()-400)),  ###
 145                     self.GetParent().GetParent().ShowNextPiece.shape())
 146 
 147 
 148     def DrawSquare(self, dc, x, y, shape):
 149         colors = ['#000000', '#CC6666', '#66CC66', '#6666CC',
 150                   '#CCCC66', '#CC66CC', '#66CCCC', '#DAAA00']
 151 
 152         light = ['#000000', '#F89FAB', '#79FC79', '#7979FC',
 153                  '#FCFC79', '#FC79FC', '#79FCFC', '#FCC600']
 154 
 155         dark = ['#000000', '#803C3B', '#3B803B', '#3B3B80',
 156                 '#80803B', '#803B80', '#3B8080', '#806200']
 157 
 158         pen = wx.Pen(light[shape])
 159         pen.SetCap(wx.CAP_PROJECTING)
 160         dc.SetPen(pen)
 161 
 162         dc.DrawLine(x, int(y + self.SquareHeight() - 1), x, y)
 163         dc.DrawLine(x, y, int(x + self.SquareWidth() - 1), y)
 164 
 165         darkpen = wx.Pen(dark[shape])
 166         darkpen.SetCap(wx.CAP_PROJECTING)
 167         dc.SetPen(darkpen)
 168 
 169         dc.DrawLine(int(x + 1), int(y + self.SquareHeight() - 1),   ###
 170             int(x + self.SquareWidth() - 1), int(y + self.SquareHeight() - 1))   ###
 171         dc.DrawLine(int(x + self.SquareWidth() - 1),   ###
 172         int(y + self.SquareHeight() - 1), int(x + self.SquareWidth() - 1), y + 1)  ###
 173 
 174         dc.SetPen(wx.TRANSPARENT_PEN)
 175         dc.SetBrush(wx.Brush(colors[shape]))
 176         dc.DrawRectangle(int(x + 1), int(y + 1), int(self.SquareWidth() - 2),   ###
 177                          int(self.SquareHeight() - 2))   ###
 178 
 179 #---------------------------------------------------------------------------
 180 
 181 class Board(wx.Panel):
 182     BoardWidth = 12
 183     BoardHeight = 20
 184     Speed = 300
 185     ID_TIMER = 1
 186     def __init__(self, parent, style):
 187         wx.Panel.__init__(self, parent, style=wx.WANTS_CHARS)
 188         # You can use arrow keys after adding style = wx.WANTS_CHARS.
 189 
 190 
 191         #------------
 192 
 193         # Delete flickers.
 194         if wx.Platform == "__WXMSW__":
 195             self.SetDoubleBuffered(True)
 196 
 197         #------------
 198 
 199         self.timer = wx.Timer(self, Board.ID_TIMER)
 200         self.isWaitingAfterLine = False
 201         self.curPiece = Shape()
 202         self.nextPiece = Shape()
 203         self.nextPiece.SetRandomShape()
 204         self.curX = 0
 205         self.curY = 0
 206         self.numLinesRemoved = 0
 207         self.Score = 0
 208         self.board = []
 209 
 210         #------------
 211 
 212         self.isStarted = False
 213         self.isPaused = False
 214 
 215         #------------
 216 
 217         self.Bind(wx.EVT_PAINT, self.OnPaint)
 218         self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
 219         self.Bind(wx.EVT_TIMER, self.OnTimer, id=Board.ID_TIMER)
 220 
 221         #------------
 222 
 223         self.ClearBoard()
 224 
 225     #-----------------------------------------------------------------------
 226 
 227     def ShapeAt(self, x, y):
 228         return self.board[(int(y) * int(Board.BoardWidth)) + int(x)]
 229 
 230 
 231     def SetShapeAt(self, x, y, shape):
 232         self.board[(int(y) * int(Board.BoardWidth)) + int(x)] = shape
 233 
 234 
 235     def SquareWidth(self):
 236         return self.GetClientSize().GetWidth() / Board.BoardWidth
 237 
 238 
 239     def SquareHeight(self):
 240         return self.GetClientSize().GetHeight() / Board.BoardHeight
 241 
 242 
 243     def Start(self):
 244         if self.isPaused:
 245             return
 246 
 247         self.isStarted = True
 248         self.isWaitingAfterLine = False
 249         self.numLinesRemoved = 0
 250         self.Score = 0
 251         self.ClearBoard()
 252 
 253         wx.MessageBox("""Hello !\n"""
 254                       """Welcome to Tetris World.\n\n"""
 255                       """Here are some information you may need.\n\n"""
 256                       """Azerty keyboard :\n"""
 257                       """--------------------\n"""
 258                       """Z --> Rotate\n"""
 259                       """Q/D --> Left or Right move\n"""
 260                       """S --> One line down\n"""
 261                       """Space --> Drop down\n"""
 262                       """P --> Pause\n\n"""
 263                       """Hope you enjoy ! ^.^""",
 264                       "Tetris",
 265                       wx.OK | wx.ICON_INFORMATION,
 266                       self)
 267 
 268         # self.GetParent().GetParent().Music.Play(wx.SOUND_ASYNC)
 269 
 270         self.NewPiece()
 271         self.timer.Start(Board.Speed)
 272 
 273 
 274     def Pause(self):
 275         if not self.isStarted:
 276             return
 277 
 278         self.isPaused = not self.isPaused
 279         # statusbar = self.GetParent().statusbar
 280 
 281         if self.isPaused:
 282             self.timer.Stop()
 283             # statusbar.SetStatusText('Paused')
 284         else:
 285             self.timer.Start(Board.Speed)
 286             # statusbar.SetStatusText(str(self.numLinesRemoved))
 287         self.Refresh()
 288 
 289 
 290     def ClearBoard(self):
 291         for i in range(Board.BoardHeight * Board.BoardWidth):
 292             self.board.append(Tetrominoes.NoShape)
 293 
 294 
 295     def OnPaint(self, event):
 296         dc = wx.PaintDC(self)
 297 
 298         size = self.GetClientSize()
 299         boardTop = size.GetHeight() - Board.BoardHeight * self.SquareHeight()
 300 
 301         for i in range(Board.BoardHeight):
 302             for j in range(Board.BoardWidth):
 303                 shape = self.ShapeAt(j, Board.BoardHeight - i - 1)
 304                 if shape != Tetrominoes.NoShape:
 305                     self.DrawSquare(dc,
 306                         int(0 + j * self.SquareWidth()),   ###
 307                         int(boardTop + i * self.SquareHeight()), shape)   ###
 308 
 309         if self.curPiece.shape() != Tetrominoes.NoShape:
 310             for i in range(4):
 311                 x = self.curX + self.curPiece.x(i)
 312                 y = self.curY - self.curPiece.y(i)
 313                 self.DrawSquare(dc, int(0 + x * self.SquareWidth()),  ###
 314                     int((boardTop + (Board.BoardHeight - y - 1)) * (self.SquareHeight())),  ###
 315                     self.curPiece.shape())
 316 
 317 
 318     def OnKeyDown(self, event):
 319         if not self.isStarted or self.curPiece.shape() == Tetrominoes.NoShape:
 320             event.Skip()
 321             return
 322 
 323         keycode = event.GetKeyCode()
 324 
 325         if keycode == ord('P') or keycode == ord('p'):
 326             self.Pause()
 327             return
 328         if self.isPaused:
 329             return
 330         elif keycode == ord('Q') or keycode == ord('q'):
 331             self.TryMove(self.curPiece, self.curX - 1, self.curY)
 332         elif keycode == ord('D') or keycode == ord('d'):
 333             self.TryMove(self.curPiece, self.curX + 1, self.curY)
 334         #elif keycode == wx.WXK_DOWN:
 335             #self.TryMove(self.curPiece.rotatedRight(), self.curX, self.curY)
 336         elif keycode == ord('Z') or keycode == ord('z'):
 337             self.TryMove(self.curPiece.RotatedLeft(), self.curX, self.curY)
 338         elif keycode == ord('S') or keycode == ord('s'):
 339             self.OneLineDown()
 340         elif keycode == wx.WXK_SPACE:
 341             self.DropDown()
 342         else:
 343             event.Skip()
 344 
 345 
 346     def OnTimer(self, event):
 347         if event.GetId() == Board.ID_TIMER:
 348             if self.isWaitingAfterLine:
 349                 self.isWaitingAfterLine = False
 350                 self.NewPiece()
 351             else:
 352                 self.OneLineDown()
 353         else:
 354             event.Skip()
 355 
 356 
 357     def DropDown(self):
 358         newY = self.curY
 359         while newY > 0:
 360             if not self.TryMove(self.curPiece, self.curX, newY - 1):
 361                 break
 362             newY -= 1
 363 
 364         self.PieceDropped()
 365 
 366 
 367     def OneLineDown(self):
 368         if not self.TryMove(self.curPiece, self.curX, self.curY - 1):
 369             self.PieceDropped()
 370 
 371 
 372     def PieceDropped(self):
 373         for i in range(4):
 374             x = self.curX + self.curPiece.x(i)
 375             y = self.curY - self.curPiece.y(i)
 376             self.SetShapeAt(x, y, self.curPiece.shape())
 377 
 378         self.RemoveFullLines()
 379 
 380         if not self.isWaitingAfterLine:
 381             self.NewPiece()
 382 
 383 
 384     def RemoveFullLines(self):
 385         numFullLines = 0
 386 
 387         # statusbar = self.GetParent().statusbar
 388 
 389         rowsToRemove = []
 390 
 391         for i in range(Board.BoardHeight):
 392             n = 0
 393             for j in range(Board.BoardWidth):
 394                 if not self.ShapeAt(j, i) == Tetrominoes.NoShape:
 395                     n = n + 1
 396 
 397             if n == 12:
 398                 rowsToRemove.append(i)
 399 
 400         rowsToRemove.reverse()
 401 
 402         for m in rowsToRemove:
 403             for k in range(m, Board.BoardHeight):
 404                 for l in range(Board.BoardWidth):
 405                         self.SetShapeAt(l, k, self.ShapeAt(l, k + 1))
 406 
 407             numFullLines = numFullLines + len(rowsToRemove)
 408 
 409 
 410             if numFullLines > 0:
 411                 #if numFullLines == 1:
 412                     #self.Score += 10
 413                 #else :
 414                     #self.Score += numFullLines*20
 415                 #self.numLinesRemoved += numFullLines
 416                 # statusbar.SetStatusText(str(self.numLinesRemoved))
 417                 self.isWaitingAfterLine = True
 418                 self.curPiece.SetShape(Tetrominoes.NoShape)
 419                 self.Refresh()
 420 
 421         if len(rowsToRemove) != 0:
 422             self.numLinesRemoved += len(rowsToRemove)
 423             if len(rowsToRemove) == 1:
 424                 self.Score += 10
 425             else:
 426                 self.Score += len(rowsToRemove)*20
 427             self.GetParent().GetParent().info.Refresh()
 428 
 429 
 430     def NewPiece(self):
 431         # self.curPiece = self.nextPiece (it's wrong !)
 432         # The original one has problem !!
 433         # self.curPiece will always be the same as self.nextPiece
 434         # This is the proper way !
 435         self.curPiece.SetShape(self.nextPiece.shape())
 436         # statusbar = self.GetParent().statusbar
 437         self.nextPiece.SetRandomShape()
 438 
 439         self.GetParent().GetParent().ShowNextPiece = self.nextPiece
 440         # self.GetParent is a SpiltterWindow, and SpiltterWIndow's parent is SplitterFrame !
 441         self.GetParent().GetParent().info.Refresh()
 442 
 443         self.curX = Board.BoardWidth / 2 + 1
 444         self.curY = Board.BoardHeight - 1 + self.curPiece.MinY()
 445 
 446         if not self.TryMove(self.curPiece, self.curX, self.curY):
 447             self.curPiece.SetShape(Tetrominoes.NoShape)
 448             self.timer.Stop()
 449             self.isStarted = False
 450             wx.MessageBox("Sorry ! Game Over !", "Game Over",
 451                           wx.OK | wx.ICON_INFORMATION, self)
 452             # Once the game is over, the program will quit.
 453             self.GetParent().GetParent().Close()
 454 
 455 
 456     def TryMove(self, NewPiece, newX, newY):
 457         for i in range(4):
 458             x = newX + NewPiece.x(i)
 459             y = newY - NewPiece.y(i)
 460             if x < 0 or x >= Board.BoardWidth or y < 0 or y >= Board.BoardHeight:
 461                 return False
 462             if self.ShapeAt(x, y) != Tetrominoes.NoShape:
 463                 return False
 464 
 465         self.curPiece = NewPiece
 466         self.curX = newX
 467         self.curY = newY
 468         self.Refresh()
 469         return True
 470 
 471 
 472     def DrawSquare(self, dc, x, y, shape):
 473         colors = ['#000000', '#CC6666', '#66CC66', '#6666CC',
 474                   '#CCCC66', '#CC66CC', '#66CCCC', '#DAAA00']
 475 
 476         light = ['#000000', '#F89FAB', '#79FC79', '#7979FC',
 477                  '#FCFC79', '#FC79FC', '#79FCFC', '#FCC600']
 478 
 479         dark = ['#000000', '#803C3B', '#3B803B', '#3B3B80',
 480                  '#80803B', '#803B80', '#3B8080', '#806200']
 481 
 482         pen = wx.Pen(light[shape])
 483         pen.SetCap(wx.CAP_PROJECTING)
 484         dc.SetPen(pen)
 485 
 486         dc.DrawLine(x, int(y + self.SquareHeight() - 1), x, y)  ###
 487         dc.DrawLine(x, y, int(x + self.SquareWidth() - 1), y)  ###
 488 
 489         darkpen = wx.Pen(dark[shape])
 490         darkpen.SetCap(wx.CAP_PROJECTING)
 491         dc.SetPen(darkpen)
 492 
 493         dc.DrawLine(x + 1, int(y + self.SquareHeight() - 1),  ###
 494             int(x + self.SquareWidth() - 1), int(y + self.SquareHeight() - 1))  ###
 495         dc.DrawLine(x + int(self.SquareWidth() - 1),
 496         int(y + self.SquareHeight() - 1), int(x + self.SquareWidth() - 1), y + 1)   ###
 497 
 498         dc.SetPen(wx.TRANSPARENT_PEN)
 499         dc.SetBrush(wx.Brush(colors[shape]))
 500         dc.DrawRectangle(int(x + 1), int(y + 1), int(self.SquareWidth() - 2),
 501         int(self.SquareHeight() - 2))  ###
 502 
 503 #---------------------------------------------------------------------------
 504 
 505 class Tetrominoes(object):
 506     NoShape = 0
 507     ZShape = 1
 508     SShape = 2
 509     LineShape = 3
 510     TShape = 4
 511     SquareShape = 5
 512     LShape = 6
 513     MirroredLShape = 7
 514 
 515 #---------------------------------------------------------------------------
 516 
 517 class Shape(object):
 518     coordsTable = (
 519         ((0, 0),     (0, 0),     (0, 0),     (0, 0)),
 520         ((0, -1),    (0, 0),     (-1, 0),    (-1, 1)),
 521         ((0, -1),    (0, 0),     (1, 0),     (1, 1)),
 522         ((0, -1),    (0, 0),     (0, 1),     (0, 2)),
 523         ((-1, 0),    (0, 0),     (1, 0),     (0, 1)),
 524         ((0, 0),     (1, 0),     (0, 1),     (1, 1)),
 525         ((-1, -1),   (0, -1),    (0, 0),     (0, 1)),
 526         ((1, -1),    (0, -1),    (0, 0),     (0, 1))
 527     )
 528     def __init__(self):
 529         self.coords = [[0,0] for i in range(4)]
 530         self.pieceShape = Tetrominoes.NoShape
 531         self.SetShape(Tetrominoes.NoShape)
 532 
 533     #-----------------------------------------------------------------------
 534 
 535     def shape(self):
 536         return self.pieceShape
 537 
 538 
 539     def SetShape(self, shape):
 540         table = Shape.coordsTable[shape]
 541         for i in range(4):
 542             for j in range(2):
 543                 self.coords[i][j] = table[i][j]
 544 
 545         self.pieceShape = shape
 546 
 547 
 548     def SetRandomShape(self):
 549         self.SetShape(random.randint(1, 7))
 550 
 551 
 552     def x(self, index):
 553         return self.coords[index][0]
 554 
 555 
 556     def y(self, index):
 557         return self.coords[index][1]
 558 
 559 
 560     def SetX(self, index, x):
 561         self.coords[index][0] = x
 562 
 563 
 564     def SetY(self, index, y):
 565         self.coords[index][1] = y
 566 
 567 
 568     def MinX(self):
 569         m = self.coords[0][0]
 570         for i in range(4):
 571             m = min(m, self.coords[i][0])
 572         return m
 573 
 574 
 575     def MaxX(self):
 576         m = self.coords[0][0]
 577         for i in range(4):
 578             m = max(m, self.coords[i][0])
 579         return m
 580 
 581 
 582     def MinY(self):
 583         m = self.coords[0][1]
 584         for i in range(4):
 585             m = min(m, self.coords[i][1])
 586         return m
 587 
 588 
 589     def MaxY(self):
 590         m = self.coords[0][1]
 591         for i in range(4):
 592             m = max(m, self.coords[i][1])
 593         return m
 594 
 595 
 596     def RotatedLeft(self):
 597         if self.pieceShape == Tetrominoes.SquareShape:
 598             return self
 599 
 600         result = Shape()
 601         result.pieceShape = self.pieceShape
 602         for i in range(4):
 603             result.SetX(i, self.y(i))
 604             result.SetY(i, -self.x(i))
 605 
 606         return result
 607 
 608 #---------------------------------------------------------------------------
 609 
 610 def main():
 611     app = wx.App()
 612     SplitterFrame(None, -1, 'Tetris')
 613     app.MainLoop()
 614 
 615 #---------------------------------------------------------------------------
 616 
 617 if __name__ == '__main__':
 618     main()


Memory game

img_memory_game.png

Readme file : memory_README.md

   1 # memory_game.py
   2 
   3 """
   4 wxPython Memory game.
   5 All images should be in folder named "Images".
   6 Images used are W : 100px H : 150px, though any size works if all images same size.
   7 Line 32 has some commented out code to print the key to terminal for testing.
   8 
   9 Author : Zoenberger
  10 Link : https://github.com/zoenberger/Memory-Game-using-wxPython
  11 """
  12 
  13 import wx
  14 import os
  15 import random
  16 import time
  17 
  18 # class MemoryGame
  19 # def Winner
  20 # def GetJpgList
  21 
  22 #---------------------------------------------------------------------------
  23 
  24 class MemoryGame(wx.Frame):
  25     def __init__(self):
  26         wx.Frame.__init__(self, None, title="")
  27 
  28         #------------
  29 
  30         self.SetIcon(wx.Icon(".\icons\wxwin.ico"))
  31         self.SetTitle("Memory game")
  32         self.SetSize((900,700))
  33 
  34         #------------
  35 
  36         self.Move((50,25))
  37 
  38         #------------
  39 
  40         self.panel = wx.Panel(self)
  41 
  42         #------------
  43 
  44         # Define how big game is...can be useful
  45         # for making skill options later.
  46         self.numPairs = 12
  47 
  48         # Get all images in directory called
  49         # "Images" & shuffle order
  50         self.imageArray = GetJpgList("./images")
  51         random.shuffle(self.imageArray)
  52 
  53         # Create array with how many cards needed
  54         # and double it to make matched pairs.
  55         self.imagePairs = self.imageArray[0:self.numPairs]
  56         self.imagePairs = self.imagePairs * 2
  57 
  58         # Because we doubled, we need to re-shuffle order.
  59         random.shuffle(self.imagePairs)
  60 
  61         #------------
  62 
  63         # PRINT KEY TO TERMINAL SO YOU CAN QUICKLY SOLVE.
  64         # countrow=0
  65         # for card in self.imagePairs:
  66         #     countrow +=1
  67         #     if countrow%6 == 0:
  68         #         print card
  69         #     else:
  70         #         print card,
  71 
  72         # Create blank card and give name of file name.
  73         card = wx.Image('./images/main_card.jpg',wx.BITMAP_TYPE_ANY).ConvertToBitmap()
  74         self.blankCards =[]
  75         for i in range(len(self.imagePairs)):
  76             self.blankCards.append(wx.StaticBitmap(self.panel,wx.ID_ANY, card,name=self.imagePairs[i]))
  77 
  78         # Bind left click to each card that calls check function.
  79         for img in self.blankCards:
  80             img.Bind(wx.EVT_LEFT_DOWN, self.OnClick)
  81 
  82         #------------
  83 
  84         # Visual Layout.
  85         hbox = wx.BoxSizer(wx.HORIZONTAL)
  86         gs = wx.GridSizer(4, 6, 15, 15)
  87         gs.AddMany(self.blankCards)
  88         hbox.Add(gs, proportion=0, flag = wx.LEFT | wx.TOP, border = 10)
  89 
  90         title = wx.StaticText(self.panel, label="Memory Game")
  91         hbox.Add(title,proportion=1, flag = wx.LEFT | wx.TOP | wx.RIGHT | wx.EXPAND, border = 10)
  92 
  93         self.panel.SetSizer(hbox)
  94         self.Show()
  95 
  96         #------------
  97 
  98         # Keeps track to see if you've won.
  99         self.foundMatches= 0
 100         # Keeps track of 1st or second click.
 101         self.clickCount = 0
 102         # Holding spot if it's first click.
 103         self.card1 = ''
 104         self.totalTries = 0
 105 
 106     #-----------------------------------------------------------------------
 107 
 108     def OnClick(self, event):
 109         self.clickCount += 1
 110 
 111         #------------
 112 
 113         # Get card clicked on, swap out blank
 114         # image with image by filename.
 115         newCard = event.GetEventObject()
 116         img = wx.Image(newCard.GetName(), wx.BITMAP_TYPE_ANY)
 117         newCard.SetBitmap(wx.Bitmap(img))
 118 
 119         #------------
 120 
 121         if self.clickCount == 1:
 122             # Put into holding space if 1st click.
 123             self.card1 = newCard
 124             self.card1.Unbind(wx.EVT_LEFT_DOWN)
 125 
 126         else:
 127             # FOUND MATCH : unbind click events. Update match tracker.
 128             self.totalTries += 1
 129             if (newCard.GetName() == self.card1.GetName()):
 130                 for findItem in self.blankCards:
 131                     if findItem.GetName() == newCard.GetName():
 132                         findItem.Unbind(wx.EVT_LEFT_DOWN)
 133                 self.foundMatches += 1
 134                 print(self.foundMatches)
 135             else:
 136                 # NO MATCH : wait then hide both cards again.
 137                 # This basically freezes screen, but clicks still captured.
 138                 time.sleep(1)
 139                 blankCard = wx.Image('./images/main_card.jpg', wx.BITMAP_TYPE_ANY)
 140                 newCard.SetBitmap(wx.Bitmap(blankCard))
 141                 self.card1.SetBitmap(wx.Bitmap(blankCard))
 142                 self.card1.Bind(wx.EVT_LEFT_DOWN, self.OnClick)
 143             self.clickCount = 0
 144 
 145         if self.foundMatches == self.numPairs:
 146             Winner()
 147             print("Total Tries = " + str(self.totalTries))
 148             total = ("Total Tries = " + str(self.totalTries))
 149 
 150             dlg = wx.MessageDialog(self,
 151                                    total,
 152                                    "Winner !",
 153                                    wx.OK | wx.CENTRE | wx.ICON_INFORMATION)
 154             dlg.ShowModal()
 155             dlg.Destroy()
 156 
 157 #---------------------------------------------------------------------------
 158 
 159 # NOTE : make the winning more exciting. Hahahaha.
 160 def Winner():
 161     print("WINNER WINNER WINNER !")
 162 
 163 #---------------------------------------------------------------------------
 164 
 165 # Get all JPEGs in a directory that is passed and return image names array.
 166 # Note I found this code snippet here :
 167 # http ://wiki.wxpython.org/wxStaticBitmap
 168 def GetJpgList(loc):
 169     jpgs = [f for f in os.listdir(loc) if f[-4:] == ".jpg"]
 170     #print "JPGS are:", jpgs
 171 
 172     return [os.path.join(loc, f) for f in jpgs]
 173 
 174 #---------------------------------------------------------------------------
 175 
 176 def main():
 177     app = wx.App(False)
 178     frame = MemoryGame()
 179     app.MainLoop()
 180 
 181 #---------------------------------------------------------------------------
 182 
 183 if __name__ == '__main__':
 184     main()


Reversi

img_reversi.png

   1 # reversi.py
   2 
   3 """
   4 wxPython Reversi game.
   5 
   6 Author : Hatena
   7 Link : https://yatt.hatenablog.jp/entry/20100129/1264791420
   8 """
   9 
  10 import wx
  11 from copy import deepcopy
  12 
  13 WHITE = -1
  14 BLANK = 0
  15 BLACK = 1
  16 
  17 # def Notify
  18 # class Reversi
  19 # class Frame
  20 
  21 #---------------------------------------------------------------------------
  22 
  23 def Notify(caption, message):
  24     dialog = wx.MessageDialog(None,
  25                               message=message,
  26                               caption=caption,
  27                               style=wx.OK)
  28     dialog.ShowModal()
  29     dialog.Destroy()
  30 
  31 #---------------------------------------------------------------------------
  32 
  33 class Reversi(object):
  34     def __init__(self):
  35 
  36         #------------
  37 
  38         self.board = [[0]*8 for x in range(8)]
  39         self.board[3][3] = WHITE
  40         self.board[4][4] = WHITE
  41         self.board[3][4] = BLACK
  42         self.board[4][3] = BLACK
  43         self.turns = 1              # Turn counter.
  44         self.current = BLACK        # Current player.
  45         self.nstone = [2, 60, 2]    # white, blank, black.
  46         self.nreversed = 0
  47         self.passed = None
  48         self.over = False
  49 
  50     #-----------------------------------------------------------------------
  51 
  52     def __getitem__(self, i):
  53         return self.board[i]
  54 
  55 
  56     def Stones(self, s):
  57         return self.nstone[1 + s]
  58 
  59 
  60     def Feverseline(self, x, y, dx, dy):
  61         if not (0<=x<8) or not (0<=y<8):
  62             return False
  63 
  64         elif self[x][y] == BLANK:
  65             return False
  66 
  67         elif self[x][y] == self.current:
  68             return True
  69 
  70         elif self[x][y] == -self.current:
  71             ret = self.Feverseline(x+dx, y+dy, dx, dy)
  72             if ret:
  73                 self[x][y] *= -1 # Reverse.
  74                 self.nreversed += 1
  75             return ret
  76 
  77 
  78     def Put(self, x, y, validation=False):
  79         if self.over or self[x][y] != BLANK:
  80             return False
  81 
  82         backup = self[x][y]
  83         self[x][y] = self.current
  84         self.nreversed = 0
  85 
  86         for dx in [-1, 0, 1]:
  87             for dy in [-1, 0, 1]:
  88                 self.Feverseline(x+dx, y+dy, dx, dy)
  89 
  90         if self.nreversed == 0:
  91             self[x][y] = backup
  92             return False
  93 
  94         if validation:
  95             # Despress changing state but only self.board.
  96             return True
  97 
  98         self.nstone[1 + BLANK] -= 1
  99         self.nstone[1 + self.current] += self.nreversed + 1
 100         self.nstone[1 - self.current] -= self.nreversed
 101         self.turns += 1
 102         self.current *= -1 # Change turn.
 103 
 104         # Check game is over or not.
 105         for s in [WHITE, BLANK, BLACK]:
 106             if self.Stones(s) == 0:
 107                 self.over = True
 108                 return True
 109 
 110         for i in range(8):
 111             for j in range(8):
 112                 if self.Available(i, j):
 113                     self.passed = None
 114                     return True
 115 
 116         self.passed = self.current
 117         self.current *= -1
 118 
 119         for i in range(8):
 120             for j in range(8):
 121                 if self.Available(i, j):
 122                     return True
 123         self.current *= -1
 124         self.over = True
 125         return True
 126 
 127 
 128     def Available(self, x, y):
 129         if self.over:
 130             return False
 131 
 132         # Backup board.
 133         backup = deepcopy(self.board)
 134         ret = self.Put(int(x), int(y), True)
 135         # Restore board.
 136         self.board = backup
 137         return ret
 138 
 139 #---------------------------------------------------------------------------
 140 
 141 class Frame(wx.Frame):
 142     def __init__(self):
 143         style=wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER ^ wx.MAXIMIZE_BOX
 144         wx.Frame.__init__(self, None, -1, "Reversi", style=style)
 145 
 146         #------------
 147 
 148         self.SetIcon(wx.Icon(".\icons\wxwin.ico"))
 149 
 150         #------------
 151 
 152         # Panel.
 153         self.panel = wx.Panel(self)
 154         self.panel.SetDoubleBuffered(True)  ###
 155         self.panel.Bind(wx.EVT_LEFT_DOWN, self.TryPut)
 156         self.panel.Bind(wx.EVT_PAINT, self.Refresh)
 157 
 158         #------------
 159 
 160         self.Newgame(None)
 161 
 162         #------------
 163 
 164         # Menubar.
 165         menu = wx.Menu()
 166         menu.Append(1, "New game")
 167         menu.AppendSeparator()
 168         menu.Append(2, "Quit")
 169         menubar = wx.MenuBar()
 170         menubar.Append(menu, "Menu")
 171         self.SetMenuBar(menubar)
 172 
 173         self.Bind(wx.EVT_MENU, self.Newgame, id=1)
 174         self.Bind(wx.EVT_MENU, self.Quit, id=2)
 175 
 176         #------------
 177 
 178         # Status bar.
 179         self.CreateStatusBar()
 180 
 181         #------------
 182 
 183         # Ban resize.
 184         # self.Bind(wx.EVT_SIZE, lambda e:e)
 185 
 186         #------------
 187 
 188         self.Show()
 189 
 190     #-----------------------------------------------------------------------
 191 
 192     def Quit(self, event):
 193         self.Close()
 194 
 195 
 196     def Newgame(self, event):
 197         # Initialize reversi and Refresh screen.
 198         self.reversi = Reversi()
 199         self.panel.Refresh()
 200 
 201 
 202     def TryPut(self, event):
 203         if self.reversi.over:
 204             return
 205 
 206         # Calculate coordinate from window coordinate.
 207         winx,winy = event.GetX(), event.GetY()
 208         w,h = self.panel.GetSize()
 209         x = winx / (w/8)
 210         y = winy / (h/8)
 211 
 212         if not self.reversi.Available(int(x), int(y)):
 213             return
 214 
 215         ret = self.reversi.Put(int(x), int(y))
 216         self.panel.Refresh()
 217 
 218         # If game is over then display dialog.
 219         if self.reversi.over:
 220             black = self.reversi.Stones(BLACK)
 221             white = self.reversi.Stones(WHITE)
 222             mes = "Black : %d\nWhite : %d\n" % (black, white)
 223             if black == white:
 224                 mes += "** draw **"
 225             else:
 226                 mes += "Winner : %s" % ["Black", "White"][black < white]
 227             Notify("Game is over !", mes)
 228 
 229         elif self.reversi.passed != None:
 230             Notify("Passing turn", "Pass")
 231 
 232 
 233     def Refresh(self, event):
 234         dc = wx.AutoBufferedPaintDCFactory(self.panel)
 235         dc = wx.GCDC(dc)
 236         self.SetStatusText("Current player is " + ["White", "Black"][self.reversi.current==BLACK])
 237         w,h = self.panel.GetSize()
 238 
 239         # Background.
 240         dc.SetBrush(wx.Brush("#228b22"))
 241         dc.DrawRectangle(0,0,w,h)
 242         # Grid.
 243         dc.SetBrush(wx.Brush("black"))
 244         px,py = w/8,h/8
 245 
 246         for i in range(8):
 247             dc.DrawLine(int(i*px),0, int(i*px), h)  ###
 248             dc.DrawLine(0, int(i*py), w, int(i*py))  ###
 249         dc.DrawLine(w-1, 0, w-1, h-1)
 250         dc.DrawLine(0, h-1, w-1, h-1)
 251 
 252         # Stones.
 253         brushes = {WHITE: wx.Brush("white"), BLACK: wx.Brush("black")}
 254         for i in range(8):
 255             for j in range(8):
 256                 c = self.reversi[i][j]
 257                 if c != BLANK:
 258                     dc.SetBrush(brushes[c])
 259                     dc.DrawEllipse(int(i*px), int(j*py), int(px), int(py))  ###
 260 
 261                 elif self.reversi.Available(i, j):
 262                     dc.SetBrush(wx.Brush("red"))
 263                     dc.DrawCircle(int(i*px+px/2), int(j*py+py/2), 3)  ###
 264 
 265 #---------------------------------------------------------------------------
 266 
 267 def main():
 268     app = wx.App(False)
 269     frame = Frame()
 270     frame.SetSize((400, 400))
 271     app.MainLoop()
 272 
 273 #---------------------------------------------------------------------------
 274 
 275 if __name__ == '__main__':
 276     main()


Towers of hanoi

First example

img_towers_of_hanoi_1.png

Readme file : hanoi_README.md

License file : hanoi_LICENSE.md

   1 # towers_of_hanoi.py
   2 
   3 """
   4 The Towers of Hanoi for wxPython
   5 by S. Foster, Jan. 2004
   6 Link : https://code.activestate.com/recipes/577511-hanoi-towers-solver-wxpython/
   7 
   8 Based on wxHanoi.cpp
   9 By Martin Bernreuther
  10 """
  11 
  12 import wx
  13 
  14 COLOURS = ['RED', 'CORAL', 'YELLOW', 'GREEN', 'BLUE', 'MAGENTA', 'PURPLE']
  15 
  16 # class wxHanoiDisc
  17 # class wxHanoiFrame
  18 # class wxHanoiApp
  19 
  20 #---------------------------------------------------------------------------
  21 
  22 class wxHanoiDisc:
  23     """
  24     ...
  25     """
  26     def __init__(self, n, width, height):
  27 
  28         #------------
  29 
  30         self.width = (n + 1) * width
  31         self.height = height
  32         self.n = n
  33         self.brush = wx.Brush(wx.Colour(COLOURS[n % len(COLOURS)]))
  34 
  35 #---------------------------------------------------------------------------
  36 
  37 class wxHanoiFrame(wx.Frame):
  38     """
  39     ...
  40     """
  41     def __init__(self, title, size):
  42         style=wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER ^ wx.MAXIMIZE_BOX
  43         wx.Frame.__init__(self, None, -1,
  44                           title, size=size,
  45                           style=style)
  46 
  47         #------------
  48 
  49         self.SetIcon(wx.Icon(".\icons\wxwin.ico"))
  50 
  51         #------------
  52 
  53         self.sleepTime = 3
  54         self.numDiscs = 4
  55 
  56         self.pen = wx.Pen(wx.Colour('BLACK'), 1, wx.SOLID)
  57 
  58         #------------
  59 
  60         self.CreateMenu()
  61         self.CreateStatusBar()
  62         self.Initialize()
  63         self.BindEvents()
  64 
  65         #------------
  66 
  67         self.CenterOnScreen(wx.BOTH)
  68         self.Show(True)
  69 
  70     #-----------------------------------------------------------------------
  71 
  72     def CreateMenu(self):
  73         def MenuCallback(menu, item, callback):
  74             id = wx.NewIdRef()
  75             menu.Append(id, item)
  76             self.Bind(wx.EVT_MENU, callback, id)
  77 
  78         menuBar = wx.MenuBar()
  79 
  80         menuFile = wx.Menu()
  81         MenuCallback(menuFile, 'E&xit...\tCtrl-X', self.OnQuit)
  82         menuBar.Append(menuFile, '&File')
  83 
  84         menuPlay = wx.Menu()
  85         MenuCallback(menuPlay, '&Number of Discs...', self.OnInpNumDiscs)
  86         MenuCallback(menuPlay, '&Time between Moves...', self.OnInpSleepTime)
  87         menuPlay.AppendSeparator()
  88         MenuCallback(menuPlay, '&Play', self.OnPlay)
  89         MenuCallback(menuPlay, '&Reset', self.OnReset)
  90         menuBar.Append(menuPlay, '&Play')
  91 
  92         menuHelp = wx.Menu()
  93         MenuCallback(menuHelp, '&About...', self.OnAbout)
  94         menuBar.Append(menuHelp, '&Help')
  95 
  96         self.SetMenuBar(menuBar)
  97 
  98 
  99     def Initialize(self):
 100         self.width, self.height = self.GetClientSize()
 101         maxwidth = self.width / 3
 102         w = self.width / 6
 103         self.xpos = [i * w for i in [1, 3, 5]]
 104 
 105         height = self.height / self.numDiscs
 106         width = maxwidth / self.numDiscs
 107         if height > width:
 108             height = width
 109         self.discheight = height
 110         self.discwidthfac = width
 111 
 112         discs = list(range(self.numDiscs))
 113         discs.reverse()
 114 
 115         self.pegs = [[wxHanoiDisc(i, width, height) for i in discs], [], []]
 116         self.moves = 0
 117 
 118         width, height = self.GetClientSize()
 119         self.Draw(wx.ClientDC(self), width, height)
 120 
 121 
 122     def BindEvents(self):
 123         self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
 124         self.Bind(wx.EVT_PAINT, self.OnPaint)
 125 
 126 
 127     def OnQuit(self, event):
 128         self.Close(True)
 129 
 130 
 131     def OnCloseWindow(self, event):
 132         self.Destroy()
 133 
 134 
 135     def OnAbout(self, event):
 136         wx.MessageBox(__doc__, 'About wxHanoi', wx.OK|wx.ICON_INFORMATION, self)
 137 
 138 
 139     def OnInpNumDiscs(self, _event):
 140         self.numDiscs = wx.GetNumberFromUser('', 'Discs:', 'Number of Discs',
 141                                              self.numDiscs, 1, 25, self)
 142         if self.numDiscs == -1:
 143             self.SetStatusText("Invalid number entered or dialog cancelled.")
 144         else:
 145             self.Initialize()
 146 
 147 
 148     def OnInpSleepTime(self, event):
 149         self.sleepTime = wx.GetNumberFromUser('', 'Wait [sec/10]:', 'Time between Moves',
 150                                               self.sleepTime, 0, 10, self)
 151         if self.sleepTime == -1:
 152             self.SetStatusText("Invalid number entered or dialog cancelled.")
 153         else:
 154             self.Initialize()
 155 
 156 
 157     def OnPlay(self, event):
 158         self.Initialize()
 159         self.SetStatusText('Playing')
 160         self.Move(0, 2, 1, self.numDiscs)
 161         self.SetStatusText('Finished: %s Moves' % self.moves)
 162 
 163 
 164     def OnReset(self, event):
 165         self.Initialize()
 166 
 167 
 168     def DrawDisc(self, dc, disc, x, y):
 169         assert x <= 2
 170         dc.SetPen(self.pen)
 171         dc.SetBrush(disc.brush)
 172         dc.DrawRectangle(int(self.xpos[x] - (disc.width / 2)),
 173                          int(self.height - (y * self.discheight)),
 174                          int(disc.width),
 175                          int(disc.height))
 176 
 177 
 178     def Draw(self, dc, width, height):
 179         mdc = wx.MemoryDC()
 180         mdc.SelectObject(wx.Bitmap(width, height))
 181         for x, peg in enumerate(self.pegs):
 182             for y, disc in enumerate(peg):
 183                 self.DrawDisc(mdc, disc, x, y+1)
 184         dc.Blit(0, 0, width, height, mdc, 0, 0)
 185 
 186 
 187     def OnPaint(self, event):
 188         width, height = self.GetClientSize()
 189         self.Draw(wx.PaintDC(self), width, height)
 190 
 191 
 192     def MoveDisc(self, src, dst):
 193         disc = self.pegs[src].pop()
 194         self.pegs[dst].append(disc)
 195         self.moves += 1
 196         self.SetStatusText('Move %s' % self.moves)
 197         width, height = self.GetClientSize()
 198         self.Draw(wx.ClientDC(self), width, height)
 199         wx.MilliSleep(10 * self.sleepTime)
 200 
 201 
 202     def Move(self, src, dst, temp, n):
 203         if n == 1:
 204             self.MoveDisc(src, dst)
 205         else:
 206             self.Move(src, temp, dst, n-1)
 207             self.MoveDisc(src, dst)
 208             self.Move(temp, dst, src, n-1)
 209 
 210 #---------------------------------------------------------------------------
 211 
 212 class wxHanoiApp(wx.App):
 213     """
 214     ...
 215     """
 216     def OnInit(self):
 217 
 218         #------------
 219 
 220         self.frame = wxHanoiFrame('Towers of Hanoi',
 221                                   wx.Size(450, 350))
 222         self.SetTopWindow(self.frame)
 223 
 224         return True
 225 
 226 #---------------------------------------------------------------------------
 227 
 228 def main():
 229     app = wxHanoiApp()
 230     app.MainLoop()
 231 
 232 #---------------------------------------------------------------------------
 233 
 234 if __name__ == '__main__':
 235     main()


Second example

img_towers_of_hanoi_2.png

Readme file : hanoi1_README.md

License file : hanoi1_LICENSE.md

   1 # towers_of_hanoi_bis.py
   2 
   3 """
   4 The Towers of Hanoi
   5 
   6 Author: A. Polino
   7 Link : https://code.activestate.com/recipes/577511-hanoi-towers-solver-wxpython/
   8 """
   9 
  10 import wx
  11 import sys
  12 
  13 # def Gen_hanoi
  14 # def Create_plates
  15 # class Plate
  16 # class HanoiWindow
  17 # class HanoiFrame
  18 # class HanoiApp
  19 # class
  20 
  21 #---------------------------------------------------------------------------
  22 
  23 ## Make sure the windows is focused than press any button, and the program will move a plate. keep  ## pressing until the problem is solved
  24 ## by default it will display 5 plates. To change this, you have to call the script with a second   ## argument, wich is the number of plates (max 10)
  25 
  26 def Gen_hanoi(stack, start=1, temp=2, goal=3):
  27     """
  28     ...
  29     """
  30 
  31     if stack == 2:
  32         yield start, temp
  33         yield start, goal
  34         yield temp, goal
  35 
  36     else:
  37         for x in Gen_hanoi(stack - 1, start, goal, temp):
  38             yield x
  39         yield start, goal
  40 
  41         for x in Gen_hanoi(stack - 1, temp, start, goal):
  42             yield x
  43 
  44 #---------------------------------------------------------------------------
  45 
  46 def Create_plates(num):
  47     """
  48     ...
  49     """
  50 
  51     assert num <= 10
  52 
  53     x_start = 10
  54     x_len = 100
  55     plates = []
  56 
  57     for x in range(num):
  58         plates.append(Plate(x_len, x_start))
  59         x_len -= 10
  60         x_start += 5
  61 
  62     return plates
  63 
  64 #---------------------------------------------------------------------------
  65 
  66 class Plate(object):
  67     """
  68     ...
  69     """
  70     def __init__(self, x_len, x_start):
  71 
  72         #------------
  73 
  74         self.x_len = x_len
  75         self.x_start = x_start
  76 
  77 #---------------------------------------------------------------------------
  78 
  79 class HanoiWindow(wx.Window):
  80     """
  81     ...
  82     """
  83     def __init__(self, parent, num):
  84         wx.Window.__init__(self, parent, id=-1, pos=wx.Point(0, 0),
  85                            size=wx.DefaultSize, style=wx.SUNKEN_BORDER|
  86                            wx.WANTS_CHARS|wx.FULL_REPAINT_ON_RESIZE)
  87 
  88         #------------
  89 
  90         self.SetBackgroundColour(wx.Colour('#eceade'))
  91 
  92         #------------
  93 
  94         self.BindEvents()
  95 
  96         #------------
  97 
  98         self.towers = [Create_plates(num), [], []]
  99         self.solver = Gen_hanoi(num)
 100 
 101     #-----------------------------------------------------------------------
 102 
 103     def BindEvents(self):
 104         self.Bind(wx.EVT_PAINT, self.OnPaint)
 105         self.Bind(wx.EVT_KEY_UP, self.OnKeyUp)
 106 
 107 
 108     def OnPaint(self, evt):
 109         def draw_rect(x_len, x_start, y_start):
 110             dc = wx.PaintDC(self)
 111             font = dc.GetFont()
 112             font.SetPointSize(15)
 113             dc.SetFont(font)
 114             size, colour = 2, wx.Colour('black')
 115             dc.SetPen(wx.Pen(colour, size, wx.SOLID))
 116             point = wx.Point(x_start, y_start)
 117             dc.DrawLines([point, point + wx.Point(x_len, 0)])
 118             dc.DrawLines([point - wx.Point(0, 5), point + wx.Point(x_len, 0) - wx.Point(0, 5)])
 119             dc.DrawLines([point, point - wx.Point(0, 5)])
 120             dc.DrawLines([point + wx.Point(x_len, 0), point - wx.Point(0, 5) + wx.Point(x_len, 0)])
 121 
 122         w, h = self.GetClientSize()
 123         buffer = wx.Bitmap(w, h)
 124         dc = wx.PaintDC(self)
 125         font = dc.GetFont()
 126         font.SetPointSize(15)
 127         dc.SetFont(font)
 128         msg = 'Hanoi Towers'
 129         w, h = dc.GetTextExtent(msg)
 130         dc.DrawText(msg, 200, 20)
 131         size, colour = 8, wx.Colour('black')
 132         dc.SetPen(wx.Pen(colour, size, wx.SOLID))
 133         for num in range(len(self.towers)):
 134             y_start = 300
 135             tower = self.towers[num]
 136             num = num * 200 + 10
 137             point = wx.Point(num, y_start)
 138             dc.DrawLines([point, point + wx.Point(120, 0)]) # Base
 139             # Plates
 140             for plate in tower:
 141                 y_start -= 10
 142                 draw_rect(plate.x_len, num + plate.x_start, y_start)
 143 
 144 
 145     def OnKeyUp(self, evt):
 146         try:
 147             from_, to = next(self.solver)
 148             self.towers[to-1].append(self.towers[from_-1].pop())
 149             self.Refresh()
 150         except StopIteration:
 151             wx.MessageBox('Problem Solved !', 'Problem solved', wx.OK)
 152 
 153 #---------------------------------------------------------------------------
 154 
 155 class HanoiFrame(wx.Frame):
 156     """
 157     ...
 158     """
 159     def __init__(self, title, num):
 160         style=wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER ^ wx.MAXIMIZE_BOX
 161         wx.Frame.__init__(self, parent=None, id=-1,
 162                           title=title, size=(600, 500),
 163                           pos=(200, 200), style=style)
 164 
 165         #------------
 166 
 167         self.SetIcon(wx.Icon(".\icons\wxwin.ico"))
 168 
 169         #------------
 170 
 171         self.Window = HanoiWindow(self, num)
 172 
 173         #------------
 174 
 175         self.BindEvents()
 176 
 177         #------------
 178 
 179         self.CenterOnScreen(wx.BOTH)
 180         self.Show(True)
 181 
 182     #-----------------------------------------------------------------------
 183 
 184     def BindEvents(self):
 185         self.Bind(wx.EVT_CLOSE, self.close_frame)
 186 
 187 
 188     def close_frame(self, evt):
 189         # sys.exit(0)
 190         self.Destroy()
 191 
 192 #---------------------------------------------------------------------------
 193 
 194 class HanoiApp(wx.App):
 195     """
 196     ...
 197     """
 198     def OnInit(self):
 199         if len(sys.argv) < 2:
 200             num = 5
 201         else:
 202             num = int(sys.argv[1])
 203 
 204         #------------
 205 
 206         hano = HanoiFrame('Hanoi Towers', num)
 207         self.SetTopWindow(hano)
 208 
 209         return True
 210 
 211 #---------------------------------------------------------------------------
 212 
 213 def main():
 214     app = HanoiApp()
 215     app.MainLoop()
 216 
 217 #---------------------------------------------------------------------------
 218 
 219 if __name__ == '__main__':
 220     main()


Download source

source.zip


Additional Information

Link :

https://wiki.python.org/moin/GameProgramming

http://mientki.ruhosting.nl/data_www/pylab_works/pw_bricks_2d_scene.html

- - - - -

https://wiki.wxpython.org/TitleIndex

https://docs.wxpython.org/


Thanks to

Jan Bodnar (tetris.py coding), Hanming Zhang (tetris_bis.py coding), Zoenberger (memory_game.py coding), Hatenablog (reversi.py coding), S. Foster (towers_of_hanoi.py coding), A. Polino (towers_of_hanoi_bis.py coding), ActiveState, the wxPython community...


About this page

Date(d/m/y) Person (bot) Comments :

19/07/20 - Ecco (Created page for wxPython Phoenix).

14/01/23 - Ecco (Updated page and "source.zip" for Python 3.10.5).


Comments

- blah, blah, blah...

How to create a game for wxPython - Part 1 (Phoenix) (last edited 2023-01-14 15:55:08 by Ecco)

NOTE: To edit pages in this wiki you must be a member of the TrustedEditorsGroup.