Ejemplo n.º 1
0
 def get_rating(self, variant: str, chess960: bool) -> Rating:
     if variant in self.perfs:
         gl = self.perfs[variant + ("960" if chess960 else "")]["gl"]
         la = self.perfs[variant + ("960" if chess960 else "")]["la"]
         return gl2.create_rating(gl["r"], gl["d"], gl["v"], la)
     rating = gl2.create_rating()
     self.perfs[variant + ("960" if chess960 else "")] = DEFAULT_PERF
     return rating
Ejemplo n.º 2
0
 def __init__(
     self,
     _id: str,
     wplayer: User,
     wrating: str,
     bplayer: User,
     brating: str,
     result: str,
     date: datetime,
     wberserk: bool,
     bberserk: bool,
 ):
     self.id = _id
     self.wplayer = wplayer
     self.bplayer = bplayer
     self.result = result
     self.date = date
     self.white_rating = gl2.create_rating(int(wrating.rstrip("?")))
     self.black_rating = gl2.create_rating(int(brating.rstrip("?")))
     self.wberserk = wberserk
     self.bberserk = bberserk
Ejemplo n.º 3
0
async def load_game(app, game_id):
    """ Return Game object from app cache or from database """
    db = app["db"]
    games = app["games"]
    users = app["users"]
    if game_id in games:
        return games[game_id]

    doc = await db.game.find_one({"_id": game_id})

    if doc is None:
        return None

    wp, bp = doc["us"]
    if wp in users:
        wplayer = users[wp]
    else:
        wplayer = User(app, username=wp, anon=True)
        users[wp] = wplayer

    if bp in users:
        bplayer = users[bp]
    else:
        bplayer = User(app, username=bp, anon=True)
        users[bp] = bplayer

    variant = C2V[doc["v"]]

    initial_fen = doc.get("if")

    # Old USI Shogi games saved using usi2uci() need special handling
    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)

    game = Game(
        app, game_id, variant, initial_fen, wplayer, bplayer,
        base=doc["b"],
        inc=doc["i"],
        byoyomi_period=int(bool(doc.get("bp"))),
        level=doc.get("x"),
        rated=doc.get("y"),
        chess960=bool(doc.get("z")),
        create=False,
        tournamentId=doc.get("tid"))

    mlist = decode_moves(doc["m"], variant)

    if mlist or (game.tournamentId is not None and doc["s"] > STARTED):
        game.saved = True

    if usi_format and variant == "shogi":
        mirror = mirror9
        mlist = map(mirror, mlist)

    elif usi_format and (variant in ("minishogi", "kyotoshogi")):
        mirror = mirror5
        mlist = map(mirror, mlist)

    elif variant in GRANDS:
        mlist = map(zero2grand, mlist)

    if "a" in doc:
        if usi_format and "m" in doc["a"][0]:
            doc["a"][0]["m"] = mirror(usi2uci(doc["a"][0]["m"]))
        game.steps[0]["analysis"] = doc["a"][0]

    if "mct" in doc:
        print(doc["mct"])
        manual_count_toggled = iter(doc["mct"])
        count_started = -1
        count_ended = -1

    for ply, move in enumerate(mlist):
        try:
            if "mct" in doc:
                # print("Ply", ply, "Move", move)
                if ply + 1 >= count_ended:
                    try:
                        game.board.count_started = -1
                        count_started, count_ended = next(manual_count_toggled)
                        # print("New count interval", (count_started, count_ended))
                    except StopIteration:
                        # print("Piece's honour counting started")
                        count_started = 0
                        count_ended = MAX_PLY + 1
                        game.board.count_started = 0
                if ply + 1 == count_started:
                    # print("Count started", count_started)
                    game.board.count_started = ply

            san = game.board.get_san(move)
            game.board.push(move)
            game.check = game.board.is_checked()
            turnColor = "black" if game.board.color == BLACK else "white"
            if usi_format:
                turnColor = "black" if turnColor == "white" else "white"
            game.steps.append({
                "fen": game.board.fen,
                "move": move,
                "san": san,
                "turnColor": turnColor,
                "check": game.check}
            )

            if "a" in doc:
                if usi_format and "m" in doc["a"][ply + 1]:
                    doc["a"][ply + 1]["m"] = mirror(usi2uci(doc["a"][ply + 1]["m"]))
                try:
                    game.steps[-1]["analysis"] = doc["a"][ply + 1]
                except IndexError:
                    print("IndexError", ply, move, san)

        except Exception:
            log.exception("ERROR: Exception in load_game() %s %s %s %s %s", game_id, variant, doc.get("if"), move, list(mlist))
            break

    if len(game.steps) > 1:
        move = game.steps[-1]["move"]
        game.lastmove = move

    level = doc.get("x")
    game.date = doc["d"]
    if game.date.tzinfo is None:
        game.date = game.date.replace(tzinfo=timezone.utc)
    game.status = doc["s"]
    game.level = level if level is not None else 0
    game.result = C2R[doc["r"]]

    try:
        game.wrating = doc["p0"]["e"]
        game.brating = doc["p1"]["e"]
    except KeyError:
        game.wrating = "1500?"
        game.brating = "1500?"

    game.white_rating = gl2.create_rating(int(game.wrating.rstrip("?")))
    game.black_rating = gl2.create_rating(int(game.brating.rstrip("?")))

    try:
        game.wrdiff = doc["p0"]["d"]
        game.brdiff = doc["p1"]["d"]
    except KeyError:
        game.wrdiff = ""
        game.brdiff = ""

    if game.tournamentId is not None:
        game.wberserk = doc.get("wb", False)
        game.bberserk = doc.get("bb", False)

    if doc.get("by") is not None:
        game.imported_by = doc.get("by")

    return game