Ejemplo n.º 1
0
def save(handle, model, position=None, flip=False):
    """ Saves the game from GameModel to .pgn """
    processed_tags = []

    def write_tag(tag, value, roster=False):
        nonlocal processed_tags
        if tag in processed_tags or (not roster and not value):
            return
        try:
            pval = str(value)
            pval = pval.replace("\\", "\\\\")
            pval = pval.replace("\"", "\\\"")
            print('[%s "%s"]' % (tag, pval), file=handle)
        except UnicodeEncodeError:
            pval = bytes(pval, "utf-8").decode(PGN_ENCODING, errors="ignore")
            print('[%s "%s"]' % (tag, pval), file=handle)
        processed_tags = processed_tags + [tag]

    # Mandatory ordered seven-tag roster
    status = reprResult[model.status]
    for tag in mandatory_tags:
        value = model.tags[tag]
        if tag == "Date":
            y, m, d = parseDateTag(value)
            y = "%04d" % y if y is not None else "????"
            m = "%02d" % m if m is not None else "??"
            d = "%02d" % d if d is not None else "??"
            value = "%s.%s.%s" % (y, m, d)
        elif value == "":
            value = "?"
        write_tag(tag, value, roster=True)
    write_tag("Result", reprResult[model.status], roster=True)

    # Variant
    if model.variant.variant != NORMALCHESS:
        write_tag("Variant", model.variant.cecp_name.capitalize())

    # Initial position
    if model.boards[0].asFen() != FEN_START:
        write_tag("SetUp", "1")
        write_tag("FEN", model.boards[0].asFen())

    # Number of moves
    write_tag("PlyCount", model.ply - model.lowply)

    # Final position
    if model.reason in ABORTED_REASONS:
        value = "abandoned"
    elif model.reason == WON_ADJUDICATION and model.isEngine2EngineGame():
        value = "rules infraction"
    elif model.reason in ADJUDICATION_REASONS:
        value = "adjudication"
    elif model.reason in DEATH_REASONS:
        value = "death"
    elif model.reason in CALLFLAG_REASONS:
        value = "time forfeit"
    elif model.reason in ADJOURNED_REASONS or status == "*":
        value = "unterminated"
    else:
        value = "normal"
    write_tag("Termination", value)

    # ELO and its variation
    if conf.get("saveRatingChange"):
        welo = model.tags["WhiteElo"]
        belo = model.tags["BlackElo"]
        if welo != "" and belo != "":
            write_tag("WhiteRatingDiff",
                      get_elo_rating_change_pgn(model, WHITE))  # Unofficial
            write_tag("BlackRatingDiff",
                      get_elo_rating_change_pgn(model, BLACK))  # Unofficial

    # Time
    if model.timed:
        write_tag(
            'WhiteClock',
            msToClockTimeTag(int(model.timemodel.getPlayerTime(WHITE) * 1000)))
        write_tag(
            'BlackClock',
            msToClockTimeTag(int(model.timemodel.getPlayerTime(BLACK) * 1000)))

    # Write all the unprocessed tags
    for tag in model.tags:
        # Debug: print(">> %s = %s" % (tag, str(model.tags[tag])))
        write_tag(tag, model.tags[tag])

    # Discovery of the moves and comments
    save_emt = conf.get("saveEmt")
    save_eval = conf.get("saveEval")
    result = []
    walk(model.boards[0].board, result, model, save_emt, save_eval)

    # Alignment of the fetched elements
    indented = conf.get("indentPgn")
    if indented:
        buffer = ""
        depth = 0
        crlf = False
        for text in result:
            # De/Indentation
            crlf = (buffer[-1:] if len(buffer) > 0 else "") in ["\r", "\n"]
            if text == "(":
                depth += 1
                if indented and not crlf:
                    buffer += os.linesep
                    crlf = True
            # Space between each term
            last = buffer[-1:] if len(buffer) > 0 else ""
            crlf = last in ["\r", "\n"]
            if not crlf and last != " " and last != "\t" and last != "(" and not text.startswith(
                    "\r") and not text.startswith(
                        "\n") and text != ")" and len(buffer) > 0:
                buffer += " "
            # New line for a new main move
            if len(buffer) == 0 or (indented and depth == 0 and last != "\r"
                                    and last != "\n" and re.match(
                                        r"^[0-9]+\.", text) is not None):
                buffer += os.linesep
                crlf = True
            # Alignment
            if crlf and depth > 0:
                for j in range(0, depth):
                    buffer += "    "
            # Term
            buffer += text
            if indented and text == ")":
                buffer += os.linesep
                crlf = True
                depth -= 1
    else:
        # Add new line to separate tag section and movetext
        print('', file=handle)
        buffer = textwrap.fill(" ".join(result), width=80)

    # Final
    status = reprResult[model.status]
    print(buffer, status, file=handle)
    # Add new line to separate next game
    print('', file=handle)

    output = handle.getvalue() if isinstance(handle, StringIO) else ""
    handle.close()
    return output
