Viewing file: lan.py (5.67 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
# -*- coding: utf-8 -*- """ """
__author__ = 'Robert Ancell <bob27@users.sourceforge.net>' __license__ = 'GNU General Public License Version 2' __copyright__ = 'Copyright 2005-2006 Robert Ancell'
import board
CHECK = '+' CHECKMATE = '#'
# Notation for takes MOVE = '-' TAKE = 'x'
# Castling moves CASTLE_SHORT = 'o-o' CASTLE_LONG = 'o-o-o'
# Characters used to describe pieces _typeToLAN = {board.PAWN: 'P', board.KNIGHT: 'N', board.BISHOP: 'B', board.ROOK: 'R', board.QUEEN: 'Q', board.KING: 'K'} _lanToType = {} for (pieceType, character) in _typeToLAN.iteritems(): _lanToType[character] = pieceType _lanToType[character.lower()] = pieceType # English pieces are sometimes written in lowercase
class DecodeError(Exception): """ """ pass def _checkLocation(location): """ """ if len(location) != 2: raise DecodeError('Invalid length location') if location[0] < 'a' or location[0] > 'h': raise DecodeError('Invalid rank') if location[1] < '0' or location[1] > '8': raise DecodeError('Invalid file') return location
def decode(colour, move): """Decode a long algebraic format move. 'colour' is the colour of the player making the move (board.WHITE or board.BLACK). 'move' is the move description (string).
Returns a tuple containing (start, end, piece, moveType, promotionType, result) 'start' is the location being moved from (string, e.g. 'a1', 'h8'). 'end' is the location being moved to (string, e.g. 'a1', 'h8'). 'piece' is the piece being moved (board.PAWN, board.ROOK, ... or None if not specified). 'moveType' is a flag to show if this move takes an oppoenent piece (MOVE, TAKE or None if not specified). 'promotionType' is the piece type to promote to (board.ROOK, board.KNIGHT, ... or None if not specified). 'check' is the result after the move (CHECK, CHECKMATE or None if not specified). Raises DecodeError if the move is unable to be decoded. """ pieceType = None promotionType = None moveType = None result = None m = move if colour is board.WHITE: baseFile = '1' else: baseFile = '8' if m == CASTLE_SHORT: return ('e' + baseFile, 'g' + baseFile, None, None, None, None) elif m == CASTLE_LONG: return ('e' + baseFile, 'c' + baseFile, None, None, None, None)
# First character can be the piece types if len(m) < 1: raise DecodeError('Too short') try: pieceType = _lanToType[m[0]] except KeyError: pieceType = None else: m = m[1:]
if len(m) < 2: raise DecodeError('Too short') try: start = _checkLocation(m[:2]) except DecodeError, e: if pieceType is None: raise e # Perhaps the first character wasn't a piece type m = move start = _checkLocation(m[:2]) pieceType = None m = m[2:] if len(m) < 1: raise DecodeError('Too short') if m[0] == MOVE or m[0] == TAKE: moveType = m[0] m = m[1:]
if len(m) < 2: raise DecodeError('Too short') end = _checkLocation(m[:2]) m = m[2:]
# Look for promotion type, note this can be in upper or lower case if len(m) > 0: if m[0] == '=': if len(m) < 2: raise DecodeError('Too short') try: promotionType = _lanToType[m[1]] except KeyError: raise DecodeError('Unknown promotion type') m = m[2:] else: try: promotionType = _lanToType[m[0]] except KeyError: pass else: m = m[1:]
if len(m) == 1: if m == CHECK or m == CHECKMATE: result = m m = '' elif len(m) == 2: if m == '++': result = CHECKMATE m = ''
if len(m) != 0: raise DecodeError('Extra characters') return (start, end, pieceType, moveType, promotionType, result)
def encode(colour, start, end, piece = None, moveType = None, promotionType = None, result = None): """Encode a long algebraic format move. 'start' is the location being moved from (string, e.g. 'a1', 'h8'). 'end' is the location being moved to (string, e.g. 'a1', 'h8'). 'piece' is the piece being moved (board.PAWN, board.ROOK, ... or None if not specified). 'moveType' is a flag to show if this move takes an oppoenent piece (MOVE, TAKE or None if not specified). 'promotionType' is the piece type to promote to (board.ROOK, board.KNIGHT, ... or None if not specified). 'check' is the result after the move (CHECK, CHECKMATE or None if not specified). Returns a string describing this move. """ try: _checkLocation(start) _checkLocation(end) except DecodeError: raise TypeError("Invalid values for 'start' and 'end'") string = '' # Report the piece being moved if piece is not None: string += _typeToLAN[piece] # Report the source location string += start # Report if this is a move or a take if moveType != None: string += moveType
# Report the target location string += end # Report the promotion type # FIXME: Only report if a pawn promotion if promotionType != None: if False: # FIXME: What to name this flag? string += '=' string += _typeToLAN[promotionType].lower()
# Report the check result if result is not None: string += result
return string
|