Example #1
0
def apidoc():
    render = {}
    render["DEFAULT_FEN"] = DEFAULT_FEN
    render["status"] = 200

    # Parse the FEN.
    fen = request.args.get("fen")
    if not fen:
        render["status"] = 400
    else:
        try:
            board = chess.Board(fen)
        except ValueError:
            try:
                board = chess.Board()
                board.set_epd(fen)
            except ValueError:
                render["status"] = 400

    # Set the exact given FEN and a sanitized FEN for result.
    if fen is not None:
        render["fen"] = fen

    if render["status"] == 400:
        render["sanitized_fen"] = "8/8/8/8/8/8/8/8 w - - 0 1"
    else:
        render["sanitized_fen"] = board.fen()
        if board.status() == chess.STATUS_VALID:
            render["request_body"] = json.dumps(probe(board), indent=2, sort_keys=True)
        else:
            render["status"] = 400

    # Render.
    return html_minify(render_template("apidoc.html", **render))
Example #2
0
def apidoc():
    render = {}
    render["DEFAULT_FEN"] = DEFAULT_FEN
    render["status"] = 200

    # Parse the FEN.
    fen = request.args.get("fen")
    if not fen:
        render["status"] = 400
        render["error"] = "fen required"
    else:
        try:
            board = chess.Board(fen)
        except ValueError:
            render["status"] = 400
            render["error"] = "invalid fen"

    # Set the exact given FEN and a sanitized FEN for result.
    if fen is not None:
        render["fen"] = fen

    if render["status"] == 400:
        render["sanitized_fen"] = "8/8/8/8/8/8/8/8 w - - 0 1"
    else:
        render["sanitized_fen"] = board.fen()
        if board.is_valid():
            render["request_body"] = json.dumps(probe(board),
                                                indent=2,
                                                sort_keys=True)
        else:
            render["status"] = 400
            render["error"] = "illegal fen"

    # Render.
    return html_minify(render_template("apidoc.html", **render))
Example #3
0
def imprint():
    return html_minify(render_template("legal.html"))
