Example #1
0
    def from_replay(cls,
                    savegame_file=None,
                    player_intelligence=Intelligence.Human,
                    opponent_intelligence=Intelligence.Network):

        if not savegame_file:
            savegame_file = max(glob.iglob('./replay/*/*.json'),
                                key=os.path.getctime)

        controller = cls(View(), Sound())
        savegame_document = json.loads(open(savegame_file).read())
        controller.game = Game.from_log_document(savegame_document,
                                                 player_intelligence,
                                                 opponent_intelligence)
        controller.clear_move()

        if controller.game.is_turn_done():
            controller.game.shift_turn()
        controller.game.gamestate.set_available_actions()

        player = controller.game.current_player()
        print("current player is", player.color, player.intelligence)

        if play_fanfare:
            controller.sound.play_fanfare()

        return controller
Example #2
0
def test_get_expected_action():
    game_document = json.loads(open("./tests/keep_replays/3.json").read())
    game = Game.from_log_document(game_document)
    expected_action = server_library.get_expected_action(
        game_document, game.gamestate)

    assert expected_action == (11, "move_with_attack")
Example #3
0
def calculate_ratings():
    games = list(get_collection("games").find({}).sort("finished_at", 1))

    debug_lines = []
    ranking = {}

    for game_document in games:
        try:
            log_document = construct_log_document(game_document)
            game = Game.from_log_document(log_document)
            if game.gamestate.is_ended():
                winner = game.current_player().profile
                loser = game.opponent_player().profile
                if winner not in ranking:
                    ranking[winner] = [1000]
                if loser not in ranking:
                    ranking[loser] = [1000]

                ranking_winner = ranking[winner][-1]
                ranking_loser = ranking[loser][-1]
                rating_difference = ranking_loser - ranking_winner

                # "skill_factor" is an expression I came up with. I'm not sure what it's really called.
                # Arpad Elo came up with the value 400. It means that a player with 400 higher rating
                # than another player has a 90% probability of winning. At a difference of 200 the
                # probability is 75%
                skill_factor = float(2000)

                expected_outcome_for_winner = 1 / (
                    1 + pow(10, (rating_difference / skill_factor)))

                # The k value determines the volatility in the ratings. 32 is pretty high. It's what ICC uses
                # It means that the most points that can be won in one game is 32
                k_value = 32

                rating_points_won_and_lost = int(
                    k_value * (1 - expected_outcome_for_winner))

                # debug_line = str(game_document["created_at"]) + " "
                # debug_line += " (" + str(game_document["_id"]) + "): " + winner + " beat " + loser
                # debug_line += " (p: " + "{0:.2f}".format(expected_outcome_for_winner) + "). "
                # debug_line += winner + ": " + str(ranking_winner)
                # debug_line += " => " + str(ranking_winner + rating_points_won_and_lost) + ", "
                # debug_line += loser + ": " + str(ranking_loser)
                # debug_line += " => " + str(ranking_loser - rating_points_won_and_lost)
                # debug_lines.append(debug_line)

                ranking[winner].append(ranking_winner +
                                       rating_points_won_and_lost)
                ranking[loser].append(ranking_loser -
                                      rating_points_won_and_lost)
        except Exception:
            debug_lines.append(
                str(game_document["_id"]) + ": " + traceback.format_exc())

    #for index, line in enumerate(debug_lines):
    #    ranking["debug_{0:03d}".format(index)] = line

    return ranking