Ejemplo n.º 2
0
def save(handle, model, position=None):
    """ Saves the game from GameModel to .pgn """

    # Header
    status = "%s" % reprResult[model.status]

    print('[Event "%s"]' % model.getTagExport("Event", ""), file=handle)
    print('[Site "%s"]' % model.getTagExport("Site", ""), file=handle)
    print('[Date "%04d.%02d.%02d"]' % (int(
        model.tags["Year"]), int(model.tags["Month"]), int(model.tags["Day"])),
          file=handle)
    print('[Round "%s"]' % model.getTagExport("Round", "?"), file=handle)
    print('[White "%s"]' % repr(model.players[WHITE]), file=handle)
    print('[Black "%s"]' % repr(model.players[BLACK]), file=handle)
    print('[Result "%s"]' % status, file=handle)
    tag = model.getTagExport("ECO", "")
    if tag != "":
        print('[ECO "%s"]' % tag, file=handle)
        tag = model.getTagExport("Opening", "")
        if tag != "":
            print('[Opening "%s"]' % tag, file=handle)  # Unofficial
            tag = model.getTagExport("Variation", "")
            if tag != "":
                print('[Variation "%s"]' % tag, file=handle)  # Unofficial
    welo = model.getTagExport("WhiteElo", "")
    if welo != "":
        print('[WhiteElo "%s"]' % welo, file=handle)
    belo = model.getTagExport("BlackElo", "")
    if belo != "":
        print('[BlackElo "%s"]' % belo, file=handle)
    if welo != "" and belo != "" and conf.get("saveRatingChange", False):
        diff = str(get_elo_rating_change_pgn(model, WHITE))
        if diff != "":
            print('[WhiteRatingDiff "%s"]' % diff, file=handle)  # Unofficial
        diff = str(get_elo_rating_change_pgn(model, BLACK))
        if diff != "":
            print('[BlackRatingDiff "%s"]' % diff, file=handle)  # Unofficial
    tag = model.getTagExport("TimeControl", "")
    if tag != "":
        print('[TimeControl "%s"]' % tag, file=handle)
    if model.timed:
        print(
            '[WhiteClock "%s"]' %
            msToClockTimeTag(int(model.timemodel.getPlayerTime(WHITE) * 1000)),
            file=handle)
        print(
            '[BlackClock "%s"]' %
            msToClockTimeTag(int(model.timemodel.getPlayerTime(BLACK) * 1000)),
            file=handle)

    if model.variant.variant != NORMALCHESS:
        print('[Variant "%s"]' % model.variant.cecp_name.capitalize(),
              file=handle)

    if model.boards[0].asFen() != FEN_START:
        print('[SetUp "1"]', file=handle)
        print('[FEN "%s"]' % model.boards[0].asFen(), file=handle)
    print('[PlyCount "%s"]' % (model.ply - model.lowply), file=handle)
    tag = model.getTagExport("Annotator", "")
    if tag != "":
        print('[Annotator "%s"]' % tag, file=handle)
    if model.reason == WON_CALLFLAG:
        termination = "time forfeit"
    elif model.reason == WON_ADJUDICATION and model.isEngine2EngineGame():
        termination = "rules infraction"
    elif model.reason in (DRAW_ADJUDICATION, WON_ADJUDICATION):
        termination = "adjudication"
    elif model.reason == WHITE_ENGINE_DIED:
        termination = "white engine died"
    elif model.reason == BLACK_ENGINE_DIED:
        termination = "black engine died"
    elif model.reason in ABORTED_REASONS:
        termination = "abandoned"
    elif model.reason in ADJOURNED_REASONS:
        termination = "unterminated"
    else:
        termination = "normal"
    print('[Termination "%s"]' % termination, file=handle)

    save_emt = conf.get("saveEmt", False)
    save_eval = conf.get("saveEval", False)

    # Discovery of the moves and comments
    result = []
    walk(model.boards[0].board, result, model, save_emt, save_eval)

    # Alignment of the fetched elements
    indented = conf.get("indentPgn", False)
    buffer = ""
    depth = 0
    crlf = False
    for text in result:
        # De/Indentation
        crlf = (buffer[-1:] if len(buffer) > 0 else "") in ["\r", "\n"]
        if text == "(":
            depth += 1
            if indented and not crlf:
                buffer += os.linesep
                crlf = True
        # Space between each term
        last = buffer[-1:] if len(buffer) > 0 else ""
        crlf = last in ["\r", "\n"]
        if not crlf and last != " " and last != "\t" and last != "(" and not text.startswith(
                "\r") and not text.startswith(
                    "\n") and text != ")" and len(buffer) > 0:
            buffer += " "
        # New line for a new main move
        if len(buffer) == 0 or (indented and depth == 0 and last != "\r"
                                and last != "\n"
                                and re.match("^[0-9]+\.", text) is not None):
            buffer += os.linesep
            crlf = True
        # Alignment
        if crlf and depth > 0:
            for j in range(0, depth):
                buffer += "    "
        # Term
        buffer += text
        if indented and text == ")":
            buffer += os.linesep
            crlf = True
            depth -= 1

    # Status of the game
    buffer += ("" if crlf else (os.linesep if indented else " ")) + status
    if not indented:
        buffer = wrap(buffer, 80)

    # Final
    print(buffer, "", file=handle)
    output = handle.getvalue() if isinstance(handle, StringIO) else ""
    handle.close()
    return output