Example #4
0
def index():
    # Setup a board from the given valid FEN or fall back to the default FEN.
    try:
        board = chess.Board(request.args.get("fen", DEFAULT_FEN))
    except ValueError:
        try:
            board = chess.Board()
            board.set_epd(request.args.get("fen", DEFAULT_FEN))
        except ValueError:
            board = chess.Board(DEFAULT_FEN)

    # Get FENs with the current side to move, black and white to move.
    original_turn = board.turn
    board.turn = chess.WHITE
    white_fen = board.fen()
    board.turn = chess.BLACK
    black_fen = board.fen()
    board.turn = original_turn
    fen = board.fen()

    wdl = None
    winning_side = None
    winning_moves = []
    drawing_moves = []
    losing_moves = []

    if board.status() != chess.STATUS_VALID:
        status = "Invalid position"
    elif board.fen() == DEFAULT_FEN:
        status = "Draw by insufficient material"
        wdl = 0
    elif board.is_stalemate():
        status = "Draw by stalemate"
        wdl = 0
    elif board.is_checkmate():
        wdl = 2
        if board.turn == chess.WHITE:
            status = "Black won by checkmate"
            winning_side = "black"
        else:
            status = "White won by checkmate"
            winning_side = "white"
    else:
        wdl = tablebases.probe_wdl(board)
        dtz = tablebases.probe_dtz(board)
        if board.is_insufficient_material():
            status = "Draw by insufficient material"
            wdl = 0
        elif dtz is None:
            status = "Position not found in tablebases"
        elif dtz == 0:
            status = "Tablebase draw"
        elif dtz > 0 and board.turn == chess.WHITE:
            status = "White is winning with DTZ %d" % (abs(dtz), )
            winning_side = "white"
            losing_side = "black"
        elif dtz < 0 and board.turn == chess.WHITE:
            status = "White is losing with DTZ %d" % (abs(dtz), )
            winning_side = "black"
            losing_side = "white"
        elif dtz > 0 and board.turn == chess.BLACK:
            status = "Black is winning with DTZ %d" % (abs(dtz), )
            winning_side = "black"
            losing_side = "white"
        elif dtz < 0 and board.turn == chess.BLACK:
            status = "Black is losing with DTZ %d" % (abs(dtz), )
            winning_side = "white"
            losing_side = "black"

        for move in board.legal_moves:
            san = board.san(move)
            board.push(move)

            move_info = {
                "uci": move.uci(),
                "san": san,
                "fen": board.epd() + " 0 1",
                "dtz": tablebases.probe_dtz(board),
                "zeroing": board.halfmove_clock == 0,
                "checkmate": board.is_checkmate(),
                "stalemate": board.is_stalemate(),
                "insufficient_material": board.is_insufficient_material(),
            }

            move_info["winning"] = move_info["checkmate"] or (move_info["dtz"] is not None and move_info["dtz"] < 0)
            move_info["drawing"] = move_info["stalemate"] or move_info["insufficient_material"] or (move_info["dtz"] == 0 or (move_info["dtz"] is None and wdl is not None and wdl < 0))

            if move_info["winning"]:
                if move_info["checkmate"]:
                    move_info["badge"] = "Checkmate"
                elif move_info["zeroing"]:
                    move_info["badge"] = "Zeroing"
                else:
                    move_info["badge"] = "Win with DTZ %d" % (abs(move_info["dtz"]), )

                winning_moves.append(move_info)
            elif move_info["drawing"]:
                if move_info["stalemate"]:
                    move_info["badge"] = "Stalemate"
                elif move_info["insufficient_material"]:
                    move_info["badge"] = "Insufficient material"
                elif move_info["dtz"] == 0:
                    move_info["badge"] = "Draw"
                else:
                    move_info["badge"] = "Unknown"

                drawing_moves.append(move_info)
            else:
                if move_info["dtz"] is None:
                    move_info["badge"] = "Unknown"
                else:
                    move_info["badge"] = "Loss with DTZ %d" % (abs(move_info["dtz"]), )
                losing_moves.append(move_info)

            board.pop()

    winning_moves.sort(key=lambda move: move["uci"])
    winning_moves.sort(key=lambda move: move["dtz"], reverse=True)
    winning_moves.sort(key=lambda move: move["zeroing"], reverse=True)
    winning_moves.sort(key=lambda move: move["checkmate"], reverse=True)

    drawing_moves.sort(key=lambda move: move["uci"])
    drawing_moves.sort(key=lambda move: move["insufficient_material"], reverse=True)
    drawing_moves.sort(key=lambda move: move["stalemate"], reverse=True)

    losing_moves.sort(key=lambda move: move["uci"])
    losing_moves.sort(key=lambda move: move["dtz"], reverse=True)

    return html_minify(render_template("index.html",
        fen_input=board.epd() + " 0 1" if board.epd() + " 0 1" != DEFAULT_FEN else "",
        fen=fen,
        status=status,
        insufficient_material=board.is_insufficient_material(),
        winning_side=winning_side,
        winning_moves=winning_moves,
        drawing_moves=drawing_moves,
        losing_moves=losing_moves,
        blessed_loss=wdl == -1,
        cursed_win=wdl == 1,
        illegal=board.status() != chess.STATUS_VALID,
        not_yet_solved=board.epd() + " 0 1" == chess.STARTING_FEN,
        unknown=wdl is None,
        turn="white" if board.turn == chess.WHITE else "black",
        white_fen=white_fen,
        black_fen=black_fen,
        horizontal_fen=mirror_horizontal(fen),
        vertical_fen=mirror_vertical(fen),
        swapped_fen=swap_colors(fen),
        DEFAULT_FEN=DEFAULT_FEN,
        material=material(board)
    ))
Example #5
0
def imprint():
    return html_minify(render_template("legal.html"))
