def pgn(self): try: mlist = sf.get_san_moves(self.variant, self.initial_fen, self.board.move_stack, self.chess960, sf.NOTATION_SAN) except Exception: log.exception("ERROR: Exception in game %s pgn()" % self.id) mlist = self.board.move_stack moves = " ".join( (move if ind % 2 == 1 else "%s. %s" % (((ind + 1) // 2) + 1, move) for ind, move in enumerate(mlist))) no_setup = self.initial_fen == self.board.start_fen( "chess") and not self.chess960 # Use lichess format for crazyhouse games to support easy import setup_fen = self.initial_fen if self.variant != "crazyhouse" else self.initial_fen.replace( "[]", "") return '[Event "{}"]\n[Site "{}"]\n[Date "{}"]\n[Round "-"]\n[White "{}"]\n[Black "{}"]\n[Result "{}"]\n[TimeControl "{}+{}"]\n[WhiteElo "{}"]\n[BlackElo "{}"]\n[Variant "{}"]\n{fen}{setup}\n{} {}\n'.format( "PyChess " + ("rated" if self.rated else "casual") + " game", URI + "/" + self.id, self.date.strftime("%Y.%m.%d"), self.wplayer.username, self.bplayer.username, self.result, self.base * 60, self.inc, self.wrating, self.brating, self.variant.capitalize() if not self.chess960 else VARIANT_960_TO_PGN[self.variant], moves, self.result, fen="" if no_setup else '[FEN "%s"]\n' % setup_fen, setup="" if no_setup else '[SetUp "1"]\n')
def pgn(doc): variant = C2V[doc["v"]] mlist = decode_moves(doc["m"], variant) chess960 = bool(int(doc.get("z"))) if "z" in doc else False if variant == "xiangqi" or variant == "grand" or variant == "grandhouse" or variant == "shako" or variant == "janggi": mlist = list(map(zero2grand, mlist)) fen = doc["if"] if "if" in doc else sf.start_fen(variant) mlist = sf.get_san_moves(variant, fen, mlist, chess960) moves = " ".join( (move if ind % 2 == 1 else "%s. %s" % (((ind + 1) // 2) + 1, move) for ind, move in enumerate(mlist))) no_setup = fen == STANDARD_FEN and not chess960 # Use lichess format for crazyhouse games to support easy import setup_fen = fen if variant != "crazyhouse" else fen.replace("[]", "") return '[Event "{}"]\n[Site "{}"]\n[Date "{}"]\n[Round "-"]\n[White "{}"]\n[Black "{}"]\n[Result "{}"]\n[TimeControl "{}+{}"]\n[WhiteElo "{}"]\n[BlackElo "{}"]\n[Variant "{}"]\n{fen}{setup}\n{} {}\n'.format( "PyChess " + ("rated" if "y" in doc and doc["y"] == 1 else "casual") + " game", URI + "/" + doc["_id"], doc["d"].strftime("%Y.%m.%d"), doc["us"][0], doc["us"][1], C2R[doc["r"]], doc["b"] * 60, doc["i"], doc["p0"]["e"] if "p0" in doc else "?", doc["p1"]["e"] if "p1" in doc else "?", variant.capitalize() if not chess960 else VARIANT_960_TO_PGN[variant], moves, C2R[doc["r"]], fen="" if no_setup else '[FEN "%s"]\n' % setup_fen, setup="" if no_setup else '[SetUp "1"]\n')
def pgn(doc): variant = C2V[doc["v"]] mlist = decode_moves(doc["m"], variant) chess960 = bool(int(doc.get("z"))) if "z" in doc else False if variant[-5:] == "shogi": mlist = list(map(uci2usi, mlist)) elif variant == "xiangqi" or variant == "grand" or variant == "grandhouse" or variant == "shako": mlist = list(map(zero2grand, mlist)) fen = doc[ "if"] if "if" in doc else SHOGI_FEN if variant == "shogi" else MINISHOGI_FEN if variant == "minishogi" else KYOTOSHOGI_FEN if variant == "kyotoshogi" else sf.start_fen( variant) mlist = sf.get_san_moves(variant, fen, mlist, chess960) moves = " ".join( (move if ind % 2 == 1 else "%s. %s" % (((ind + 1) // 2) + 1, move) for ind, move in enumerate(mlist))) no_setup = fen == STANDARD_FEN and not chess960 return '[Event "{}"]\n[Site "{}"]\n[Date "{}"]\n[Round "-"]\n[White "{}"]\n[Black "{}"]\n[Result "{}"]\n[TimeControl "{}+{}"]\n[WhiteElo "{}"]\n[BlackElo "{}"]\n[Variant "{}"]\n{fen}{setup}\n{} {}\n'.format( "PyChess " + ("rated" if doc["y"] == 1 else "casual") + " game", URI + "/" + doc["_id"], doc["d"].strftime("%Y.%m.%d"), doc["us"][0], doc["us"][1], C2R[doc["r"]], doc["b"] * 60, doc["i"], doc["p0"]["e"], doc["p1"]["e"], variant.capitalize() if not chess960 else VARIANT_960_TO_PGN[variant], moves, C2R[doc["r"]], fen="" if no_setup else '[FEN "%s"]\n' % fen, setup="" if no_setup else '[SetUp "1"]\n')
def test_get_san_moves(self): UCI_moves = ["e2e4", "e7e5", "g1f3", "b8c6h", "f1c4", "f8c5e"] SAN_moves = ["e4", "e5", "Nf3", "Nc6/H", "Bc4", "Bc5/E"] result = sf.get_san_moves("seirawan", SEIRAWAN, UCI_moves) self.assertEqual(result, SAN_moves) UCI_moves = ["c3c4", "g7g6", "b2h8"] SAN_moves = ["P-7f", "P-3d", "Bx2b="] result = sf.get_san_moves("shogi", SHOGI, UCI_moves) self.assertEqual(result, SAN_moves) UCI_moves = ["h3e3", "h10g8", "h1g3", "c10e8", "a1a3", "i10h10"] SAN_moves = ["C2=5", "H8+7", "H2+3", "E3+5", "R9+2", "R9=8"] result = sf.get_san_moves("xiangqi", XIANGQI, UCI_moves, False, sf.NOTATION_XIANGQI_WXF) self.assertEqual(result, SAN_moves)
def pgn(doc): variant = C2V[doc["v"]] mlist = decode_moves(doc["m"], variant) if len(mlist) == 0: return None chess960 = bool(int(doc.get("z"))) if "z" in doc else False initial_fen = doc.get("if") usi_format = variant.endswith("shogi") and doc.get("uci") is None if usi_format: # wplayer, bplayer = bplayer, wplayer if initial_fen: # print("load_game() USI SFEN was:", initial_fen) parts = initial_fen.split() if len(parts) > 3 and parts[1] in "wb": pockets = "[%s]" % parts[2] if parts[2] not in "-0" else "" initial_fen = parts[0] + pockets + ( " w" if parts[1] == "b" else " b") + " 0 " + parts[3] else: initial_fen = parts[0] + (" w" if parts[1] == "b" else " b") + " 0" # print(" changed to:", initial_fen) if usi_format and variant == "shogi": mirror = mirror9 mlist = list(map(mirror, mlist)) elif usi_format and (variant == "minishogi" or variant == "kyotoshogi"): mirror = mirror5 mlist = list(map(mirror, mlist)) elif variant == "xiangqi" or variant == "grand" or variant == "grandhouse" or variant == "shako" or variant == "janggi": mlist = list(map(zero2grand, mlist)) fen = initial_fen if initial_fen is not None else sf.start_fen(variant) # print(variant, fen, mlist) try: mlist = sf.get_san_moves(variant, fen, mlist, chess960) except Exception: try: mlist = sf.get_san_moves(variant, fen, mlist[:-1], chess960) except Exception: log.error("Movelist contains invalid move %s" % mlist) mlist = mlist[0] moves = " ".join( (move if ind % 2 == 1 else "%s. %s" % (((ind + 1) // 2) + 1, move) for ind, move in enumerate(mlist))) no_setup = fen == STANDARD_FEN and not chess960 # Use lichess format for crazyhouse games to support easy import setup_fen = fen if variant != "crazyhouse" else fen.replace("[]", "") return '[Event "{}"]\n[Site "{}"]\n[Date "{}"]\n[Round "-"]\n[White "{}"]\n[Black "{}"]\n[Result "{}"]\n[TimeControl "{}+{}"]\n[WhiteElo "{}"]\n[BlackElo "{}"]\n[Variant "{}"]\n{fen}{setup}\n{} {}\n'.format( "PyChess " + ("rated" if "y" in doc and doc["y"] == 1 else "casual") + " game", URI + "/" + doc["_id"], doc["d"].strftime("%Y.%m.%d"), doc["us"][0], doc["us"][1], C2R[doc["r"]], doc["b"] * 60, doc["i"], doc["p0"]["e"] if "p0" in doc else "?", doc["p1"]["e"] if "p1" in doc else "?", variant.capitalize() if not chess960 else VARIANT_960_TO_PGN[variant], moves, C2R[doc["r"]], fen="" if no_setup else '[FEN "%s"]\n' % setup_fen, setup="" if no_setup else '[SetUp "1"]\n')