Ejemplo n.º 3
0
def save(handle, model, position=None):
    """ Saves the game from GameModel to .pgn """

    status = "%s" % reprResult[model.status]

    print('[Event "%s"]' % model.getTagExport("Event", ""), file=handle)
    print('[Site "%s"]' % model.getTagExport("Site", ""), file=handle)
    print('[Date "%04d.%02d.%02d"]' %
          (int(model.tags["Year"]), int(model.tags["Month"]), int(model.tags["Day"])), file=handle)
    print('[Round "%s"]' % model.getTagExport("Round", "?"), file=handle)
    print('[White "%s"]' % repr(model.players[WHITE]), file=handle)
    print('[Black "%s"]' % repr(model.players[BLACK]), file=handle)
    print('[Result "%s"]' % status, file=handle)
    tag = model.getTagExport("ECO", "")
    if tag != "":
        print('[ECO "%s"]' % tag, file=handle)
        tag = model.getTagExport("Opening", "")
        if tag != "":
            print('[Opening "%s"]' % tag, file=handle)  # Unofficial
            tag = model.getTagExport("Variation", "")
            if tag != "":
                print('[Variation "%s"]' % tag, file=handle)  # Unofficial
    welo = model.getTagExport("WhiteElo", "")
    if welo != "":
        print('[WhiteElo "%s"]' % welo, file=handle)
    belo = model.getTagExport("BlackElo", "")
    if belo != "":
        print('[BlackElo "%s"]' % belo, file=handle)
    if welo != "" and belo != "" and conf.get("saveRatingChange", False):
        diff = str(get_elo_rating_change_pgn(model, WHITE))
        if diff != "":
            print('[WhiteRatingDiff "%s"]' % diff, file=handle)  # Unofficial
        diff = str(get_elo_rating_change_pgn(model, BLACK))
        if diff != "":
            print('[BlackRatingDiff "%s"]' % diff, file=handle)  # Unofficial
    tag = model.getTagExport("TimeControl", "")
    if tag != "":
        print('[TimeControl "%s"]' % tag, file=handle)
    if model.timed:
        print('[WhiteClock "%s"]' %
              msToClockTimeTag(int(model.timemodel.getPlayerTime(WHITE) * 1000)), file=handle)
        print('[BlackClock "%s"]' %
              msToClockTimeTag(int(model.timemodel.getPlayerTime(BLACK) * 1000)), file=handle)

    if model.variant.variant != NORMALCHESS:
        print('[Variant "%s"]' % model.variant.cecp_name.capitalize(),
              file=handle)

    if model.boards[0].asFen() != FEN_START:
        print('[SetUp "1"]', file=handle)
        print('[FEN "%s"]' % model.boards[0].asFen(), file=handle)
    print('[PlyCount "%s"]' % (model.ply - model.lowply), file=handle)
    tag = model.getTagExport("Annotator", "")
    if tag != "":
        print('[Annotator "%s"]' % tag, file=handle)
    if model.reason == WON_CALLFLAG:
        termination = "time forfeit"
    elif model.reason == WON_ADJUDICATION and model.isEngine2EngineGame():
        termination = "rules infraction"
    elif model.reason in (DRAW_ADJUDICATION, WON_ADJUDICATION):
        termination = "adjudication"
    elif model.reason == WHITE_ENGINE_DIED:
        termination = "white engine died"
    elif model.reason == BLACK_ENGINE_DIED:
        termination = "black engine died"
    elif model.reason in ABORTED_REASONS:
        termination = "abandoned"
    elif model.reason in ADJOURNED_REASONS:
        termination = "unterminated"
    else:
        termination = "normal"
    print('[Termination "%s"]' % termination, file=handle)

    print("", file=handle)

    save_emt = conf.get("saveEmt", False)
    save_eval = conf.get("saveEval", False)

    result = []
    walk(model.boards[0].board, result, model, save_emt, save_eval)

    result = " ".join(result)
    result = wrap(result, 80)
    print(result, status, file=handle)
    print("", file=handle)
    output = handle.getvalue() if isinstance(handle, StringIO) else ""
    handle.close()
    return output