Example #6
0
def index():
    # Setup a board from the given valid FEN or fall back to the default FEN.
    try:
        board = chess.Board(request.args.get("fen", DEFAULT_FEN))
    except ValueError:
        try:
            board, _ = chess.Board.from_epd(
                request.args.get("fen", DEFAULT_FEN))
        except ValueError:
            board = chess.Board(DEFAULT_FEN)

    # Get FENs with the current side to move, black and white to move.
    original_turn = board.turn
    board.turn = chess.WHITE
    white_fen = board.fen()
    board.turn = chess.BLACK
    black_fen = board.fen()
    board.turn = original_turn
    fen = board.fen()

    wdl = None
    winning_side = None
    winning_moves = []
    drawing_moves = []
    losing_moves = []

    if not board.is_valid():
        status = "Invalid position"
    elif board.is_stalemate():
        status = "Draw by stalemate"
        wdl = 0
    elif board.is_checkmate():
        wdl = 2
        if board.turn == chess.WHITE:
            status = "Black won by checkmate"
            winning_side = "black"
        else:
            status = "White won by checkmate"
            winning_side = "white"
    else:
        wdl = syzygy.probe_wdl(board)
        dtz = syzygy.probe_dtz(board)
        if board.is_insufficient_material():
            status = "Draw by insufficient material"
            wdl = 0
        elif dtz is None:
            status = "Position not found in tablebases"
        elif dtz == 0:
            status = "Tablebase draw"
        elif dtz > 0 and board.turn == chess.WHITE:
            status = "White is winning with DTZ %d" % (abs(dtz), )
            winning_side = "white"
            losing_side = "black"
        elif dtz < 0 and board.turn == chess.WHITE:
            status = "White is losing with DTZ %d" % (abs(dtz), )
            winning_side = "black"
            losing_side = "white"
        elif dtz > 0 and board.turn == chess.BLACK:
            status = "Black is winning with DTZ %d" % (abs(dtz), )
            winning_side = "black"
            losing_side = "white"
        elif dtz < 0 and board.turn == chess.BLACK:
            status = "Black is losing with DTZ %d" % (abs(dtz), )
            winning_side = "white"
            losing_side = "black"

        for move in board.legal_moves:
            san = board.san(move)
            uci = board.uci(move)
            board.push(move)

            move_info = {
                "uci": uci,
                "san": san,
                "fen": board.epd() + " 0 1",
                "dtz": syzygy.probe_dtz(board),
                "dtm": gaviota.probe_dtm(board),
                "zeroing": board.halfmove_clock == 0,
                "checkmate": board.is_checkmate(),
                "stalemate": board.is_stalemate(),
                "insufficient_material": board.is_insufficient_material(),
            }

            move_info["dtm"] = abs(
                move_info["dtm"]) if move_info["dtm"] is not None else None

            move_info["winning"] = move_info["checkmate"] or (
                move_info["dtz"] is not None and move_info["dtz"] < 0)
            move_info["drawing"] = move_info["stalemate"] or move_info[
                "insufficient_material"] or (move_info["dtz"] == 0 or
                                             (move_info["dtz"] is None
                                              and wdl is not None and wdl < 0))

            if move_info["winning"]:
                if move_info["checkmate"]:
                    move_info["badge"] = "Checkmate"
                elif move_info["zeroing"]:
                    move_info["badge"] = "Zeroing"
                else:
                    move_info["badge"] = "Win with DTZ %d" % (abs(
                        move_info["dtz"]), )

                winning_moves.append(move_info)
            elif move_info["drawing"]:
                if move_info["stalemate"]:
                    move_info["badge"] = "Stalemate"
                elif move_info["insufficient_material"]:
                    move_info["badge"] = "Insufficient material"
                elif move_info["dtz"] == 0:
                    move_info["badge"] = "Draw"
                else:
                    move_info["badge"] = "Unknown"

                drawing_moves.append(move_info)
            else:
                if move_info["dtz"] is None:
                    move_info["badge"] = "Unknown"
                elif move_info["zeroing"]:
                    move_info["badge"] = "Zeroing"
                else:
                    move_info["badge"] = "Loss with DTZ %d" % (abs(
                        move_info["dtz"]), )
                losing_moves.append(move_info)

            board.pop()

    winning_moves.sort(key=lambda move: move["uci"])
    winning_moves.sort(key=lambda move: (move["dtm"] is None, move["dtm"]))
    winning_moves.sort(key=lambda move: (move["dtz"] is None, move["dtz"]),
                       reverse=True)
    winning_moves.sort(key=lambda move: move["zeroing"], reverse=True)
    winning_moves.sort(key=lambda move: move["checkmate"], reverse=True)

    drawing_moves.sort(key=lambda move: move["uci"])
    drawing_moves.sort(key=lambda move: move["insufficient_material"],
                       reverse=True)
    drawing_moves.sort(key=lambda move: move["stalemate"], reverse=True)

    losing_moves.sort(key=lambda move: move["uci"])
    losing_moves.sort(key=lambda move: (move["dtm"] is not None, move["dtm"]),
                      reverse=True)
    losing_moves.sort(key=lambda move: (move["dtz"] is None, move["dtz"]),
                      reverse=True)
    losing_moves.sort(key=lambda move: move["zeroing"])

    return html_minify(
        render_template("index.html",
                        fen_input=board.epd() +
                        " 0 1" if board.epd() + " 0 1" != DEFAULT_FEN else "",
                        fen=fen,
                        status=status,
                        insufficient_material=board.is_insufficient_material(),
                        winning_side=winning_side,
                        winning_moves=winning_moves,
                        drawing_moves=drawing_moves,
                        losing_moves=losing_moves,
                        blessed_loss=wdl == -1,
                        cursed_win=wdl == 1,
                        illegal=not board.is_valid(),
                        not_yet_solved=board.epd() +
                        " 0 1" == chess.STARTING_FEN,
                        unknown=wdl is None,
                        turn="white" if board.turn == chess.WHITE else "black",
                        white_fen=white_fen,
                        black_fen=black_fen,
                        horizontal_fen=mirror_horizontal(fen),
                        vertical_fen=mirror_vertical(fen),
                        swapped_fen=swap_colors(fen),
                        clear_fen=clear_fen(fen),
                        DEFAULT_FEN=DEFAULT_FEN,
                        material=material(board)))