[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    playground/games/kmj
From:       Wolfgang Rohdewald <wolfgang () rohdewald ! de>
Date:       2009-02-26 13:46:38
Message-ID: 1235655998.960640.6333.nullmailer () svn ! kde ! org
[Download RAW message or body]

SVN commit 932374 by wrohdewald:

introducing Walls.divide()


 M  +90 -28    board.py  
 M  +6 -7      kmj.py  


--- trunk/playground/games/kmj/board.py #932373:932374
@@ -35,20 +35,30 @@
     the unit of xoffset is the width of the tile, 
     the unit of yoffset is the height of the tile. 
     """
-    def __init__(self, element,  xoffset = 0, yoffset = 0, level=0):
+    def __init__(self, element,  xoffset = 0, yoffset = 0, level=0,  faceDown=False):
         QGraphicsSvgItem.__init__(self)
         self.__board = None
         self.element = element
         self.selected = False
+        self.__faceDown = faceDown
         self.level = level
         self.xoffset = xoffset
         self.yoffset = yoffset
         self.face = None
 
-    def xmousePressEvent(self, event):
+    def mousePressEvent(self, event):
         """selects the tile. While moving, it should be above all other tiles"""
+        # TODO: find out which tile is clicked on. Do not react when clicking on shadow...
+        for tile in self.collidingItems():
+            if isinstance(tile, Tile) and tile.zValue() > self.zValue():
+                print 'other tile %s has z=%d, we(%s) have z=%d' \
+                    % (tile.element, tile.zValue(), self.element, self.zValue())
+                QGraphicsSvgItem.mousePressEvent(self, event)
+                return
 #        self.setZValue(1000000000)
+#        self.select()
         print 'mousepos:', self.mapToScene(event.pos())
+        print 'tile:', self.element
         print 'tilerect:', self.mapToScene(self.boundingRect()).boundingRect()
         print 'tileset.tilesize:', self.tileset.tileSize
         if self.face:
@@ -75,11 +85,15 @@
 
     def setBoard(self, board):
         """assign the tile to a board and define it according to the board parameters"""
-        if self.__board and board != self.__board:
-            logException(TileException('Tile can only belong to one board'))
+#        if self.__board and board != self.__board:
+   #         logException(TileException('Tile can only belong to one board'))
+        self.__board = board
+        self.recompute()
+        
+    def recompute(self):
+        """recomputes position and visuals of the tile"""
         self.prepareGeometryChange()
-        self.__board = board
-        self.setParentItem(board)
+        self.setParentItem(self.__board)
         self.placeInScene()
         self.setSharedRenderer(self.tileset.renderer())
         lightSource = self.board.lightSource
@@ -93,7 +107,7 @@
             xoffset = shadowWidth-1
         if 'S' in lightSource:
             yoffset = shadowHeight-1
-        if self.element:
+        if self.element and not self.faceDown:
             if not self.face:
                 self.face = QGraphicsSvgItem()
                 self.face.setParentItem(self)
@@ -102,12 +116,31 @@
             # by shadow width
             self.face.setPos(xoffset, yoffset)
             self.face.setSharedRenderer(self.tileset.renderer())
-        else:
+        elif self.face:
             self.face = None
         self.setTileId()
      
     board = property(getBoard, setBoard)
+
+    def getFaceDown(self):
+        """does the tile with face down?"""
+        return self.__faceDown
+        
+    def setFaceDown(self, faceDown):
+        """turn the tile face up/down"""
+        self.__faceDown = faceDown
+        self.recompute()
+        
+    faceDown = property(getFaceDown, setFaceDown)
     
+    def setPos(self, xoffset=0, yoffset=0, level=0):
+        """change Position of tile in board"""
+        self.level = level
+        self.xoffset = xoffset
+        self.yoffset = yoffset
+        self.board.setDrawingOrder()
+        self.recompute()
+        
     def setTileId(self):
         """sets the SVG element id of the tile"""
         lightSourceIndex = LIGHTSOURCES.index(self.board.rotatedLightSource())
@@ -143,14 +176,13 @@
         shiftZ = self.board.shiftZ(self.level)
         sceneX = self.xoffset*width+ shiftZ.x()
         sceneY = self.yoffset*height+ shiftZ.y()
-        self.setPos(sceneX, sceneY)
+        QGraphicsRectItem.setPos(self, sceneX, sceneY)
      
     def select(self, selected=True):
         """selected tiles are drawn differently"""
         if self.selected != selected:
             self.selected = selected
             self.setTileId()
-
  
 class PlayerWind(QGraphicsEllipseItem):
     """a round wind tile"""
@@ -230,11 +262,11 @@
             result += rect.top()
         return result
 
-    def addTile(self,  element,  xoffset = 0, yoffset = 0, level=0):
+    def addTile(self,  element,  xoffset = 0, yoffset = 0, level=0,  faceDown=False):
         """adds a new tile to the board. If a tile with the same size exists at this        
             position, change that existing tile and return the existing tile. If a
             tile exists with the same topleft position, we delete that one first"""
-        tile = Tile(element, xoffset, yoffset, level=level)
+        tile = Tile(element, xoffset, yoffset, level=level,  faceDown=faceDown)
         tile.board = self
         self.setDrawingOrder()
         return tile
@@ -373,22 +405,30 @@
                 item.placeInScene()
         return
         
-    def allTiles(self):
-        """returns a list with all tileface names"""
+    def getAllTiles(self):
+        """returns a randomized list with all tileface names,
+        This list will be built only if it does not yet exist. If you want it to
+        be rebuilt with new random values, use flushAllTiles"""
         if len(self.__allTiles) == 0:
             for name, num, amount in (('CHARACTER', 9, 4), ('BAMBOO', 9, 4), 
                 ('ROD', 9, 4), ('SEASON', 4, 1), ('FLOWER', 4, 1), ('WIND', 4, 4),
                 ('DRAGON', 3, 4)):
                 for idx in range(1, num+1):
                     self.__allTiles.extend([name + '_' + str(idx)]*amount)
-        return list(self.__allTiles)
+        random.shuffle(self.__allTiles)
+        return self.__allTiles
 
+    allTiles = property(getAllTiles)
+    
+    def flushAllTiles(self):
+        """throw away the random tile list. Next access to allTiles will rebuild it"""
+        self.__allTiles = []
+
     def randomTile144(self):
         """a generator returning 144 random tiles"""
-        tiles = self.allTiles()
-        random.shuffle(tiles)
-        for idx in range(0, len(tiles)):
-            yield tiles[idx]
+        self.flushAllTiles()
+        for idx in range(0, len(self.allTiles)):
+            yield self.allTiles[idx]
 
 
 class FittingView(QGraphicsView):
@@ -424,15 +464,19 @@
     def __init__(self, length, tileset):
         Board.__init__(self)
         self.length = length
-        self.dividePos = None
         self.lightSource = 'NW'
         self.tileset = tileset
-        self.walls = [self.wall(angle) for angle in (270, 0, 90, 180)]
-        self.walls[0].setPos(xWidth=self.length, yWidth=self.length, yHeight=1 )
-        self.walls[1].setPos(yWidth=self.length)
-        self.walls[2].setPos(xHeight=1)
-        self.walls[3].setPos(xHeight=1, xWidth=self.length, yHeight=1)
+        self.tile = self.randomTile144()
+        self.tiles = []
+        # living end: self.tiles[0]
+        # dead end: self.tiles[-1]
+        self.walls = [self.wall(angle) for angle in (0, 90, 180,  270)]
+        self.walls[0].setPos(yWidth=self.length)
+        self.walls[1].setPos(xHeight=1)
+        self.walls[2].setPos(xHeight=1, xWidth=self.length, yHeight=1)
+        self.walls[3].setPos(xWidth=self.length, yWidth=self.length, yHeight=1 )
         self.setDrawingOrder()
+        self.divide(0, 4)
 
     def __getitem__(self, index):
         return self.walls[index]
@@ -442,11 +486,29 @@
         result = Board(rotation)
         result.setParentItem(self)
         result.lightSource = self.lightSource
-        for position in range(0, self.length):
-            result.addTile('', position)
-            result.addTile('', position, level=1)
+        for position in range(self.length-1, -1, -1):
+            self.tiles.append(result.addTile(self.tile.next(), position, level=1, faceDown=True))
+            self.tiles.append(result.addTile(self.tile.next(), position, faceDown=True))
         return result
+        
+    def moveDividedTile(self, angle,  tile, offset):
+        """moves a tile from the divide hole to its new place"""
+        newOffset = tile.xoffset + offset
+        if newOffset >= self.length:
+            tile.board = self.walls[(angle//90+3) % 4]
+        tile.setPos(newOffset % self.length, level=2)
 
+    def divide(self, angle, diceSum):
+        """divides the wall with angle, building a living and and a dead end"""
+        livingEnd = angle//90 * self.length + diceSum*2
+        # shift tiles: tile[0] becomes living end
+        self.tiles = self.tiles[livingEnd:] + self.tiles[0:livingEnd]
+        # move last two tiles onto the dead end:
+        self.moveDividedTile(angle, self.tiles[-1], 3)
+        self.moveDividedTile(angle,  self.tiles[-2], 5)
+        self.tiles = self.tiles[:-12] + self.tiles[-2:-1] + self.tiles[-12:-8] + \
+                            self.tiles[-1:] + self.tiles[-8:-2]
+        
 class Shisen(Board):
     """builds a Shisen board, just for testing"""
     def __init__(self):
--- trunk/playground/games/kmj/kmj.py #932373:932374
@@ -528,8 +528,8 @@
         """sets the background of the central widget"""
         if not self.background:
             self.background = Background(self.pref.background)
-        self.background.setPalette(self.centralWidget)
-        self.centralWidget.setAutoFillBackground(True)
+        self.background.setPalette(self.centralWidget())
+        self.centralWidget().setAutoFillBackground(True)
     
     def resizeEvent(self, event):
         """adapt background to new window size"""
@@ -544,10 +544,10 @@
         for a huge rect like 4000x3000 where my screen only has
         1920x1200"""
         self.setObjectName("MainWindow")
-        self.centralWidget = QWidget()
+        centralWidget = QWidget()
         self.centralScene = QGraphicsScene()
         self.centralView = FittingView()
-        layout = QGridLayout(self.centralWidget)
+        layout = QGridLayout(centralWidget)
         layout.setContentsMargins(0, 0, 0, 0)
         layout.addWidget(self.centralView)
         self.centralView.setScene(self.centralScene)
@@ -562,7 +562,7 @@
         for player in self.players:
             player.wind.setTileset(self.windTileset)
             
-        self.setCentralWidget(self.centralWidget)
+        self.setCentralWidget(centralWidget)
         self.actionNewGame = self.kmjAction("new", "document-new", self.newGame)
         self.actionPlayers = self.kmjAction("players",  "personal",  self.slotPlayers)
         self.actionNewHand = self.kmjAction("newhand",  "object-rotate-left",  self.newHand)
@@ -634,8 +634,7 @@
         tileset from the config dialog is only  applied the first time. It always
         works if we ensure that the Tileset class gets a string with a
         different id. Maybe there is a problem in the interaction between
-        python strings and QString.
-        TODO: I should really find out if this is a bug in my code or in pyqt"""
+        python strings and QString."""
         if self.tileset.desktopFileName != self.pref.tileset:
             self.tileset = Tileset(self.pref.tileset+'x'[:-1])
             self.walls.tileset = self.tileset
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic