예제 #1
0
def handle_move(game: database.Game, san_move: str) -> None:
    board = load_from_pgn(game.pgn)

    try:
        move(board, san_move)
    except ValueError as err:
        raise err

    game.pgn = save_to_pgn(board)
    database.add_to_database(game)
예제 #2
0
def update_game(
    game: database.Game,
    recalculate_expiration_date: bool = False,
    reset_action: bool = False,
    concede_side: int = None,
    only_check_expiration: bool = False,
) -> None:
    if game.winner is not None:
        return  # if the game has already finished, there is nothing to do

    board = load_from_pgn(game.pgn)
    turn = get_turn(board)

    if has_game_expired(game):
        game.win_reason = "Game expired"
        if turn == constants.WHITE:
            game.winner = constants.BLACK
        else:
            game.winner = constants.WHITE

        database.add_to_database(game)

        recalculate_elo(game)
        return

    if only_check_expiration:
        return

    if concede_side in [constants.WHITE, constants.BLACK]:
        if concede_side == constants.WHITE:
            game.winner = constants.BLACK
        else:
            game.winner = constants.WHITE

        concede_side_str = constants.turn_to_str(concede_side).capitalize()
        game.win_reason = f"{concede_side_str} conceded"
        game.expiration_date = None

        database.add_to_database(game)

        recalculate_elo(game)
        return

    if recalculate_expiration_date:
        game.expiration_date = datetime.datetime.now() + EXPIRATION_TIMEDELTA
        database.add_to_database(game)

    claim_draw = game.action_proposed == constants.ACTION_DRAW
    undo_last = game.action_proposed == constants.ACTION_UNDO
    both_agreed = game.white_accepted_action and game.black_accepted_action

    try:
        winner = get_winner(board,
                            claim_draw=claim_draw,
                            both_agreed=both_agreed)
        reason = get_game_over_reason(board,
                                      claim_draw=claim_draw,
                                      both_agreed=both_agreed)
    except RuntimeError as err:
        logger.info("The game has not ended yet:")
        logger.info(
            err
        )  # not actually an error, just the reasoning behind the game not being over

        if undo_last and both_agreed:
            undo(board)
            game.pgn = save_to_pgn(board)
            database.add_to_database(game)

        if reset_action:
            game.action_proposed = constants.ACTION_NONE
            game.white_accepted_action = False
            game.black_accepted_action = False

            database.add_to_database(game)

        return

    game.winner = winner
    game.win_reason = reason
    game.expiration_date = None
    database.add_to_database(game)

    recalculate_elo(game)