Example #4
0
def do_action_post(game_id):
    games = get_collection("games")
    game_document = games.find_one({"_id": ObjectId(game_id)})
    if not game_document:
        return {
            "Status": "Error",
            "Message": "Could not find game with id " + game_id
        }

    try:
        action_document = request.json
    except ValueError:
        return {
            "Status": "Error",
            "Message":
            "No JSON decoded. Request body: " + request.body.getvalue()
        }

    action_document["created_at"] = datetime.utcnow()
    log_document = construct_log_document(game_document)
    game = Game.from_log_document(log_document)

    validation_errors = validate_input(log_document, game.gamestate,
                                       action_document)
    if validation_errors:
        return validation_errors

    if action_document[
            "type"] == "options" and "move_with_attack" in action_document:
        response_document = register_move_with_attack(action_document, game_id,
                                                      game.gamestate)
        cache.set(game_id, datetime.utcnow().replace(microsecond=0))
        return response_document
    elif action_document["type"] == "options" and "upgrade" in action_document:
        response_document = register_upgrade(action_document, game.gamestate,
                                             game_id)
        cache.set(game_id, datetime.utcnow().replace(microsecond=0))
        return response_document

    # Initial validation is done with a non-shifted gamestate, because it is
    # easier to find expected action from that
    # The rest is done with the turn shifted (if relevant)
    if game.is_turn_done():
        game.shift_turn()

    result = validate_action(game.gamestate, action_document)
    if isinstance(result, dict):
        return result
    else:
        action = result

    response_document = register_move_attack_ability(action_document, game_id,
                                                     game.gamestate, action)
    cache.set(game_id, datetime.utcnow().replace(microsecond=0))
    return response_document
Example #5
0
    def from_network(cls, player):

        client = Client(player)
        game_document = client.get_game()

        controller = cls(View(), Sound())
        controller.game = Game.from_log_document(game_document, player)
        controller.client = client
        player = controller.game.current_player()
        print("current player is", player.color, player.intelligence,
              player.profile)
        controller.clear_move()
        controller.game.gamestate.set_available_actions()

        if play_fanfare:
            controller.sound.play_fanfare()

        return controller
def is_outcome_correct(test_document):
    game = Game.from_log_document(test_document)
    controller = Controller(View(), Sound())
    controller.positions = read_positions(test_document["pre_positions"])

    controller.game = game
    click_position = Position.from_string(test_document["click_position"])

    if "outcome" in test_document:
        outcome = Outcome.from_document(test_document["outcome"])
        controller.determine_outcome = partial(determine_outcome, outcome)

    if "end_at" in test_document:
        end_at = test_document["end_at"]
        controller.pick_end_at = partial(pick_end_at, end_at)

    if "upgrade_choice" in test_document:
        upgrade_choice = int(test_document["upgrade_choice"])
        controller.pick_upgrade = partial(pick_upgrade, upgrade_choice)

    if "move_with_attack" in test_document:
        controller.ask_about_move_with_attack = partial(ask_about_move_with_attack, test_document["move_with_attack"])

    controller.game.gamestate.set_available_actions()

    controller.game.save = save

    controller.add_log = add_log

    controller.left_click(click_position)

    actual_gamestate = controller.game.gamestate.to_document()
    expected_gamestate = Gamestate.from_document(test_document["post_gamestate"]).to_document()

    actual_positions = controller.positions
    expected_positions = read_positions(test_document["post_positions"])

    return give_output(actual_gamestate, expected_gamestate, actual_positions, expected_positions)
Example #7
0
def view(game_id):
    last_modified_cache = cache.get(game_id)
    if last_modified_cache:
        if_modified_since_header = request.get_header("If-Modified-Since")
        if if_modified_since_header:
            if_modified_since_tuple = parsedate(if_modified_since_header)
            if_modified_since_timestamp = mktime(if_modified_since_tuple)
            if_modified_since = datetime.fromtimestamp(
                if_modified_since_timestamp)
            if last_modified_cache <= if_modified_since:
                # If our latest update is earlier than the client's latest update,
                # let the client know that nothing new is afoot
                response.status = 304
                return

    games = get_collection("games")
    game_document = games.find_one({"_id": ObjectId(game_id)})
    if not game_document:
        return {
            "Status": "Error",
            "Message": "Could not find game with id " + game_id
        }

    log_document = construct_log_document(game_document)
    game = Game.from_log_document(log_document)
    number = get_expected_action(log_document, game.gamestate)[0]
    if number == log_document["action_count"]:
        # Action isn't completed yet
        log_document["action_count"] = number - 1

    last_modified = log_document["last_modified"]
    if last_modified > datetime(1970, 1, 1):
        stamp = mktime(last_modified.timetuple())
        formatted_time = format_date_time(stamp)
        response.set_header("Last-Modified", formatted_time)
        cache.set(game_id, last_modified.replace(microsecond=0))

    return log_document