Exemplo n.º 1
0
def evaluate_saved_model(weight_files,
                         num_game,
                         seed,
                         bomb,
                         num_run=1,
                         log_prefix=None,
                         verbose=True):
    model_lockers = []
    greedy_extra = 0
    num_player = len(weight_files)
    assert num_player > 1, "1 weight file per player"

    for weight_file in weight_files:
        if verbose:
            print("evaluating: %s\n\tfor %dx%d games" %
                  (weight_file, num_run, num_game))
        if ("GREEDY_EXTRA1" in weight_file or "sad" in weight_file
                or "aux" in weight_file):
            player_greedy_extra = 1
            greedy_extra = 1
        else:
            player_greedy_extra = 0

        device = "cpu"
        game_info = utils.get_game_info(num_player, player_greedy_extra)
        input_dim = game_info["input_dim"]
        output_dim = game_info["num_action"]
        hid_dim = 512

        actor = iql_r2d2.R2D2Agent(1, 0.99, 0.9, device, input_dim, hid_dim,
                                   output_dim)
        state_dict = torch.load(weight_file)
        if "pred.weight" in state_dict:
            state_dict.pop("pred.bias")
            state_dict.pop("pred.weight")

        actor.online_net.load_state_dict(state_dict)
        model_lockers.append(rela.ModelLocker([actor], device))

    scores = []
    perfect = 0
    for i in range(num_run):
        _, _, score, p = evaluate(
            model_lockers,
            num_game,
            num_game * i + seed,
            0,
            num_player,
            bomb,
            greedy_extra,
        )
        scores.extend(score)
        perfect += p

    mean = np.mean(scores)
    sem = np.std(scores) / np.sqrt(len(scores))
    perfect_rate = perfect / (num_game * num_run)
    if verbose:
        print("score: %f +/- %f" % (mean, sem), "; perfect: ", perfect_rate)
    return mean, sem, perfect_rate
def game():
    # read the HTTP parameters
    if "user" not in request.values or "game" not in request.values:
        TODO
    game = int(request.values["game"])
    user = request.values["user"]


    # connect to the database, then read the game state
    conn = open_db()

    (players,size,state)       = utils.get_game_info(conn, game)
    (board, nextToPlay,letter) = utils.build_board(conn, game,size)

    return render_template("game.html",
                           gameID=game,
                           players=players,
                           size=3,
                           nextToPlay=players[nextToPlay],
                           thisPlayer=user,
                           state=state,
                           board=board,
                           canPlay=(nextToPlay == user))
    # retrieving set of games we already have retrieved player stats for
    registered_games = set([pg['game_id'] for pg in player_game_stats])

    cnt = 0

    for game in games[:]:
        cnt += 1
        # skipping already processed games
        if game['game_id'] in registered_games:
            continue

        # retrieving shots for current game
        game_shots = list(
            filter(lambda d: d['game_id'] == game['game_id'], shots))

        print("+ Retrieving player stats for game %s" % get_game_info(game))
        single_player_game_stats = get_single_game_player_data(
            game, game_shots)
        player_game_stats.extend(single_player_game_stats)

        # collecting stat lines on a per-player basis
        for stat_line in single_player_game_stats:
            per_player_game_stats[(stat_line['player_id'],
                                   stat_line['team'])].append(stat_line)

        if limit and cnt >= limit:
            break

    # retrieving current timestamp to indicate last modification of dataset
    current_datetime = datetime.now().timestamp() * 1000
    output = [current_datetime, player_game_stats]
