home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / var / lib / python-support / python2.6 / glchess / game.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-04-20  |  25.0 KB  |  807 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. '''
  5. '''
  6. __author__ = 'Robert Ancell <bob27@users.sourceforge.net>'
  7. __license__ = 'GNU General Public License Version 2'
  8. __copyright__ = 'Copyright 2005-2006  Robert Ancell'
  9. import chess.board as chess
  10. import chess.san as chess
  11. RESULT_IN_PROGRESS = '*'
  12. RESULT_WHITE_WINS = '1-0'
  13. RESULT_BLACK_WINS = '0-1'
  14. RESULT_DRAW = '1/2-1/2'
  15. RULE_CHECKMATE = 'CHECKMATE'
  16. RULE_STALEMATE = 'STALEMATE'
  17. RULE_TIMEOUT = 'TIMEOUT'
  18. RULE_FIFTY_MOVES = 'FIFTY_MOVES'
  19. RULE_THREE_FOLD_REPETITION = 'THREE_FOLD_REPETITION'
  20. RULE_INSUFFICIENT_MATERIAL = 'INSUFFICIENT_MATERIAL'
  21. RULE_RESIGN = 'RESIGN'
  22. RULE_DEATH = 'DEATH'
  23. RULE_AGREEMENT = 'AGREEMENT'
  24. RULE_ABANDONMENT = 'ABANDONMENT'
  25.  
  26. class ChessMove:
  27.     '''
  28.     '''
  29.     number = 0
  30.     player = None
  31.     piece = None
  32.     promotion = None
  33.     victim = None
  34.     start = None
  35.     end = None
  36.     canMove = ''
  37.     sanMove = ''
  38.     opponentInCheck = False
  39.     opponentCanMove = False
  40.     fiftyMoveRule = False
  41.     threeFoldRepetition = False
  42.     comment = ''
  43.     nag = ''
  44.  
  45.  
  46. class ChessPlayer:
  47.     '''
  48.     '''
  49.     __name = None
  50.     __game = None
  51.     __readyToMove = False
  52.     
  53.     def __init__(self, name):
  54.         """Constructor for a chess player.
  55.  
  56.         'name' is the name of the player.
  57.         """
  58.         self._ChessPlayer__name = str(name)
  59.         self.isAlive = True
  60.  
  61.     
  62.     def onPieceMoved(self, piece, start, end, delete):
  63.         """Called when a chess piece is moved.
  64.         
  65.         'piece' is the piece that has been moved (chess.board.ChessPiece).
  66.         'start' is the location the piece in LAN format (string) or None if the piece has been created.
  67.         'end' is the location the piece has moved to in LAN format (string).
  68.         'delete' is a flag to show if the piece should be deleted when it arrives there (boolean).
  69.         """
  70.         pass
  71.  
  72.     
  73.     def onPlayerMoved(self, player, move):
  74.         """Called when a player has moved.
  75.         
  76.         'player' is the player that has moved (ChessPlayer).
  77.         'move' is the record for this move (ChessMove).
  78.         """
  79.         pass
  80.  
  81.     
  82.     def onUndoMove(self):
  83.         pass
  84.  
  85.     
  86.     def onPlayerStartTurn(self, player):
  87.         pass
  88.  
  89.     
  90.     def onGameEnded(self, game):
  91.         """Called when a chess game has ended.
  92.         
  93.         'game' is the game that has ended (Game).
  94.         """
  95.         pass
  96.  
  97.     
  98.     def readyToMove(self):
  99.         '''FIXME
  100.         '''
  101.         pass
  102.  
  103.     
  104.     def getName(self):
  105.         '''Get the name of this player.
  106.         
  107.         Returns the player name (string).
  108.         '''
  109.         return self._ChessPlayer__name
  110.  
  111.     
  112.     def getGame(self):
  113.         '''Get the game this player is in.
  114.         
  115.         Returns the game (Game) or None if not in a game.
  116.         '''
  117.         return self._ChessPlayer__game
  118.  
  119.     
  120.     def getRemainingTime(self):
  121.         '''Get the amount of time this player has remaining.
  122.         
  123.         Returns the amount of time in milliseconds.
  124.         '''
  125.         if self is self._ChessPlayer__game.getWhite():
  126.             timer = self._ChessPlayer__game.whiteTimer
  127.         elif self is self._ChessPlayer__game.getBlack():
  128.             timer = self._ChessPlayer__game.blackTimer
  129.         else:
  130.             return 0
  131.         if self is self._ChessPlayer__game.getWhite() is None:
  132.             return 0
  133.         return timer.controller.getRemaining()
  134.  
  135.     
  136.     def isReadyToMove(self):
  137.         '''
  138.         '''
  139.         return self._ChessPlayer__readyToMove
  140.  
  141.     
  142.     def canMove(self, start, end, promotionType = chess.board.QUEEN):
  143.         '''
  144.         '''
  145.         return self._ChessPlayer__game.canMove(self, start, end, promotionType)
  146.  
  147.     
  148.     def move(self, move):
  149.         """Move a piece.
  150.         
  151.         'move' is the move to make in Normal/Long/Standard Algebraic format (string).
  152.         """
  153.         self._ChessPlayer__game.move(self, move)
  154.  
  155.     
  156.     def undo(self):
  157.         '''Undo moves until it is this players turn'''
  158.         self._ChessPlayer__game.undo(self)
  159.  
  160.     
  161.     def endMove(self):
  162.         '''Complete this players turn'''
  163.         self._ChessPlayer__game.endMove(self)
  164.  
  165.     
  166.     def resign(self):
  167.         '''Resign from the game'''
  168.         self._ChessPlayer__game.resign(self)
  169.  
  170.     
  171.     def claimDraw(self):
  172.         '''Claim a draw'''
  173.         return self._ChessPlayer__game.claimDraw()
  174.  
  175.     
  176.     def outOfTime(self):
  177.         '''Report this players timer has expired'''
  178.         self._ChessPlayer__game.outOfTime(self)
  179.  
  180.     
  181.     def die(self):
  182.         '''Report this player has died'''
  183.         self.isAlive = False
  184.         if self._ChessPlayer__game is not None:
  185.             self._ChessPlayer__game.killPlayer(self)
  186.         
  187.  
  188.     
  189.     def _setGame(self, game):
  190.         '''
  191.         '''
  192.         self._ChessPlayer__game = game
  193.  
  194.     
  195.     def _setReadyToMove(self, readyToMove):
  196.         if self._ChessPlayer__readyToMove == readyToMove:
  197.             return None
  198.         self._ChessPlayer__readyToMove = readyToMove
  199.         if readyToMove is True:
  200.             self.readyToMove()
  201.         
  202.  
  203.  
  204.  
  205. class ChessGameBoard(chess.board.ChessBoard):
  206.     '''
  207.     '''
  208.     __game = None
  209.     
  210.     def __init__(self, game):
  211.         '''
  212.         '''
  213.         self._ChessGameBoard__game = game
  214.         chess.board.ChessBoard.__init__(self)
  215.  
  216.     
  217.     def onPieceMoved(self, piece, start, end, delete):
  218.         '''Called by chess.board.ChessBoard'''
  219.         self._ChessGameBoard__game._onPieceMoved(piece, start, end, delete)
  220.  
  221.  
  222.  
  223. class ChessGameSANConverter(chess.san.SANConverter):
  224.     '''
  225.     '''
  226.     __colourToSAN = {
  227.         chess.board.WHITE: chess.san.SANConverter.WHITE,
  228.         chess.board.BLACK: chess.san.SANConverter.BLACK }
  229.     __sanToColour = { }
  230.     for a, b in __colourToSAN.iteritems():
  231.         __sanToColour[b] = a
  232.     
  233.     __typeToSAN = {
  234.         chess.board.PAWN: chess.san.SANConverter.PAWN,
  235.         chess.board.KNIGHT: chess.san.SANConverter.KNIGHT,
  236.         chess.board.BISHOP: chess.san.SANConverter.BISHOP,
  237.         chess.board.ROOK: chess.san.SANConverter.ROOK,
  238.         chess.board.QUEEN: chess.san.SANConverter.QUEEN,
  239.         chess.board.KING: chess.san.SANConverter.KING }
  240.     __sanToType = { }
  241.     for a, b in __typeToSAN.iteritems():
  242.         __sanToType[b] = a
  243.     
  244.     
  245.     def __init__(self, board, moveNumber):
  246.         self.board = board
  247.         self.moveNumber = moveNumber
  248.         chess.san.SANConverter.__init__(self)
  249.  
  250.     
  251.     def decode(self, colour, move):
  252.         (start, end, result, promotionType) = chess.san.SANConverter.decode(self, self._ChessGameSANConverter__colourToSAN[colour], move)
  253.         return (start, end, self._ChessGameSANConverter__sanToType[promotionType])
  254.  
  255.     
  256.     def encode(self, start, end, isTake, promotionType):
  257.         if promotionType is None:
  258.             promotion = self.QUEEN
  259.         else:
  260.             promotion = self._ChessGameSANConverter__typeToSAN[promotionType]
  261.         return chess.san.SANConverter.encode(self, start, end, isTake, promotion)
  262.  
  263.     
  264.     def getPiece(self, location):
  265.         '''Called by chess.san.SANConverter'''
  266.         piece = self.board.getPiece(location, self.moveNumber)
  267.         if piece is None:
  268.             return None
  269.         return (self._ChessGameSANConverter__colourToSAN[piece.getColour()], self._ChessGameSANConverter__typeToSAN[piece.getType()])
  270.  
  271.     
  272.     def testMove(self, colour, start, end, promotionType, allowSuicide = False):
  273.         '''Called by chess.san.SANConverter'''
  274.         move = self.board.testMove(self._ChessGameSANConverter__sanToColour[colour], start, end, self._ChessGameSANConverter__sanToType[promotionType], allowSuicide, self.moveNumber)
  275.         if move is None:
  276.             return False
  277.         if move.opponentInCheck:
  278.             if not move.opponentCanMove:
  279.                 return chess.san.SANConverter.CHECKMATE
  280.             return chess.san.SANConverter.CHECK
  281.         return True
  282.  
  283.  
  284.  
  285. class ChessGame:
  286.     '''
  287.     '''
  288.     __players = None
  289.     __whitePlayer = None
  290.     __blackPlayer = None
  291.     __spectators = None
  292.     board = None
  293.     __started = False
  294.     __currentPlayer = None
  295.     __moves = None
  296.     __inCallback = False
  297.     __queuedCalls = None
  298.     result = RESULT_IN_PROGRESS
  299.     rule = None
  300.     whiteTimer = None
  301.     blackTimer = None
  302.     
  303.     def __init__(self):
  304.         '''Game constructor'''
  305.         self._ChessGame__players = []
  306.         self._ChessGame__spectators = []
  307.         self.board = ChessGameBoard(self)
  308.         self._ChessGame__moves = []
  309.         self._ChessGame__queuedCalls = []
  310.  
  311.     
  312.     def getAlivePieces(self, moveNumber = -1):
  313.         """Get the alive pieces on the board.
  314.         
  315.         'moveNumber' is the move to get the pieces from (integer).
  316.         
  317.         Returns a dictionary of the alive pieces (board.ChessPiece) keyed by location.
  318.         Raises an IndexError exception if moveNumber is invalid.
  319.         """
  320.         return self.board.getAlivePieces(moveNumber)
  321.  
  322.     
  323.     def getDeadPieces(self, moveNumber = -1):
  324.         """Get the dead pieces from the game.
  325.         
  326.         'moveNumber' is the move to get the pieces from (integer).
  327.         
  328.         Returns a list of the pieces (board.ChessPiece) in the order they were killed.
  329.         Raises an IndexError exception if moveNumber is invalid.
  330.         """
  331.         return self.board.getDeadPieces(moveNumber)
  332.  
  333.     
  334.     def setTimers(self, whiteTimer, blackTimer):
  335.         '''
  336.         '''
  337.         self.whiteTimer = whiteTimer
  338.         self.blackTimer = blackTimer
  339.  
  340.     
  341.     def setWhite(self, player):
  342.         """Set the white player in the game.
  343.         
  344.         'player' is the player to use as white.
  345.         
  346.         If the game has started or there is a white player an exception is thrown.
  347.         """
  348.         if not self._ChessGame__started is False:
  349.             raise AssertionError
  350.         if not self._ChessGame__whitePlayer is None:
  351.             raise AssertionError
  352.         self._ChessGame__whitePlayer = player
  353.         self._ChessGame__connectPlayer(player)
  354.  
  355.     
  356.     def getWhite(self):
  357.         '''Returns the current white player (player.Player)'''
  358.         return self._ChessGame__whitePlayer
  359.  
  360.     
  361.     def setBlack(self, player):
  362.         """Set the black player in the game.
  363.         
  364.         'player' is the player to use as black.
  365.         
  366.         If the game has started or there is a black player an exception is thrown.
  367.         """
  368.         if not self._ChessGame__started is False:
  369.             raise AssertionError
  370.         if not self._ChessGame__blackPlayer is None:
  371.             raise AssertionError
  372.         self._ChessGame__blackPlayer = player
  373.         self._ChessGame__connectPlayer(player)
  374.  
  375.     
  376.     def getBlack(self):
  377.         '''Returns the current white player (player.Player)'''
  378.         return self._ChessGame__blackPlayer
  379.  
  380.     
  381.     def getCurrentPlayer(self):
  382.         '''Get the player to move'''
  383.         return self._ChessGame__currentPlayer
  384.  
  385.     
  386.     def addSpectator(self, player):
  387.         """Add a spectator to the game.
  388.         
  389.         'player' is the player spectating.
  390.         
  391.         This can be called after the game has started.
  392.         """
  393.         self._ChessGame__spectators.append(player)
  394.         self._ChessGame__connectPlayer(player)
  395.  
  396.     
  397.     def isStarted(self):
  398.         '''Returns True if the game has been started'''
  399.         return self._ChessGame__started
  400.  
  401.     
  402.     def start(self, moves = []):
  403.         """Start the game.
  404.         
  405.         'moves' is a list of moves to start with.
  406.         
  407.         If there is no white or black player then an exception is raised.
  408.         """
  409.         if not self._ChessGame__whitePlayer is not None or self._ChessGame__blackPlayer is not None:
  410.             raise AssertionError
  411.         self._ChessGame__currentPlayer = self._ChessGame__whitePlayer
  412.         for move in moves:
  413.             self.move(self._ChessGame__currentPlayer, move)
  414.             if self._ChessGame__currentPlayer is self._ChessGame__whitePlayer:
  415.                 self._ChessGame__currentPlayer = self._ChessGame__blackPlayer
  416.                 continue
  417.             self._ChessGame__blackPlayer is not None
  418.             self._ChessGame__currentPlayer = self._ChessGame__whitePlayer
  419.         
  420.         self._ChessGame__started = True
  421.         if not self._ChessGame__whitePlayer.isAlive:
  422.             self.killPlayer(self._ChessGame__whitePlayer)
  423.             return None
  424.         if not self._ChessGame__blackPlayer.isAlive:
  425.             self.killPlayer(self._ChessGame__blackPlayer)
  426.             return None
  427.         if self.result != RESULT_IN_PROGRESS:
  428.             self._notifyEndGame()
  429.             return None
  430.         self.startLock()
  431.         for player in self._ChessGame__players:
  432.             player.onPlayerStartTurn(self._ChessGame__currentPlayer)
  433.         
  434.         self._ChessGame__currentPlayer._setReadyToMove(True)
  435.         self.endLock()
  436.  
  437.     
  438.     def getSquareOwner(self, coord):
  439.         '''TODO
  440.         '''
  441.         piece = self.board.getPiece(coord)
  442.         if piece is None:
  443.             return None
  444.         colour = piece.getColour()
  445.         if colour is chess.board.WHITE:
  446.             return self._ChessGame__whitePlayer
  447.         if colour is chess.board.BLACK:
  448.             return self._ChessGame__blackPlayer
  449.         return None
  450.  
  451.     
  452.     def canMove(self, player, start, end, promotionType):
  453.         """Test if a player can move.
  454.         
  455.         'player' is the player making the move.
  456.         'start' is the location to move from in LAN format (string).
  457.         'end' is the location to move from in LAN format (string).
  458.         'promotionType' is the piece type to promote pawns to. FIXME: Make this a property of the player
  459.         
  460.         Return True if can move, otherwise False.
  461.         """
  462.         if player is not self._ChessGame__currentPlayer:
  463.             return False
  464.         if player is self._ChessGame__whitePlayer:
  465.             colour = chess.board.WHITE
  466.         elif player is self._ChessGame__blackPlayer:
  467.             colour = chess.board.BLACK
  468.         elif not False:
  469.             raise AssertionError
  470.         move = self.board.testMove(colour, start, end, promotionType = promotionType)
  471.         return move is not None
  472.  
  473.     
  474.     def move(self, player, move):
  475.         """Get a player to make a move.
  476.         
  477.         'player' is the player making the move.
  478.         'move' is the move to make in SAN or LAN format (string).
  479.         """
  480.         if self._ChessGame__inCallback:
  481.             self._ChessGame__queuedCalls.append((self.move, (player, move)))
  482.             return None
  483.         self.startLock()
  484.         self.endLock()
  485.  
  486.     
  487.     def undo(self, player):
  488.         if self._ChessGame__inCallback:
  489.             self._ChessGame__queuedCalls.append((self.undo, (player,)))
  490.             return None
  491.         self.startLock()
  492.         self._ChessGame__whitePlayer._setReadyToMove(False)
  493.         self._ChessGame__blackPlayer._setReadyToMove(False)
  494.         if player is self._ChessGame__whitePlayer:
  495.             self._ChessGame__currentPlayer = self._ChessGame__blackPlayer
  496.         else:
  497.             self._ChessGame__currentPlayer = self._ChessGame__whitePlayer
  498.         if len(self._ChessGame__moves) > 0 and self._ChessGame__moves[-1].player is not player:
  499.             count = 2
  500.         else:
  501.             count = 1
  502.         for i in xrange(count):
  503.             if len(self._ChessGame__moves) != 0:
  504.                 self.board.undo()
  505.                 self._ChessGame__moves = self._ChessGame__moves[:-1]
  506.                 for p in self._ChessGame__players:
  507.                     p.onUndoMove()
  508.                 
  509.         
  510.         self.endLock()
  511.  
  512.     
  513.     def startLock(self):
  514.         if not self._ChessGame__inCallback is False:
  515.             raise AssertionError
  516.         self._ChessGame__inCallback = True
  517.  
  518.     
  519.     def endLock(self):
  520.         self._ChessGame__inCallback = False
  521.         while len(self._ChessGame__queuedCalls) > 0:
  522.             (call, args) = self._ChessGame__queuedCalls[0]
  523.             self._ChessGame__queuedCalls = self._ChessGame__queuedCalls[1:]
  524.             call(*args)
  525.  
  526.     
  527.     def _move(self, player, move):
  528.         '''
  529.         '''
  530.         if self.result != RESULT_IN_PROGRESS:
  531.             print 'Game completed'
  532.             return None
  533.         if self._ChessGame__currentPlayer is self._ChessGame__whitePlayer:
  534.             colour = chess.board.WHITE
  535.         else:
  536.             colour = chess.board.BLACK
  537.         
  538.         try:
  539.             (start, end, _, _, promotionType, _) = chess.lan.decode(colour, move)
  540.         except chess.lan.DecodeError:
  541.             e = None
  542.             converter = ChessGameSANConverter(self.board, len(self._ChessGame__moves))
  543.             
  544.             try:
  545.                 (start, end, promotionType) = converter.decode(colour, move)
  546.             except chess.san.Error:
  547.                 e = None
  548.                 print 'Invalid move: ' + move
  549.                 return None
  550.             
  551.  
  552.             None<EXCEPTION MATCH>chess.san.Error
  553.  
  554.         piece = self.board.getPiece(start)
  555.         promotion = None
  556.         if piece is not None and piece.getType() is chess.board.PAWN:
  557.             if colour is chess.board.WHITE:
  558.                 if end[1] == '8':
  559.                     promotion = promotionType
  560.                 
  561.             elif end[1] == '1':
  562.                 promotion = promotionType
  563.             
  564.         
  565.         moveResult = self.board.movePiece(colour, start, end, promotionType)
  566.         if moveResult is None:
  567.             print 'Illegal move: ' + str(move)
  568.             return None
  569.         canMove = chess.lan.encode(colour, start, end, promotionType = promotion)
  570.         converter = ChessGameSANConverter(self.board, len(self._ChessGame__moves))
  571.         
  572.         try:
  573.             sanMove = converter.encode(start, end, moveResult.victim != None, promotionType)
  574.         except chess.san.Error:
  575.             moveResult is None
  576.             moveResult is None
  577.             sanMove = canMove
  578.         except:
  579.             moveResult is None
  580.  
  581.         m = ChessMove()
  582.         if len(self._ChessGame__moves) == 0:
  583.             m.number = 1
  584.         else:
  585.             m.number = self._ChessGame__moves[-1].number + 1
  586.         m.player = self._ChessGame__currentPlayer
  587.         m.piece = piece
  588.         m.victim = moveResult.victim
  589.         m.start = start
  590.         m.end = end
  591.         m.canMove = canMove
  592.         m.sanMove = sanMove
  593.         m.opponentInCheck = moveResult.opponentInCheck
  594.         m.opponentCanMove = moveResult.opponentCanMove
  595.         m.fiftyMoveRule = moveResult.fiftyMoveRule
  596.         m.threeFoldRepetition = moveResult.threeFoldRepetition
  597.         self._ChessGame__moves.append(m)
  598.         self._ChessGame__currentPlayer._setReadyToMove(False)
  599.         for player in self._ChessGame__players:
  600.             player.onPlayerMoved(self._ChessGame__currentPlayer, m)
  601.         
  602.         result = RESULT_IN_PROGRESS
  603.         if not m.opponentCanMove:
  604.             if self._ChessGame__currentPlayer is self._ChessGame__whitePlayer:
  605.                 result = RESULT_WHITE_WINS
  606.             else:
  607.                 result = RESULT_BLACK_WINS
  608.             if m.opponentInCheck:
  609.                 rule = RULE_CHECKMATE
  610.             else:
  611.                 result = RESULT_DRAW
  612.                 rule = RULE_STALEMATE
  613.         
  614.         if not self.board.sufficientMaterial():
  615.             result = RESULT_DRAW
  616.             rule = RULE_INSUFFICIENT_MATERIAL
  617.         
  618.         if result is not RESULT_IN_PROGRESS:
  619.             self.endGame(result, rule)
  620.         
  621.  
  622.     
  623.     def endMove(self, player):
  624.         '''
  625.         '''
  626.         if self._ChessGame__inCallback:
  627.             self._ChessGame__queuedCalls.append((self.endMove, (player,)))
  628.             return None
  629.         if player is not self._ChessGame__currentPlayer:
  630.             print 'Player attempted to move out of turn'
  631.             return None
  632.         if player.move is None:
  633.             print "Ending move when haven't made one"
  634.             return None
  635.         self.startLock()
  636.         for player in self._ChessGame__players:
  637.             player.onPlayerStartTurn(self._ChessGame__currentPlayer)
  638.         
  639.         if self._ChessGame__started is True and self.result == RESULT_IN_PROGRESS:
  640.             self._ChessGame__currentPlayer._setReadyToMove(True)
  641.         
  642.         self.endLock()
  643.  
  644.     
  645.     def resign(self, player):
  646.         """Get a player to resign.
  647.         
  648.         'player' is the player resigning.
  649.         """
  650.         rule = RULE_RESIGN
  651.         if player is self._ChessGame__whitePlayer:
  652.             self.endGame(RESULT_BLACK_WINS, rule)
  653.         else:
  654.             self.endGame(RESULT_WHITE_WINS, rule)
  655.  
  656.     
  657.     def claimDraw(self):
  658.         '''
  659.         '''
  660.         
  661.         try:
  662.             move = self._ChessGame__moves[-1]
  663.         except IndexError:
  664.             return False
  665.  
  666.         if move.fiftyMoveRule:
  667.             rule = RULE_FIFTY_MOVES
  668.         elif move.threeFoldRepetition:
  669.             rule = RULE_THREE_FOLD_REPETITION
  670.         else:
  671.             return False
  672.         move.fiftyMoveRule.endGame(RESULT_DRAW, rule)
  673.         return True
  674.  
  675.     
  676.     def killPlayer(self, player):
  677.         """Report a player has died
  678.         
  679.         'player' is the player that has died.
  680.         """
  681.         if player is self._ChessGame__whitePlayer:
  682.             result = RESULT_BLACK_WINS
  683.         elif player is self._ChessGame__blackPlayer:
  684.             result = RESULT_WHITE_WINS
  685.         
  686.         self.endGame(result, RULE_DEATH)
  687.  
  688.     
  689.     def outOfTime(self, player):
  690.         """Report a player's timer has expired"""
  691.         if player is self._ChessGame__whitePlayer:
  692.             result = RESULT_BLACK_WINS
  693.         elif player is self._ChessGame__blackPlayer:
  694.             result = RESULT_WHITE_WINS
  695.         elif not False:
  696.             raise AssertionError
  697.         self.endGame(result, RULE_TIMEOUT)
  698.  
  699.     
  700.     def abandon(self):
  701.         self.endGame(RESULT_DRAW, RULE_ABANDONMENT)
  702.  
  703.     
  704.     def endGame(self, result, rule):
  705.         if self.result != RESULT_IN_PROGRESS:
  706.             return None
  707.         self.result = result
  708.         self.rule = rule
  709.         if self.isStarted():
  710.             self._notifyEndGame()
  711.         
  712.  
  713.     
  714.     def _notifyEndGame(self):
  715.         self._ChessGame__currentPlayer._setReadyToMove(False)
  716.         for player in self._ChessGame__players:
  717.             player.onGameEnded(self)
  718.         
  719.  
  720.     
  721.     def getMoves(self):
  722.         '''
  723.         '''
  724.         return self._ChessGame__moves
  725.  
  726.     
  727.     def abort(self):
  728.         '''End the game'''
  729.         for player in self._ChessGame__players:
  730.             player.onGameEnded(self)
  731.         
  732.  
  733.     
  734.     def __connectPlayer(self, player):
  735.         """Add a player into the game.
  736.         
  737.         'player' is the player to add.
  738.         
  739.         The player will be notified of the current state of the board.
  740.         """
  741.         self._ChessGame__players.append(player)
  742.         player._setGame(self)
  743.         for file in '12345678':
  744.             for rank in 'abcdefgh':
  745.                 coord = rank + file
  746.                 piece = self.board.getPiece(coord)
  747.                 if piece is None:
  748.                     continue
  749.                 
  750.                 player.onPieceMoved(piece, None, coord, False)
  751.             
  752.         
  753.  
  754.     
  755.     def _onPieceMoved(self, piece, start, end, delete):
  756.         '''Called by the chess board'''
  757.         for player in self._ChessGame__players:
  758.             player.onPieceMoved(piece, start, end, delete)
  759.         
  760.  
  761.  
  762.  
  763. class NetworkChessGame(ChessGame):
  764.     '''
  765.     '''
  766.     
  767.     def move(self, player, move):
  768.         """Get a player to make a move.
  769.         
  770.         'player' is the player making the move.
  771.         'move' is the move to make. It can be of the form:
  772.                A coordinate move in the form ((file0, rank0), (file1, rank1), promotionType) ((int, int), (int, int), chess.board.PIECE_TYPE) or
  773.                A SAN move (string).
  774.         """
  775.         pass
  776.  
  777.  
  778. if __name__ == '__main__':
  779.     game = ChessGame()
  780.     import pgn
  781.     p = pgn.PGN('black.pgn')
  782.     g = p.getGame(0)
  783.     
  784.     class PGNPlayer(ChessPlayer):
  785.         __moveNumber = 1
  786.         __isWhite = True
  787.         
  788.         def __init__(self, isWhite):
  789.             self._PGNPlayer__isWhite = isWhite
  790.  
  791.         
  792.         def readyToMove(self):
  793.             if self._PGNPlayer__isWhite:
  794.                 move = g.getWhiteMove(self._PGNPlayer__moveNumber)
  795.             else:
  796.                 move = g.getBlackMove(self._PGNPlayer__moveNumber)
  797.             self._PGNPlayer__moveNumber += 1
  798.             self.move(move)
  799.  
  800.  
  801.     white = PGNPlayer(True)
  802.     black = PGNPlayer(False)
  803.     game.setWhite(white)
  804.     game.setBlack(black)
  805.     game.start()
  806.  
  807.