Ejemplo n.º 4
0
def save(handle, model, position=None):
    """ Saves the game from GameModel to .pgn """
    processed_tags = []

    def write_tag(tag, value, roster=False):
        nonlocal processed_tags
        if tag in processed_tags or (not roster and not value):
            return
        try:
            pval = str(value)
            pval = pval.replace("\\", "\\\\")
            pval = pval.replace("\"", "\\\"")
            print('[%s "%s"]' % (tag, pval), file=handle)
            processed_tags = processed_tags + [tag]
        except Exception:
            pass

    # Mandatory ordered seven-tag roster
    status = reprResult[model.status]
    for tag in mandatory_tags:
        value = model.tags[tag]
        if tag == "Date":
            y, m, d = parseDateTag(value)
            y = "%04d" % y if y is not None else "????"
            m = "%02d" % m if m is not None else "??"
            d = "%02d" % d if d is not None else "??"
            value = "%s.%s.%s" % (y, m, d)
        elif value == "":
            value = "?"
        write_tag(tag, value, roster=True)
    write_tag("Result", reprResult[model.status], roster=True)

    # Variant
    if model.variant.variant != NORMALCHESS:
        write_tag("Variant", model.variant.cecp_name.capitalize())

    # Initial position
    if model.boards[0].asFen() != FEN_START:
        write_tag("SetUp", "1")
        write_tag("FEN", model.boards[0].asFen())

    # Number of moves
    write_tag("PlyCount", model.ply - model.lowply)

    # Final position
    if model.reason == WON_CALLFLAG:
        value = "time forfeit"
    elif model.reason == WON_ADJUDICATION and model.isEngine2EngineGame():
        value = "rules infraction"
    elif model.reason in (DRAW_ADJUDICATION, WON_ADJUDICATION):
        value = "adjudication"
    elif model.reason == WHITE_ENGINE_DIED:
        value = "white engine died"
    elif model.reason == BLACK_ENGINE_DIED:
        value = "black engine died"
    elif model.reason in ABORTED_REASONS:
        value = "abandoned"
    elif model.reason in ADJOURNED_REASONS:
        value = "unterminated"
    else:
        value = "unterminated" if status == "*" else None
    if value is not None:
        write_tag("Termination", value)

    # ELO and its variation
    if conf.get("saveRatingChange", False):
        welo = model.tags["WhiteElo"]
        belo = model.tags["BlackElo"]
        if welo != "" and belo != "":
            write_tag("WhiteRatingDiff", get_elo_rating_change_pgn(model, WHITE))  # Unofficial
            write_tag("BlackRatingDiff", get_elo_rating_change_pgn(model, BLACK))  # Unofficial

    # Time
    if model.timed:
        write_tag('WhiteClock', msToClockTimeTag(int(model.timemodel.getPlayerTime(WHITE) * 1000)))
        write_tag('BlackClock', msToClockTimeTag(int(model.timemodel.getPlayerTime(BLACK) * 1000)))

    # Write all the unprocessed tags
    for tag in model.tags:
        # Debug: print(">> %s = %s" % (tag, str(model.tags[tag])))
        write_tag(tag, model.tags[tag])

    # Discovery of the moves and comments
    save_emt = conf.get("saveEmt", False)
    save_eval = conf.get("saveEval", False)
    result = []
    walk(model.boards[0].board, result, model, save_emt, save_eval)

    # Alignment of the fetched elements
    indented = conf.get("indentPgn", False)
    if indented:
        buffer = ""
        depth = 0
        crlf = False
        for text in result:
            # De/Indentation
            crlf = (buffer[-1:] if len(buffer) > 0 else "") in ["\r", "\n"]
            if text == "(":
                depth += 1
                if indented and not crlf:
                    buffer += os.linesep
                    crlf = True
            # Space between each term
            last = buffer[-1:] if len(buffer) > 0 else ""
            crlf = last in ["\r", "\n"]
            if not crlf and last != " " and last != "\t" and last != "(" and not text.startswith("\r") and not text.startswith("\n") and text != ")" and len(buffer) > 0:
                buffer += " "
            # New line for a new main move
            if len(buffer) == 0 or (indented and depth == 0 and last != "\r" and last != "\n" and re.match("^[0-9]+\.", text) is not None):
                buffer += os.linesep
                crlf = True
            # Alignment
            if crlf and depth > 0:
                for j in range(0, depth):
                    buffer += "    "
            # Term
            buffer += text
            if indented and text == ")":
                buffer += os.linesep
                crlf = True
                depth -= 1
    else:
        # Add new line to separate tag section and movetext
        print('', file=handle)
        buffer = textwrap.fill(" ".join(result), width=80)

    # Final
    status = reprResult[model.status]
    print(buffer, status, file=handle)
    # Add new line to separate next game
    print('', file=handle)

    output = handle.getvalue() if isinstance(handle, StringIO) else ""
    handle.close()
    return output