home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / python-support / gnome-games-data / glchess / cecp.py < prev    next >
Encoding:
Python Source  |  2009-04-14  |  6.6 KB  |  243 lines

  1. # -*- coding: utf-8 -*-
  2. __author__ = 'Robert Ancell <bob27@users.sourceforge.net>'
  3. __license__ = 'GNU General Public License Version 2'
  4. __copyright__ = 'Copyright 2005-2006  Robert Ancell'
  5.  
  6. class CECPProtocol:
  7.     """CECP protocol en/decoder.
  8.     
  9.     
  10.     """
  11.     
  12.     # Data being accumulated to be parsed
  13.     __buffer = ''
  14.     
  15.     NEWLINE             = '\n'
  16.     MOVE_PREFIXS        = ['My move is: ', 'my move is ', 'move ']
  17.     INVALID_MOVE_PREFIX = 'Illegal move: '
  18.     RESIGN_PREFIX       = 'tellics resign'
  19.     DRAW_PREFIX         = '1/2-1/2'
  20.     
  21.     def __init__(self):
  22.         """
  23.         """
  24.         # Go to simple interface mode
  25.         self.onOutgoingData('xboard\n')
  26.         
  27.     # Methods to extend
  28.     
  29.     def onOutgoingData(self, data):
  30.         """Called when there is data to send to the CECP engine.
  31.         
  32.         'data' is the data to give to the AI (string).
  33.         """
  34.         print 'OUT: ' + repr(data)
  35.     
  36.     def onUnknownLine(self, line):
  37.         """Called when an unknown line is received from the CECP AI.
  38.         
  39.         'line' is the line that has not been decoded (string). There is
  40.                no newline on the end of the string.
  41.         """
  42.         print 'Unknown CECP line: ' + line
  43.     
  44.     def onMove(self, move):
  45.         """Called when the AI makes a move.
  46.         
  47.         'move' is the move the AI has decided to make (string).
  48.         """
  49.         print 'CECP move: ' + move
  50.     
  51.     def onIllegalMove(self, move):
  52.         """Called when the AI rejects a move.
  53.         
  54.         'move' is the move the AI rejected (string).
  55.         """
  56.         print 'CECP illegal move: ' + move
  57.         
  58.     def onResign(self):
  59.         """Called when the AI resigns"""
  60.         print 'CECP AI resigns'
  61.         
  62.     def logText(self, text, style):
  63.         print 'LOG: %s' % text
  64.         
  65.     # Public methods
  66.     
  67.     def sendSetSearchDepth(self, searchDepth):
  68.         """Set the search depth for the AI.
  69.         
  70.         'searchDepth' is the number of moves to look ahead (integer).
  71.         """
  72.         # This is the CECP specified method
  73.         self.onOutgoingData('sd %i\n' % int(searchDepth))
  74.         
  75.         # GNUchess uses this instead
  76.         self.onOutgoingData('depth %i\n' % int(searchDepth))
  77.         
  78.     def sendSetPondering(self, aiPonders):
  79.         """Enable/disable AI pondering.
  80.         
  81.         'aiPonders' is a flag to show if the AI thinks during opponent moves (True) or not (False).
  82.         """
  83.         if aiPonders:
  84.             self.onOutgoingData('hard\n')
  85.         else:
  86.             self.onOutgoingData('easy\n')
  87.     
  88.     def sendMove(self, move):
  89.         """Move for the current player.
  90.         
  91.         'move' is the move the current player has made (string).
  92.         """
  93.         self.onOutgoingData(move + '\n')
  94.         
  95.     def sendWait(self):
  96.         """Stop the AI from automatically moving"""
  97.         self.onOutgoingData('force\n')
  98.         
  99.     def sendUndo(self):
  100.         """Undo the last move"""
  101.         self.onOutgoingData('undo\n')
  102.         
  103.     def sendMovePrompt(self):
  104.         """Get the AI to move for the current player"""
  105.         self.onOutgoingData('go\n')
  106.         
  107.     def sendConventionalClock(self, moveCount, base, increment):
  108.         """
  109.         
  110.         'moveCount' ???
  111.         'base' ??? (seconds)
  112.         'increment' ??? (seconds)
  113.         """
  114.         self.onOutgoingData('level %d %d:%02d %d:%02d\n' % (moveCount, base / 60, base % 60, increment / 60, increment % 60))
  115.  
  116.     def sendQuit(self):
  117.         """Quit the engine"""
  118.         # Send 'quit' starting with a newline in case there are some characters already sent
  119.         self.onOutgoingData('\nquit\n')
  120.     
  121.     def registerIncomingData(self, data):
  122.         """
  123.         """
  124.         self.__buffer += data
  125.         self.__parseData()
  126.         
  127.     # Private methods
  128.         
  129.     def __parseData(self):
  130.         while True:
  131.             index = self.__buffer.find(self.NEWLINE)
  132.             if index < 0:
  133.                 return
  134.             
  135.             line = self.__buffer[:index]
  136.             self.__buffer = self.__buffer[index+1:]
  137.  
  138.             self.__parseLine(line)
  139.     
  140.     def __parseLine(self, line):
  141.         for prefix in self.MOVE_PREFIXS:
  142.             if line.startswith(prefix):
  143.                 move = line[len(prefix):]
  144.                 self.logText(line + '\n', 'move')
  145.                 self.onMove(move.strip())
  146.                 return
  147.             
  148.         if line.startswith(self.INVALID_MOVE_PREFIX):
  149.             self.onIllegalMove(line[len(self.INVALID_MOVE_PREFIX):])
  150.     
  151.         elif line.startswith(self.RESIGN_PREFIX):
  152.             self.onResign()
  153.             
  154.         elif line.startswith(self.DRAW_PREFIX):
  155.             print 'AI calls a draw'
  156.  
  157.         else:
  158.             self.onUnknownLine(line)
  159.             
  160.         self.logText(line + '\n', 'input')
  161.  
  162. class Connection(CECPProtocol):
  163.     """
  164.     """
  165.     
  166.     def __init__(self):
  167.         """
  168.         """
  169.         # Start protocol
  170.         CECPProtocol.__init__(self)
  171.         
  172.     # Methods to extend
  173.     
  174.     def logText(self, text, style):
  175.         """FIXME: define style
  176.         """
  177.         pass
  178.     
  179.     def onMove(self, move):
  180.         """Called when the AI makes a move.
  181.         
  182.         'move' is the move the AI made (string).
  183.         """
  184.         print 'AI moves: ' + move
  185.  
  186.     # Public methods
  187.     
  188.     def start(self):
  189.         """
  190.         """
  191.         pass
  192.     
  193.     def startGame(self):
  194.         """
  195.         """
  196.         pass
  197.     
  198.     def configure(self, options = []):
  199.         """
  200.         """
  201.         for option in options:
  202.             self.onOutgoingData(option.value + '\n')
  203.  
  204.     def requestMove(self, whiteTime, blackTime, ownTime):
  205.         """Request the AI moves for the current player"""
  206.         # Set the clock
  207.         if ownTime > 0:
  208.             self.sendConventionalClock(0, ownTime / 1000, 0)
  209.         
  210.         # Prompt the AI to move
  211.         self.sendMovePrompt()
  212.         
  213.     def undoMove(self):
  214.         """Undo the last move made by this AI"""
  215.         self.sendWait()
  216.         self.sendUndo()
  217.  
  218.     def reportMove(self, move, isSelf):
  219.         """Report the move the current player has made.
  220.         
  221.         'move' is the move to report (string).
  222.         'isSelf' is a flag to say if the move is the move this AI made (True).
  223.         """
  224.         # Don't report the move we made
  225.         if isSelf:
  226.             return
  227.         
  228.         # Stop the AI from automatically moving
  229.         self.sendWait()
  230.  
  231.         # Report the move
  232.         self.sendMove(move)
  233.  
  234.     # Private methods
  235.  
  236.     def onUnknownLine(self, line):
  237.         """Called by CECPProtocol"""
  238.         pass#print 'Unknown CECP line: ' + line
  239.  
  240.     def onIllegalMove(self, move):
  241.         """Called by CECPProtocol"""
  242.         print 'CECP illegal move: ' + move
  243.