Exemplo n.º 4
0
def reconstruct_skater_situation(game, verbose=False):
    """
    Reconstruct skater on-ice situation for specified game.
    """
    print("+ Reconstructing on-ice skater situation for game %s" % get_game_info(game))

    # building interval tree to query goalies and player situations
    # receiving a list of times when goals has been scored
    it, goal_times = build_interval_tree(game)

    # retrieving all penalties
    all_penalties = list()
    for interval in it:
        if isinstance(interval.data, Penalty):
            penalty = interval.data
            all_penalties.append(penalty)

    # retrieving game end (in seconds) from interval tree
    game_end = - it.range().begin
    # retrieving goalies on ice and extra attackers for current game
    goalies_on_ice, extra_attackers = reconstruct_goalie_situation(it)

    # setting up dictionary to hold skater situations for each second of the game
    time_dict = dict()

    # setting up container to hold goalie/penalty intervals that have been
    # valid previously
    last_intervals = ''
    # setting up sets to hold a) penalties that effectively influence the
    # skater situation on ice, b) penalties that cancel each other out, c)
    # penalties that actually have started
    effective_penalties = set()
    cancelling_penalties = set()
    started_penalties = set()
    # initial setting for skater counts per team
    skr_count = {'home': 5, 'road': 5}

    # setting up skater situation at the beginning of the game
    time_dict[0] = {**skr_count, **goalies_on_ice[0]}

    for t in range(1, game_end + 1):
        # setting up containers holding the difference in skater/goalie numbers
        # in comparison to previous numbers produced by the currently
        # ongoing intervals
        curr_delta = {'home': 0, 'road': 0}
        curr_goalie_delta = {'home': 0, 'road': 0}
        # checking whether we're in the overtime of a regular season game and
        # adjusting skater counts accordingly
        in_ot = adjust_skater_count_in_overtime(game, t, skr_count)
        # adjusting skater counts according to the goaltenders currently on ice
        current_goalies = adjust_skater_counts_for_goalies(t, goalies_on_ice, curr_goalie_delta)

        if t in goal_times and verbose:
            print("- Goal: %d:%02d (%dv%d)" % (t // 60, t % 60, skr_count['home'], skr_count['road']))

        # retrieving all currently valid goalie and penalty intervals, i.e.
        # on-going goalie shifts and currently served penalties
        current_intervals = it[-t]
        current_penalties = defaultdict(list)

        # doing further processing for the current second of the game only
        # if currently valid intervals have changed from previous second of
        # the game
        if current_intervals != last_intervals:
            # if verbose:
            #     print("%d:%02d (%d) --> " % (t // 60, t % 60, t), end='')
            # retaining only penalty intervals
            penalty_intervals = list(filter(lambda item: (isinstance(item.data, Penalty)), current_intervals))
            # collecting currently on-going penalties by team
            for pi in sorted(penalty_intervals, key=lambda interval: interval.data.from_time):
                penalty = pi.data
                if penalty.duration in (120, 300):
                    if verbose:
                        print(
                            "- Penalty: %d:%02d" % (pi.end // -60, -pi.end % 60),
                            "%d:%02d" % (pi.begin // -60, -pi.begin % 60),
                            penalty.duration, penalty.team, penalty.infraction,
                            penalty.actual_duration, penalty.surname)
                    current_penalties[penalty.home_road].append(penalty)

            # collecting penalties that have been created at the current time
            penalties = list(filter(
                lambda penalty: penalty.create_time == (t - 1) and penalty.duration in (120, 300), all_penalties))
            # if no penalties have been created at the current time, collect
            # all penalties that have started at the current time
            if not penalties:
                penalties = list(filter(
                    lambda penalty: penalty.from_time == (t - 1) and penalty.duration in (120, 300), all_penalties))

            # sorting collected penalties by actual duration and start time
            penalties = sorted(penalties, key=lambda penalty: (penalty.actual_duration, penalty.from_time))
            # retrieving and sorting penalties taken by home team
            home_penalties = list(filter(lambda penalty: penalty.home_road == 'home', penalties))
            home_penalties = sorted(home_penalties, key=lambda penalty: (penalty.actual_duration, penalty.from_time))
            # retrieving and sorting penalties taken by road team
            road_penalties = list(filter(lambda penalty: penalty.home_road == 'road', penalties))
            road_penalties = sorted(road_penalties, key=lambda penalty: (penalty.actual_duration, penalty.from_time))
            # grouping minor and major penalties taken by home team
            home_min_penalties = list(filter(lambda penalty: penalty.duration == 120, home_penalties))
            home_maj_penalties = list(filter(lambda penalty: penalty.duration == 300, home_penalties))
            # grouping minor and major penalties taken by road team
            road_min_penalties = list(filter(lambda penalty: penalty.duration == 120, road_penalties))
            road_maj_penalties = list(filter(lambda penalty: penalty.duration == 300, road_penalties))
            # retrieving all teams taking penalties at current time
            penalty_teams = set([p.home_road for p in penalties])

            # continuing if no penalties have been created or started at
            # the current time of the game
            if not penalties:
                pass
            # if only one team has taken penalties
            elif len(penalty_teams) == 1:
                for penalty in penalties:
                    # skipping penalty if it hasn't already started
                    if penalty.from_time > t:
                        continue
                    # checking if current penalty has not started yet or has
                    # been cancelled by other penalties
                    if penalty not in started_penalties.union(cancelling_penalties):
                        team = penalty.home_road
                        # in overtime the other team gets another player
                        if in_ot:
                            curr_delta[switch_team(team)] += 1
                        # in regulation the current team loses a player
                        else:
                            curr_delta[team] -= 1
                        # adding current penalty to effective penalties
                        effective_penalties.add(penalty)
                    # adding current penalty to started penalties
                    started_penalties.add(penalty)
            # if both teams have taken penalties
            else:
                # registering major penalties that cancel each other out, i.e. if both teams received the same number
                # of major penalties at the current time
                if len(home_maj_penalties) == len(road_maj_penalties):
                    for penalty in home_maj_penalties:
                        cancelling_penalties.add(penalty)
                    for penalty in road_maj_penalties:
                        cancelling_penalties.add(penalty)
                elif len(home_maj_penalties) > len(road_maj_penalties):
                    pen_cnt_diff = len(home_maj_penalties) - len(road_maj_penalties)
                    pen_cnt = 0
                    for penalty in home_maj_penalties:
                        if pen_cnt < pen_cnt_diff:
                            # adjusting the number of skaters for corresponding
                            # team starting at current time
                            if penalty not in started_penalties.union(cancelling_penalties):
                                # in regular season overtime the other team usually gets an additional player
                                if in_ot:
                                    curr_delta['road'] += 1
                                else:
                                    curr_delta['home'] -= 1
                                pen_cnt += 1
                                effective_penalties.add(penalty)
                            started_penalties.add(penalty)
                        else:
                            started_penalties.add(penalty)
                            cancelling_penalties.add(penalty)
                    for penalty in road_maj_penalties:
                        started_penalties.add(penalty)
                        cancelling_penalties.add(penalty)
                elif len(home_maj_penalties) < len(road_maj_penalties):
                    pen_cnt_diff = len(road_maj_penalties) - len(home_maj_penalties)
                    pen_cnt = 0
                    for penalty in road_maj_penalties:
                        if pen_cnt < pen_cnt_diff:
                            # adjusting the number of skaters for corresponding
                            # team starting at current time
                            if penalty not in started_penalties.union(cancelling_penalties):
                                # in regular season overtime the other team usually gets an additional player
                                if in_ot:
                                    curr_delta['home'] += 1
                                else:
                                    curr_delta['road'] -= 1
                                pen_cnt += 1
                                effective_penalties.add(penalty)
                            started_penalties.add(penalty)
                        else:
                            started_penalties.add(penalty)
                            cancelling_penalties.add(penalty)
                    for penalty in home_maj_penalties:
                        started_penalties.add(penalty)
                        cancelling_penalties.add(penalty)

                # registering minor penalties that cancel each other out, i.e. if both teams received the same number
                # of major penalties at the current time
                if len(home_min_penalties) == len(road_min_penalties):
                    # if current skater situation is 5-on-5 and only one minor
                    # penalty was taken by each team we're going to 4-on-4 now
                    if (
                        len(home_min_penalties) == 1 and
                        len(road_min_penalties) == 1 and  # redundant
                        list(skr_count.values()) == [5, 5]
                    ):
                        for pens in [home_min_penalties, road_min_penalties]:
                            for penalty in pens:
                                team = penalty.home_road
                                if penalty not in started_penalties.union(cancelling_penalties):
                                    if in_ot:
                                        curr_delta[switch_team(team)] += 1
                                    else:
                                        curr_delta[team] -= 1
                                    effective_penalties.add(penalty)
                                started_penalties.add(penalty)
                    # otherwise all penalties are cancelling each other out
                    else:
                        for penalty in home_min_penalties:
                            cancelling_penalties.add(penalty)
                        for penalty in road_min_penalties:
                            cancelling_penalties.add(penalty)
                elif len(home_min_penalties) > len(road_min_penalties):
                    pen_cnt_diff = len(home_min_penalties) - len(road_min_penalties)
                    pen_cnt = 0
                    for penalty in home_min_penalties:
                        if pen_cnt < pen_cnt_diff:
                            # adjusting the number of skaters for corresponding
                            # team starting at current time
                            if penalty not in started_penalties.union(cancelling_penalties):
                                if in_ot:
                                    curr_delta['road'] += 1
                                else:
                                    curr_delta['home'] -= 1
                                pen_cnt += 1
                                effective_penalties.add(penalty)
                            started_penalties.add(penalty)
                        else:
                            started_penalties.add(penalty)
                            cancelling_penalties.add(penalty)
                    for penalty in road_min_penalties:
                        started_penalties.add(penalty)
                        cancelling_penalties.add(penalty)
                elif len(home_min_penalties) < len(road_min_penalties):
                    pen_cnt_diff = len(road_min_penalties) - len(home_min_penalties)
                    pen_cnt = 0
                    for penalty in road_min_penalties:
                        if pen_cnt < pen_cnt_diff:
                            # adjusting the number of skaters for corresponding
                            # team starting at current time
                            if penalty not in started_penalties.union(cancelling_penalties):
                                if in_ot:
                                    curr_delta['home'] += 1
                                else:
                                    curr_delta['road'] -= 1
                                pen_cnt += 1
                                effective_penalties.add(penalty)
                            started_penalties.add(penalty)
                        else:
                            started_penalties.add(penalty)
                            cancelling_penalties.add(penalty)
                    for penalty in home_min_penalties:
                        started_penalties.add(penalty)
                        cancelling_penalties.add(penalty)

            # handling expired penalties
            expired_penalties = set()
            for penalty in started_penalties:
                if t < penalty.from_time:
                    continue
                # checking whether penalty interval currently registered as
                # ongoing is in fact still ongoing
                if penalty not in current_penalties[penalty.home_road]:
                    expired_penalties.add(penalty)
                    if penalty in effective_penalties:
                        if in_ot:
                            # this turned out to be wrong, since it lead to
                            # skater counts below 3, but is it correct now?
                            # curr_delta[switch_team(penalty.home_road)] -= 1
                            curr_delta[penalty.home_road] += 1
                        else:
                            curr_delta[penalty.home_road] += 1
            # actually removing no longer on-going intervals
            effective_penalties.difference_update(expired_penalties)
            started_penalties.difference_update(expired_penalties)

            if verbose:
                print("%d:%02d (%d) --> " % (t // 60, t % 60, t), end='')

        # actually calculating current skater count from previous count
        # and deltas collected from all current intervals
        for key in skr_count:
            skr_count[key] = skr_count[key] + curr_delta[key] + curr_goalie_delta[key]
        # re-adjusting skater counts in overtime, e.g. after penalties have
        # expired
        adjust_skater_count_in_overtime(game, t, skr_count)

        # testing modified skater counts
        test_skater_counts(skr_count)

        if verbose:
            addendum = ''
            if any(extra_attackers[t].values()):
                addendum = '(with extra attacker)'
            if current_intervals != last_intervals:
                print("%dv%d %s" % (skr_count['home'], skr_count['road'], addendum))
            if t == 3601:
                print("--> %d:%02d (%d)" % (t // 60, t % 60, t))
                print("%dv%d %s" % (skr_count['home'], skr_count['road'], addendum))

        time_dict[t] = {**skr_count, **current_goalies}
        # saving currently valid intervals for comparison at next
        # second in the game
        last_intervals = current_intervals

    for t in time_dict:
        for key in ['home', 'road']:
            if time_dict[t][key] < 3:
                time_dict[t][key] = 3
            if time_dict[t][key] > 6:
                time_dict[t][key] = 6
            time_dict[t][game["%s_abbr" % key]] = time_dict[t][key]

    return time_dict, goal_times
Exemplo n.º 5
0
    args = parser.parse_args()

    season = args.season
    game_id = args.game_id

    # setting up path to source data file
    src_dir = os.path.join(CONFIG['tgt_processing_dir'], str(season))
    src_path = os.path.join(src_dir, GAME_SRC)

    # loading games
    games = json.loads(open(src_path).read())

    for game in games:
        if game_id and game['game_id'] != game_id:
            continue
        print(get_game_info(game))

        skr_sit, goal_times = reconstruct_skater_situation(game, True)

    # for x in skr_sit:
    #     print(x, skr_sit[x])
    # print()
    # sits = defaultdict(int)
    # goals = defaultdict(int)
    # prev_sit = (5, 5)

    # for x in skr_sit:
    #     curr_sit = (skr_sit[x]['home'], skr_sit[x]['road'])
    #     if curr_sit != prev_sit:
    #         sits[curr_sit] += 1
    #         print(x, skr_sit[x])
Exemplo n.º 6
0
if __name__ == "__main__":
    torch.backends.cudnn.benchmark = True
    args = parse_args()

    if not os.path.exists(args.save_dir):
        os.makedirs(args.save_dir)

    logger_path = os.path.join(args.save_dir, "train.log")
    sys.stdout = common_utils.Logger(logger_path)
    saver = common_utils.TopkSaver(args.save_dir, 10)

    common_utils.set_all_seeds(args.seed)
    pprint.pprint(vars(args))

    game_info = utils.get_game_info(args.num_player, args.greedy_extra)

    if args.method == "vdn":
        agent = vdn_r2d2.R2D2Agent(
            args.multi_step,
            args.gamma,
            0.9,
            args.train_device,
            game_info["input_dim"],
            args.rnn_hid_dim,
            game_info["num_action"],
        )
        agent_cls = vdn_r2d2.R2D2Agent
    elif args.method == "iql":
        agent = iql_r2d2.R2D2Agent(
            args.multi_step,
Exemplo n.º 7
0
    plr_status_dict = dict()
    for plr_game in player_game_stats:
        plr_status_dict[plr_game['player_id']] = plr_game['status']

    for game in games[:]:

        game_shots = list(
            filter(
                lambda d: d['game_id'] == game['game_id'] and d['target_type']
                == 'on_goal', shots))

        # skipping already processed games
        if game['game_id'] in registered_games:
            continue

        print("+ Retrieving goalie stats for game %s" % get_game_info(game))

        # retrieving goalies dressed from game item
        goalies_dressed = [
            (game['home_abbr'],
             game['home_g1'][0] if 'home_g1' in game else None),
            (game['home_abbr'],
             game['home_g2'][0] if 'home_g2' in game else None),
            (game['home_abbr'],
             game['home_g3'][0] if 'home_g3' in game else None),
            (game['road_abbr'],
             game['road_g1'][0] if 'road_g1' in game else None),
            (game['road_abbr'],
             game['road_g2'][0] if 'road_g2' in game else None),
            (game['road_abbr'],
             game['road_g3'][0] if 'road_g3' in game else None),
Exemplo n.º 8
0
    else:
        all_shots = list()

    all_pp_situations_goals = dict()

    # retrieving set of games we already have retrieved player stats for
    registered_games = set([shot['game_id'] for shot in all_shots])

    cnt = 0
    for game in games[:]:
        cnt += 1

        # skipping already processed games
        if game['game_id'] in registered_games:
            continue
        print("+ Retrieving shots for game %s " % get_game_info(game))

        # collecting skater situation for each second of the game and a list
        # of times when goals has been scored
        times, goal_times = reconstruct_skater_situation(game)
        game_type = get_game_type_from_season_type(game)

        # retrieving raw shot data
        shots_src_path = os.path.join(CONFIG['base_data_dir'], 'shots',
                                      str(game['season']), str(game_type),
                                      "%d.json" % game['game_id'])
        if not os.path.isfile(shots_src_path):
            print("+ Skipping game since shot data is unavailable")
            continue

        shifts_src_path = os.path.join(CONFIG['base_data_dir'], 'shifts',
def move():
    if "user" not in request.values or "game" not in request.values:
        TODO
    if "pos" not in request.values and "resign" not in request.values:
        TODO


    # connect to the database
    conn = open_db()


    game = int(request.values["game"])
    (players,size,state) = utils.get_game_info(conn, game)

    print("game_info:", (players,size,state))

    user = request.values["user"]
    if user not in players:
        TODO


    if "resign" in request.values:
        resign = True
    else:
        resign = False
        pos = request.values["pos"].split(",")
        assert len(pos) == 2
        x = int(pos[0])
        y = int(pos[1])


    (board,nextPlayer,letter) = utils.build_board(conn, game,size)

    if user != players[nextPlayer]:
        TODO


    if resign:
        # this user is choosing to resign.  Update the game state to reflect that.
        other_player_name = players[1-nextPlayer]

        cursor = conn.cursor()
        cursor.execute("""UPDATE games SET state=%s WHERE id=%s;""", (other_player_name+":resignation",game))
        cursor.close()

    else:
        assert x >= 0 and x < size
        assert y >= 0 and y < size

        assert board[x][y] == ""
        board[x][y] = "XO"[nextPlayer]

        # we've done all of our sanity checks.  We now know enough to say that
        # it's safe to add a new move.
        cursor = conn.cursor()
        cursor.execute("""INSERT INTO moves(gameID,x,y,letter,time) VALUES(%s,%s,%s,%s,NOW());""", (game,x,y,letter))

        if cursor.rowcount != 1:
            TODO

        cursor.close()

        result = utils.analyze_board(board)
        if result != "":
            if result == "win":
                result = players[nextPlayer]+":win"

            cursor = conn.cursor()
            cursor.execute("""UPDATE games SET state=%s WHERE id=%s;""", (result,game))
            cursor.close()

    # we've made changes, make sure to commit them!
    conn.commit()
    conn.close()


    # Redirect to a GET operation.  This is the POST/REDIRECT/GET pattern.
    return redirect("%s?game=%d&user=$s" % (url_for("game"), game, user),
                    code=303)
Exemplo n.º 10
0
    # loading existing player game stats
    if not initial and os.path.isfile(tgt_path):
        team_game_stats = json.loads(open(tgt_path).read())[-1]
    else:
        team_game_stats = list()

    # retrieving set of games we already have retrieved player stats for
    registered_games = set([pg['game_id'] for pg in team_game_stats])

    cnt = 0
    for game in games[:]:
        cnt += 1
        # skipping already processed games
        if game['game_id'] in registered_games:
            continue
        print("+ Retrieving team stats for game %s" % get_game_info(game))
        single_team_game_stats = get_single_game_team_data(
            game, grouped_shot_data,
            pp_sit_data.get(str(game['game_id']), dict()))

        # calculating days of rest between current and previous game for each team involved
        identify_days_rest_b2b_games(team_game_stats, single_team_game_stats)

        team_game_stats.extend(single_team_game_stats)

        if limit and cnt >= limit:
            break

    # retrieving current timestamp to indicate last modification of dataset
    current_datetime = datetime.now().timestamp() * 1000
    output = [current_datetime, team_game_stats]