Advertisement
Guest User

Untitled

a guest
May 26th, 2015
289
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.30 KB | None | 0 0
  1. # -*- coding:utf-8 -*-
  2. # Copyright (c) 2011 Renato de Pontes Pereira, renato.ppontes at gmail dot com
  3. #
  4. # Permission is hereby granted, free of charge, to any person obtaining a copy
  5. # of this software and associated documentation files (the "Software"), to deal
  6. # in the Software without restriction, including without limitation the rights
  7. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. # copies of the Software, and to permit persons to whom the Software is
  9. # furnished to do so, subject to the following conditions:
  10. #
  11. # The above copyright notice and this permission notice shall be included in all
  12. # copies or substantial portions of the Software.
  13. #
  14. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  20. # SOFTWARE.
  21.  
  22. import re
  23.  
  24. firstPart=["a","b","c","d"]
  25. secondPart=["e","f","g","h"]
  26.  
  27. '''
  28. A simple PGN parser.
  29.  
  30. PGN (Portable Game Notation) is computer-processible format for recording chess
  31. games, both the moves and related data.
  32.  
  33. This module is based on features of others parser modules (such json and yaml).
  34. The basic usage::
  35.  
  36. import pgn
  37.  
  38. pgn_text = open('morphy.pgn).read()
  39. pgn_game = pgn.PGNGame()
  40.  
  41. print pgn.loads(pgn_text) # Returns a list of PGNGame
  42. print pgn.dumps(pgn_game) # Returns a string with a pgn game
  43.  
  44. '''
  45.  
  46. class PGNGame(object):
  47. '''
  48. Describes a single chess game in PGN format.
  49. '''
  50.  
  51. TAG_ORDER = ['Event', 'Site', 'Date', 'Round', 'White', 'Black', 'Result',
  52. 'Annotator', 'PlyCount', 'TimeControl', 'Time', 'Termination',
  53. 'Mode', 'FEN']
  54.  
  55. def __init__(self, event=None, site=None, date=None, round=None,
  56. white=None,
  57. black=None,
  58. result=None):
  59. '''
  60. Initializes the PGNGame, receiving the requireds tags.
  61. '''
  62. self.event = event
  63. self.site = site
  64. self.date = date
  65. self.round = round
  66. self.white = white
  67. self.black = black
  68. self.result = result
  69. self.annotator = None
  70. self.plycount = None
  71. self.timecontrol = None
  72. self.time = None
  73. self.termination = None
  74. self.mode = None
  75. self.fen = None
  76.  
  77. self.moves = []
  78.  
  79. def dumps(self):
  80. return dumps(self)
  81.  
  82. def __repr__(self):
  83. return '<PGNGame "%s" vs "%s">' % (self.white, self.black)
  84.  
  85. def _pre_process_text(text):
  86. '''
  87. This function is responsible for removal of end line commentarys
  88. (;commentary), blank lines and aditional spaces. Also, it converts
  89. ``\\r\\n`` to ``\\n``.
  90. '''
  91. text = re.sub(r'\s*(\\r)?\\n\s*', '\n', text.strip())
  92. lines = []
  93. for line in text.split('\n'):
  94. line = re.sub(r'(\s*;.*|^\s*)', '', line)
  95. if line:
  96. lines.append(line)
  97.  
  98. return lines
  99.  
  100. def _next_token(lines):
  101. '''
  102. Get the next token from lines (list of text pgn file lines).
  103.  
  104. There is 2 kind of tokens: tags and moves. Tags tokens starts with ``[``
  105. char, e.g. ``[TagName "Tag Value"]``. Moves tags follows the example:
  106. ``1. e4 e5 2. d4``.
  107. '''
  108. if not lines:
  109. return None
  110.  
  111. token = lines.pop(0).strip()
  112. if token.startswith('['):
  113. return token
  114.  
  115. while lines and not lines[0].startswith('['):
  116. token += ' '+lines.pop(0).strip()
  117.  
  118. return token.strip()
  119.  
  120. def _parse_tag(token):
  121. '''
  122. Parse a tag token and returns a tuple with (tagName, tagValue).
  123. '''
  124. tag, value = re.match(r'\[(\w*)\s*(.+)', token).groups()
  125. return tag.lower(), value.strip('"[] ')
  126.  
  127. def _parse_moves(token):
  128. '''
  129. Parse a moves token and returns a list with moviments
  130. '''
  131. moves = []
  132. while token:
  133. token = re.sub(r'^\s*(\d+\.+\s*)?', '', token)
  134.  
  135. if token.startswith('{'):
  136. pos = token.find('}')+1
  137. else:
  138. pos1 = token.find(' ')
  139. pos2 = token.find('{')
  140. if pos1 <= 0:
  141. pos = pos2
  142. elif pos2 <= 0:
  143. pos = pos1
  144. else:
  145. pos = min([pos1, pos2])
  146.  
  147. if pos > 0:
  148. moves.append(token[:pos])
  149. token = token[pos:]
  150. else:
  151. moves.append(token)
  152. token = ''
  153.  
  154. return moves
  155.  
  156. def loads(text):
  157. '''
  158. Converts a string ``text`` into a list of PNGGames
  159. '''
  160. games = []
  161. game = None
  162. lines = _pre_process_text(text)
  163.  
  164. while True:
  165. token = _next_token(lines)
  166.  
  167. if not token:
  168. break
  169.  
  170. if token.startswith('['):
  171. tag, value = _parse_tag(token)
  172. if not game or (game and game.moves):
  173. game = PGNGame()
  174. games.append(game)
  175.  
  176. setattr(game, tag, value)
  177. else:
  178. game.moves = _parse_moves(token)
  179.  
  180. return games
  181.  
  182. def dumps(games):
  183. '''
  184. Serialize a list os PGNGames (or a single game) into text format.
  185. '''
  186. all_dumps = []
  187.  
  188. if not isinstance(games, (list, tuple)):
  189. games = [games]
  190.  
  191. for game in games:
  192. dump = ''
  193. for i, tag in enumerate(PGNGame.TAG_ORDER):
  194. if getattr(game, tag.lower()):
  195. dump += '[%s "%s"]\n' % (tag, getattr(game, tag.lower()))
  196. elif i <= 6:
  197. dump += '[%s "?"]\n' % tag
  198.  
  199.  
  200. dump += '\n'
  201. i = 0
  202. for move in game.moves:
  203. if not move.startswith('{'):
  204. if i%2 == 0:
  205. dump += str(i/2+1)+'. '
  206.  
  207. i += 1
  208.  
  209. dump += move + ' '
  210.  
  211. all_dumps.append(dump.strip())
  212.  
  213. return '\n\n\n'.join(all_dumps)
  214.  
  215. def isAtoEpart(move):
  216. for letter in reversed(move):
  217. if(letter in firstPart):
  218. return True
  219. if(letter in secondPart):
  220. return False
  221.  
  222.  
  223. def translate(move):
  224. if move.startswith("N"):
  225. if(isAtoEpart(move)):
  226. return "4"
  227. else:
  228. return "5"
  229. elif move.startswith("B"):
  230. if(isAtoEpart(move)):
  231. return "6"
  232. else:
  233. return "7"
  234. elif move.startswith("K") or move.startswith("O"):
  235. return "0"
  236. elif move.startswith("R"):
  237. return "1"
  238. elif move.startswith("Q"):
  239. if(isAtoEpart(move)):
  240. return "8"
  241. else:
  242. return "9"
  243. elif move[0] in firstPart:
  244. return "2"
  245. elif move[0] in secondPart:
  246. return "3"
  247.  
  248.  
  249. if __name__=="__main__":
  250. p=PGNGame()
  251. encodedGame=""
  252. with open("kasparov_pribyl_1980.pgn","r") as f:
  253. t=f.readlines()
  254. games=loads("".join(t))
  255. for game in games:
  256. for move in game.moves:
  257. t=translate(move)
  258. if t!=None:
  259. print(move+" translated as "+t)
  260. encodedGame+=t
  261. else:
  262. print(move)
  263. s = " ".join(encodedGame[i:i+2] for i in range(0, len(encodedGame), 2))
  264. print(s)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement