[gnome-games] chess: Add an option for showing captured pieces (Bug #510732)



commit 563ea4b585aef25b3cc9fda255126a160b554ea5
Author: Greg McNew <gmcnew gmail com>
Date:   Wed Nov 10 17:01:29 2010 +1100

    chess: Add an option for showing captured pieces (Bug #510732)

 glchess/data/preferences.ui             |   25 ++++++-
 glchess/src/lib/config.py               |    1 +
 glchess/src/lib/display.py              |  104 +++++++++++++++++++++++++++----
 glchess/src/lib/gtkui/dialogs.py        |   12 +++-
 glchess/src/lib/main.py                 |    1 +
 glchess/src/lib/scene/__init__.py       |   15 ++++-
 glchess/src/lib/scene/cairo/__init__.py |   70 +++++++++++++++++----
 glchess/src/lib/scene/opengl/opengl.py  |   71 ++++++++++++++++-----
 8 files changed, 249 insertions(+), 50 deletions(-)
---
diff --git a/glchess/data/preferences.ui b/glchess/data/preferences.ui
index 1f632ca..543c40e 100644
--- a/glchess/data/preferences.ui
+++ b/glchess/data/preferences.ui
@@ -234,6 +234,23 @@
                   </packing>
                 </child>
                 <child>
+                  <object class="GtkCheckButton" id="show_captured_pieces">
+                    <property name="label" translatable="yes" comments="Preferences Dialog: Check box for selecting if captured pieces are visible">Show _Captured Pieces</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">False</property>
+                    <property name="tooltip_text" translatable="yes">Show or hide captured pieces</property>
+                    <property name="use_underline">True</property>
+                    <property name="draw_indicator">True</property>
+                    <signal name="toggled" handler="_on_show_captured_pieces_activate"/>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">3</property>
+                  </packing>
+                </child>
+                <child>
                   <object class="GtkCheckButton" id="show_toolbar">
                     <property name="label" translatable="yes" comments="Preferences Dialog: Check box for selecting if toolbar is visible">Show _Toolbar</property>
                     <property name="visible">True</property>
@@ -247,7 +264,7 @@
                   <packing>
                     <property name="expand">False</property>
                     <property name="fill">False</property>
-                    <property name="position">3</property>
+                    <property name="position">4</property>
                   </packing>
                 </child>
                 <child>
@@ -264,7 +281,7 @@
                   <packing>
                     <property name="expand">False</property>
                     <property name="fill">False</property>
-                    <property name="position">4</property>
+                    <property name="position">5</property>
                   </packing>
                 </child>
                 <child>
@@ -281,7 +298,7 @@
                   <packing>
                     <property name="expand">False</property>
                     <property name="fill">False</property>
-                    <property name="position">5</property>
+                    <property name="position">6</property>
                   </packing>
                 </child>
                 <child>
@@ -298,7 +315,7 @@
                   <packing>
                     <property name="expand">False</property>
                     <property name="fill">False</property>
-                    <property name="position">6</property>
+                    <property name="position">7</property>
                   </packing>
                 </child>
               </object>
diff --git a/glchess/src/lib/config.py b/glchess/src/lib/config.py
index 834e753..e19f1ae 100644
--- a/glchess/src/lib/config.py
+++ b/glchess/src/lib/config.py
@@ -83,6 +83,7 @@ _defaults = {'show_toolbar':                     True,
              'board_view':                       'human',
              'show_comments':                    False,
              'show_numbering':                   False,
+             'show_captured_pieces':             False,
              'enable_networking':                True,
              'load_directory':                   '',
              'save_directory':                   '',
diff --git a/glchess/src/lib/display.py b/glchess/src/lib/display.py
index 6bfede1..bdb5922 100644
--- a/glchess/src/lib/display.py
+++ b/glchess/src/lib/display.py
@@ -78,6 +78,18 @@ class SceneCairo(scene.SceneFeedback, scene.human.SceneHumanInput):
     def getPieces(self):
         return self.pieces.values()
 
+    def addPiece(self, piece, location, captured = False):
+        pieceName = {chess.board.PAWN: 'pawn', chess.board.ROOK: 'rook', chess.board.KNIGHT: 'knight',
+                     chess.board.BISHOP: 'bishop', chess.board.QUEEN: 'queen', chess.board.KING: 'king'}[piece.getType()]
+        chessSet = {chess.board.WHITE: 'white', chess.board.BLACK: 'black'}[piece.getColour()]
+        p = CairoPiece(self, piece)
+        style = config.get('piece_style')
+        p.model = self.controller.addChessPiece(chessSet, pieceName, location, p, style=style, captured=captured)
+        p.location = location
+        if not captured:
+            self.pieces[piece] = p
+        return p
+
     def movePiece(self, piece, location, delete, animate):
         """
         """
@@ -86,13 +98,7 @@ class SceneCairo(scene.SceneFeedback, scene.human.SceneHumanInput):
             p = self.pieces[piece]
         except KeyError:
             # Make the new model
-            pieceName = {chess.board.PAWN: 'pawn', chess.board.ROOK: 'rook', chess.board.KNIGHT: 'knight',
-                         chess.board.BISHOP: 'bishop', chess.board.QUEEN: 'queen', chess.board.KING: 'king'}[piece.getType()]
-            chessSet = {chess.board.WHITE: 'white', chess.board.BLACK: 'black'}[piece.getColour()]
-            p = CairoPiece(self, piece)
-            style = piecesStyle = config.get('piece_style')
-            p.model = self.controller.addChessPiece(chessSet, pieceName, location, p, style=style)
-            self.pieces[piece] = p
+            p = self.addPiece(piece, location)
 
         # Move the model
         p.location = location
@@ -100,6 +106,11 @@ class SceneCairo(scene.SceneFeedback, scene.human.SceneHumanInput):
         
         return p
 
+    def clearCapturedPieces(self):
+        """
+        """
+        self.controller.clearCapturedPieces()
+
     # Extended methods
 
     def onRedraw(self):
@@ -174,6 +185,17 @@ class SceneOpenGL(scene.SceneFeedback, scene.human.SceneHumanInput):
     def getPieces(self):
         return self.pieces.values()
         
+    def addPiece(self, piece, location, captured = False):
+        pieceName = {chess.board.PAWN: 'pawn', chess.board.ROOK: 'rook', chess.board.KNIGHT: 'knight',
+                     chess.board.BISHOP: 'bishop', chess.board.QUEEN: 'queen', chess.board.KING: 'king'}[piece.getType()]
+        chessSet = {chess.board.WHITE: 'white', chess.board.BLACK: 'black'}[piece.getColour()]
+        p = OpenGLPiece(self, piece)
+        p.model = self.controller.addChessPiece(chessSet, pieceName, location, p, captured=captured)
+        p.location = location
+        if not captured:
+            self.pieces[piece] = p
+        return p
+
     def movePiece(self, piece, location, delete, animate):
         """
         """
@@ -182,12 +204,7 @@ class SceneOpenGL(scene.SceneFeedback, scene.human.SceneHumanInput):
             p = self.pieces[piece]
         except KeyError:
             # Make the new model
-            pieceName = {chess.board.PAWN: 'pawn', chess.board.ROOK: 'rook', chess.board.KNIGHT: 'knight',
-                         chess.board.BISHOP: 'bishop', chess.board.QUEEN: 'queen', chess.board.KING: 'king'}[piece.getType()]
-            chessSet = {chess.board.WHITE: 'white', chess.board.BLACK: 'black'}[piece.getColour()]
-            p = OpenGLPiece(self, piece)
-            p.model = self.controller.addChessPiece(chessSet, pieceName, location, p)
-            self.pieces[piece] = p
+            p = self.addPiece(piece, location)
             
         # Move the model
         p.location = location
@@ -195,6 +212,11 @@ class SceneOpenGL(scene.SceneFeedback, scene.human.SceneHumanInput):
 
         return p
 
+    def clearCapturedPieces(self):
+        """
+        """
+        self.controller.clearCapturedPieces()
+
     # Extended methods
 
     def onRedraw(self):
@@ -262,6 +284,11 @@ class Splashscreen(ui.ViewFeedback):
         self.scene.showBoardNumbering(showNumbering)
         self.cairoScene.showBoardNumbering(showNumbering)
 
+    def showCapturedPieces(self, showCaptured):
+        """Called by ui.ViewFeedback"""
+        self.scene.controller.showCapturedPieces(showCaptured)
+        self.cairoScene.controller.showCapturedPieces(showCaptured)
+
     def showMoveHints(self, showHints):
         """Called by ui.ViewFeedback"""
         pass
@@ -326,6 +353,7 @@ class View(ui.ViewFeedback):
         self.selectedCoord = None
         self.showHints = False
         self.showNumbering = False
+        self.showCaptured = False
         self.doSmooth = False
         self.highlightParams = (None, None, None, None)
         self.changedHighlight = True
@@ -338,6 +366,7 @@ class View(ui.ViewFeedback):
         self.scene = SceneCairo(self)
         config.watch('board_view', self.__onBoardViewChanged)
         config.watch('piece_style', self.__onPiecesStyleChanged)
+        config.watch('show_captured_pieces', self.__onShowCapturedPiecesChanged)
 
         # Look for game events to update the scene
         movePlayer = MovePlayer(self)
@@ -360,6 +389,9 @@ class View(ui.ViewFeedback):
     def __onPiecesStyleChanged(self, key, value):
         self.updatePiecesStyle()
 
+    def __onShowCapturedPiecesChanged(self, key, value):
+        self.showCapturedPieces(value)
+
     def _updateHighlight(self, coord):
         if self.moveNumber == -1:
             player = self.game.getCurrentPlayer()
@@ -447,6 +479,11 @@ class View(ui.ViewFeedback):
         """Called by ui.ViewFeedback"""
         self.showNumbering = showNumbering
         self.scene.controller.showBoardNumbering(showNumbering)
+
+    def showCapturedPieces(self, showCaptured):
+        """Called by ui.ViewFeedback and __onShowCapturedPiecesChanged"""
+        self.showCaptured = showCaptured
+        self.scene.controller.showCapturedPieces(showCaptured)
         
     def showSmooth(self, doSmooth):
         """Called by ui.ViewFeedback"""
@@ -467,6 +504,7 @@ class View(ui.ViewFeedback):
         self.reshape(self.width, self.height)
         self.setMoveNumber(self.moveNumber)
         self.showBoardNumbering(self.showNumbering)
+        self.showCapturedPieces(self.showCaptured)
         self.showSmooth(self.doSmooth)
         self.updateRotation(animate = False)
 
@@ -498,6 +536,40 @@ class View(ui.ViewFeedback):
     def deselect(self, x, y):
         """Called by ui.ViewFeedback"""
         self.scene.deselect(x, y)
+        
+    __capturedTypeSortOrder = [
+        chess.board.QUEEN,  chess.board.ROOK, chess.board.BISHOP,
+        chess.board.KNIGHT, chess.board.PAWN
+        ]
+
+    @classmethod
+    def __capturedPieceTypeKey(cls, piece):
+        return cls.__capturedTypeSortOrder.index(piece.getType())
+    
+    @classmethod
+    def __getCapturedPieceLocations(cls, pieces):
+        whitePiece = 0
+        blackPiece = 0
+        
+        pieceLocations = {}
+        
+        # Sort captured pieces by type.
+        for piece in sorted(pieces, key = cls.__capturedPieceTypeKey):
+            if piece.getColour() == chess.board.WHITE:
+                # Captured white pieces go near black's queenside: files
+                # 'a' and 'b' (starting at 'b'), rank 8 to rank 1.
+                rank = ['a', 'b'][(whitePiece + 1) % 2]
+                file = 8 - (whitePiece / 2)
+                whitePiece += 1
+            else:
+                # Captured black pieces go near white's kingside: files
+                # 'g' and 'h' (starting at 'g'), rank 1 to rank 8.
+                rank = ['g', 'h'][blackPiece % 2]
+                file = 1 + (blackPiece / 2)
+                blackPiece += 1
+            pieceLocations[piece] = "%s%s" % (rank, file)
+
+        return pieceLocations
     
     def setMoveNumber(self, moveNumber):
         """Called by ui.ViewFeedback"""
@@ -520,6 +592,12 @@ class View(ui.ViewFeedback):
         # Move the models in the scene
         for (location, piece) in piecesByLocation.iteritems():
             self.scene.movePiece(piece, location, False, True)
+        
+        # Handle captured pieces
+        capturedPieceLocations = self.__getCapturedPieceLocations(self.game.getDeadPieces(moveNumber))
+        self.scene.clearCapturedPieces()
+        for (piece, location) in capturedPieceLocations.iteritems():
+            self.scene.addPiece(piece, location, captured = True)
 
         # Can't wait for animation if not looking at the latest move
         if moveNumber != -1:
diff --git a/glchess/src/lib/gtkui/dialogs.py b/glchess/src/lib/gtkui/dialogs.py
index 0ba8189..a1be90b 100644
--- a/glchess/src/lib/gtkui/dialogs.py
+++ b/glchess/src/lib/gtkui/dialogs.py
@@ -682,7 +682,8 @@ class GtkPreferencesDialog:
         # Watch for config changes
         for key in ['show_3d', 'show_3d_smooth', 'piece_style', 'show_toolbar',
                     'show_history', 'show_move_hints', 'show_numbering',
-                    'move_format', 'board_view', 'promotion_type']:
+                    'move_format', 'board_view', 'promotion_type',
+                    'show_captured_pieces']:
             glchess.config.watch(key, self.__applyConfig)
             try:
                 value = glchess.config.get(key)
@@ -708,6 +709,9 @@ class GtkPreferencesDialog:
                 if row[1] == value:
                     widget.set_active_iter(row.iter)
                 
+        elif name == 'show_captured_pieces':
+            self.__gui.get_object('show_captured_pieces').set_active(value)
+                
         elif name == 'show_toolbar':
             self.__gui.get_object('show_toolbar').set_active(value)
                 
@@ -803,7 +807,11 @@ class GtkPreferencesDialog:
         
     def _on_3d_smooth_toggled(self, widget):
         """Gtk+ callback"""
-        glchess.config.set('show_3d_smooth', widget.get_active())        
+        glchess.config.set('show_3d_smooth', widget.get_active())
+
+    def _on_show_captured_pieces_activate(self, widget):
+        """Gtk+ callback"""
+        glchess.config.set('show_captured_pieces', widget.get_active())
 
     def _on_show_toolbar_activate(self, widget):
         """Gtk+ callback"""
diff --git a/glchess/src/lib/main.py b/glchess/src/lib/main.py
index baa9fe8..30226f7 100644
--- a/glchess/src/lib/main.py
+++ b/glchess/src/lib/main.py
@@ -90,6 +90,7 @@ class ChessGame(game.ChessGame):
 
         self.view.showMoveHints(config.get('show_move_hints') is True)
         self.view.showBoardNumbering(config.get('show_numbering') is True)
+        self.view.showCapturedPieces(config.get('show_captured_pieces') is True)
         self.view.showSmooth(config.get('show_3d_smooth') is True)        
         
         # Watch for piece moves with a player
diff --git a/glchess/src/lib/scene/__init__.py b/glchess/src/lib/scene/__init__.py
index e6c9223..2def7b3 100644
--- a/glchess/src/lib/scene/__init__.py
+++ b/glchess/src/lib/scene/__init__.py
@@ -76,7 +76,7 @@ class Scene:
         """
         pass
 
-    def addChessPiece(self, chessSet, name, coord, feedback):
+    def addChessPiece(self, chessSet, name, coord, feedback, captured = False):
         """Add a chess piece model into the scene.
         
         'chessSet' is the name of the chess set (string).
@@ -88,6 +88,14 @@ class Scene:
         """
         raise Exception('Not implemented')
 
+    def clearCapturedPieces(self):
+        """Remove all captured pieces from the scene.
+        
+        This is typically followed by calls to addChessPiece() with
+        captured = True.
+        """
+        raise Exception('Not implemented')
+
     def setBoardHighlight(self, coords):
         """Highlight a square on the board.
         
@@ -114,6 +122,11 @@ class Scene:
         """
         pass
         
+    def showCapturedPieces(self, showCaptured):
+        """
+        """
+        pass
+
     def showBoardDarker(self, showDarker):
         """
         """
diff --git a/glchess/src/lib/scene/cairo/__init__.py b/glchess/src/lib/scene/cairo/__init__.py
index 7e12c4d..06b2564 100644
--- a/glchess/src/lib/scene/cairo/__init__.py
+++ b/glchess/src/lib/scene/cairo/__init__.py
@@ -45,12 +45,13 @@ class ChessPiece(glchess.scene.ChessPiece):
     """
     """
 
-    def __init__(self, scene, name, coord, feedback, style='simple'):
+    def __init__(self, scene, name, coord, feedback, style='simple', captured=False):
         """
         """
         self.scene = scene
         self.feedback = feedback
         self.name = name
+        self.captured = captured
         self.coord = coord # Co-ordinate being moved to
         self.pos = self.__coordToLocation(coord) # Current position
         self.targetPos   = None
@@ -62,10 +63,22 @@ class ChessPiece(glchess.scene.ChessPiece):
     def __coordToLocation(self, coord):
         """
         """
-        rank = ord(coord[0]) - ord('a')
-        file = ord(coord[1]) - ord('1')
+        file = ord(coord[0]) - ord('a')
+        rank = ord(coord[1]) - ord('1')
+        
+        if self.captured:
+            # For captured pieces, coordinates refer to a position in
+            # the imaginary 2x8 trays at each side of the table.
+            # Captured white pieces are placed at the queenside (near
+            # files a and b), and captured black pieces are placed at
+            # the kingside (near files g and h). We shift the resulting
+            # positions off the board by 3 files.
+            if coord[0] in ['a', 'b']:
+                file -= 3
+            else:
+                file += 3
         
-        return (float(rank), float(file))
+        return (float(file), float(rank))
 
     def setStyle(self, style):
         self.style = style
@@ -186,6 +199,7 @@ class Scene(glchess.scene.Scene):
         self.feedback        = feedback
         self.highlight       = {}
         self.pieces          = []
+        self.capturedPieces  = []
         self._animationQueue = []
         self.angle           = 0.0
         self.targetAngle     = 0.0
@@ -193,13 +207,16 @@ class Scene(glchess.scene.Scene):
         self.redrawStatic    = True
         self.showNumbering   = False
         self.faceToFace      = False
+        self.showCaptured    = False
+        self.width           = 0
+        self.height          = 0
         try:
             pixbuf = gtk.gdk.pixbuf_new_from_file(os.path.join(glchess.defaults.SHARED_IMAGE_DIR, 'baize.png'))
             (self.background_pixmap, _) = pixbuf.render_pixmap_and_mask()
         except gobject.GError:
             self.background_pixmap = None
 
-    def addChessPiece(self, chessSet, name, coord, feedback, style = 'simple'):
+    def addChessPiece(self, chessSet, name, coord, feedback, style = 'simple', captured = False):
         """Add a chess piece model into the scene.
         
         'chessSet' is the name of the chess set (string).
@@ -209,14 +226,21 @@ class Scene(glchess.scene.Scene):
         Returns a reference to this chess piece or raises an exception.
         """
         name = chessSet + name[0].upper() + name[1:]
-        piece = ChessPiece(self, name, coord, feedback, style=style)
-        self.pieces.append(piece)
+        piece = ChessPiece(self, name, coord, feedback, style=style, captured=captured)
+        
+        if captured:
+            self.capturedPieces.append(piece)
+        else:
+            self.pieces.append(piece)
         
         # Redraw the scene
         self.redrawStatic = True
         self.feedback.onRedraw()
         
         return piece
+        
+    def clearCapturedPieces(self):
+        self.capturedPieces = []
 
     def setBoardHighlight(self, coords):
         """Highlight a square on the board.
@@ -248,8 +272,23 @@ class Scene(glchess.scene.Scene):
         self.height = height
         
         # Make the squares as large as possible while still pixel aligned
-        shortEdge = min(self.width, self.height)
-        self.squareSize = math.floor((shortEdge - 2.0*self.BORDER) / 9.0)
+        
+        insideWidth = self.width - 2.0*self.BORDER
+        insideHeight = self.height - 2.0*self.BORDER
+        
+        # We need room for 9 squares in each dimension: 8 for the board
+        # and 1 for the board's edges (0.5 squares per side).
+        vSquares = 9
+        hSquares = 9
+        
+        # If we're supposed to show captured pieces, we need room for 6
+        # more squares in the horizontal dimension. Each side of the
+        # board will have two columns of captured pieces, surrounded by
+        # a half-square margin of empty space.
+        if self.showCaptured:
+            hSquares += 6
+        
+        self.squareSize = math.floor(min(insideWidth / hSquares, insideHeight / vSquares))
         self.pieceSize = self.squareSize - 2.0*self.PIECE_BORDER
 
         self.redrawStatic = True
@@ -283,10 +322,17 @@ class Scene(glchess.scene.Scene):
             self.feedback.onRedraw()
 
     def setPiecesStyle(self, piecesStyle):
-        for piece in self.pieces:
+        for piece in self.pieces + self.capturedPieces:
             piece.setStyle(piecesStyle)
         self.redrawStatic = True
         self.feedback.onRedraw()
+
+    def showCapturedPieces(self, showCaptured):
+        if self.showCaptured != showCaptured:
+            self.showCaptured = showCaptured
+            self.redrawStatic = True
+            self.reshape(self.width, self.height)
+            self.feedback.onRedraw()
     
     def animate(self, timeStep):
         """Extends glchess.scene.Scene"""
@@ -448,7 +494,7 @@ class Scene(glchess.scene.Scene):
                 context.fill()
                 
         context.set_source_rgb(*PIECE_COLOUR)
-        for piece in self.pieces:
+        for piece in (self.pieces + self.capturedPieces if self.showCaptured else self.pieces):
             if piece.moving:
                 continue
             piece.render(context)
@@ -464,7 +510,7 @@ class Scene(glchess.scene.Scene):
         self.__rotate(context)
 
         context.set_source_rgb(*PIECE_COLOUR)
-        for piece in self.pieces:
+        for piece in (self.pieces + self.capturedPieces if self.showCaptured else self.pieces):
             # If not rotating and piece not moving then was rendered in the static phase
             if self.angle == self.targetAngle and not piece.moving:
                 continue
diff --git a/glchess/src/lib/scene/opengl/opengl.py b/glchess/src/lib/scene/opengl/opengl.py
index e78ca8f..7ff4c44 100644
--- a/glchess/src/lib/scene/opengl/opengl.py
+++ b/glchess/src/lib/scene/opengl/opengl.py
@@ -94,15 +94,16 @@ class ChessPiece(glchess.scene.ChessPiece):
     """
     """    
     
-    def __init__(self, scene, chessSet, name, location, feedback):
+    def __init__(self, scene, chessSet, name, location, feedback, captured=False):
         """
         """
         self.scene = scene
         self.feedback = feedback
         self.chessSet = chessSet
         self.name = name
+        self.captured = captured
         self.location = location
-        self.pos = self.scene._coordToLocation(location)
+        self.pos = self._coordToLocation(location)
         self.targetPos = None  # Position moving to
         self.moving    = False # Is the piece moving?
         self.delete    = False # Delete once moved?
@@ -116,7 +117,7 @@ class ChessPiece(glchess.scene.ChessPiece):
 
         self.delete = delete
         self.location = coord
-        self.targetPos = self.scene._coordToLocation(coord)
+        self.targetPos = self._coordToLocation(coord)
         
         # If already there then delete
         if self.pos == self.targetPos:
@@ -183,6 +184,31 @@ class ChessPiece(glchess.scene.ChessPiece):
         self.pos = (self.pos[0] + xStep, self.pos[1] + yStep, self.pos[2] + zStep)
         return True
 
+    # Private methods
+
+    def _coordToLocation(self, coord):
+        """
+        """
+        file = ord(coord[0]) - ord('a')
+        rank = ord(coord[1]) - ord('1')
+        
+        if self.captured:
+            # For captured pieces, coordinates refer to a position in
+            # the imaginary 2x8 trays at each side of the table.
+            # Captured white pieces are placed at the queenside (near
+            # files a and b), and captured black pieces are placed at
+            # the kingside (near files g and h). We shift the resulting
+            # positions off the board by 3 files.
+            if coord[0] in ['a', 'b']:
+                file -= 3
+            else:
+                file += 3
+
+        x = BOARD_BORDER + float(file) * SQUARE_WIDTH + 0.5 * SQUARE_WIDTH
+        z = -(BOARD_BORDER + float(rank) * SQUARE_WIDTH + 0.5 * SQUARE_WIDTH)
+
+        return (x, 0.0, z)
+
 class Scene(glchess.scene.Scene):
     """
     """
@@ -214,6 +240,10 @@ class Scene(glchess.scene.Scene):
         # OpenGL display list for the board and a flag to regenerate it
         self.boardList        = None
         self.regenerateBoard  = False
+        
+        # Captured pieces
+        self.capturedPieces  = []
+        self.showCaptured    = False
     
         self.jitters = ((0.0, 0.0),)
 
@@ -234,7 +264,7 @@ class Scene(glchess.scene.Scene):
         """This method is called when the scene needs redrawing"""
         pass
     
-    def addChessPiece(self, chessSet, name, coord, feedback):
+    def addChessPiece(self, chessSet, name, coord, feedback, captured=False):
         """Add a chess piece model into the scene.
         
         'chessSet' is the name of the chess set (string).
@@ -245,14 +275,21 @@ class Scene(glchess.scene.Scene):
         Returns a reference to this chess piece or raises an exception.
         """
         chessSet = self.chessSets[chessSet]
-        piece = ChessPiece(self, chessSet, name, coord, feedback)
-        self.pieces.append(piece)
+        piece = ChessPiece(self, chessSet, name, coord, feedback, captured)
+        
+        if captured:
+            self.capturedPieces.append(piece)
+        else:
+            self.pieces.append(piece)
         
         # Redraw the scene
         self.feedback.onRedraw()
         
         return piece
 
+    def clearCapturedPieces(self):
+        self.capturedPieces = []
+
     def setBoardHighlight(self, coords):
         """Highlight a square on the board.
         
@@ -270,6 +307,13 @@ class Scene(glchess.scene.Scene):
 
         self.feedback.onRedraw()
 
+    def showCapturedPieces(self, showCaptured):
+        if self.showCaptured != showCaptured:
+            self.showCaptured = showCaptured
+            self.redrawStatic = True
+            self.reshape(self.viewportWidth, self.viewportHeight)
+            self.feedback.onRedraw()
+
     def showBoardNumbering(self, showNumbering):
         """Extends glchess.scene.Scene"""
         self.showNumbering = showNumbering
@@ -292,7 +336,8 @@ class Scene(glchess.scene.Scene):
         """
         self.viewportWidth = int(width)
         self.viewportHeight = int(height)
-        self.viewportAspect = float(self.viewportWidth) / float(self.viewportHeight)
+        if self.viewportWidth and self.viewportHeight:
+            self.viewportAspect = float(self.viewportWidth) / float(self.viewportHeight)
         glViewport(0, 0, self.viewportWidth, self.viewportHeight)
         self.feedback.onRedraw()
 
@@ -450,16 +495,6 @@ class Scene(glchess.scene.Scene):
         return rank + file
 
     # Private methods
-    
-    def _coordToLocation(self, coord):
-        """
-        """
-        rank = ord(coord[0]) - ord('a')
-        file = ord(coord[1]) - ord('1')
-        x = BOARD_BORDER + float(rank) * SQUARE_WIDTH + 0.5 * SQUARE_WIDTH
-        z = -(BOARD_BORDER + float(file) * SQUARE_WIDTH + 0.5 * SQUARE_WIDTH)
-        
-        return (x, 0.0, z)
         
     def animateThrobber(self, timeStep):
         """
@@ -877,7 +912,7 @@ class Scene(glchess.scene.Scene):
         """Draw the pieces in the scene"""
         glEnable(GL_TEXTURE_2D)
 
-        for piece in self.pieces:
+        for piece in (self.pieces + self.capturedPieces if self.showCaptured else self.pieces):
             glPushMatrix()
             glTranslatef(piece.pos[0], piece.pos[1], piece.pos[2])
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]