From f75f8ac264e276dcace6a61015796190ade11d3c Mon Sep 17 00:00:00 2001 From: Tonlly Date: Thu, 23 Dec 2021 22:28:55 +0100 Subject: [PATCH 1/2] Refactor countdown, fix style I have also updated the Quadruple Agent url to the mandatory https. --- PredictTool/CompileGamestates.py | 79 +++++++++++++++--------------- PredictTool/GetReplayJSON.py | 19 ++++---- PredictTool/Predict_Tool.py | 1 - PredictTool/predict_live.py | 84 ++++++++++++++------------------ 4 files changed, 85 insertions(+), 98 deletions(-) diff --git a/PredictTool/CompileGamestates.py b/PredictTool/CompileGamestates.py index de68aba..8c811d2 100644 --- a/PredictTool/CompileGamestates.py +++ b/PredictTool/CompileGamestates.py @@ -3,10 +3,14 @@ import pandas as pd import numpy as np import os + + validvenues = ["Aquarium", "Balcony", "Ballroom", "Courtyard", "Gallery", "High-Rise", "Library", "Moderne", - "Pub", "Redwoods", "Teien", "Terrace", "Veranda"] + "Pub", "Redwoods", "Teien", "Terrace", "Veranda"] cast_list = ['Ambassador', 'SuspectedDoubleAgent', 'Toby', 'Damon', 'Double Agent'] balc_cast_list = ['Ambassador', 'SuspectedDoubleAgent', 'Toby', 'Damon'] + + def GetTimeline(file): timelineJSON = {'guest_count': None} try: @@ -21,12 +25,13 @@ def GetTimeline(file): print('failed to load game') print(file) timelineList = [] - if timelineJSON["guest_count"] != None: + if timelineJSON["guest_count"] is not None: valid = True for event in timelineJSON['timeline']: timelineList.append(event) return valid, timelineList, timelineJSON + def CompileGamestates(directory): count = 0 data_file = open('sparse_data_file.csv', 'a') @@ -34,7 +39,7 @@ def CompileGamestates(directory): for file in os.listdir(directory): filepath = directory + "/" + file valid, timelineList, timelineJSON = GetTimeline(filepath) - if valid == True: + if valid is True: guest_list = {} hl_count = 0 ll_count = 0 @@ -54,17 +59,17 @@ def CompileGamestates(directory): gamestateCurrent['venue'] = timelineJSON['venue'] gamestateCurrent['sniper'] = timelineJSON['sniper'] gamestateCurrent['spy'] = timelineJSON['spy'] - gamestateCurrent['guest_count'] = timelineJSON['guest_count'] + gamestateCurrent['guest_count'] = timelineJSON['guest_count'] gamestateCurrent['reqmissions'] = timelineJSON['game_type'][1] if timelineJSON['win_type'][1] == "SpyWin": gamestateCurrent['result'] = 1 elif timelineJSON['win_type'][1] == 'SniperWin': - gamestateCurrent['result'] = 0 + gamestateCurrent['result'] = 0 countdown_start = -1 bug_time = -1 da_time = -1 swap_time = -1 - purloin_time = -1 ###Initializes all the "time since" trackers; these variables will be updated to the timestamp a mission is completed at, or when countdown is triggered. + purloin_time = -1 # Initializes all the "time since" trackers; these variables will be updated to the timestamp a mission is completed at, or when countdown is triggered. fp_time = -1 inspect_time = -1 micro_time = -1 @@ -80,7 +85,6 @@ def CompileGamestates(directory): timeadd_time = -1 red_bb = -1 - gamestateList = [] for event in timelineList: gamestateStart = gamestateCurrent @@ -93,8 +97,7 @@ def CompileGamestates(directory): pass if category == 'Cast': Cast(event, guest_list) - - + for event in timelineList: gamestateStart = gamestateCurrent current_elapsed = event["elapsed_time"] @@ -142,12 +145,12 @@ def CompileGamestates(directory): pass if category == 'MissionSelected' or category == 'MissionEnabled': gamestateCurrent = MissionInitialize(event, gamestateCurrent, category) -## for x in range(int(prev_elapsed+1), int(current_elapsed), 5): -## gamestateCurrent['elapsed'] = x -## gamestateCurrent['spytime'] = int(prev_spytime + 1) - (x - int(prev_elapsed)) -## if gamestateCurrent['countdown'] == 1: -## gamestateCurrent['countdown_elapsed'] = x - countdown_start -## gamestateList.append(gamestateCurrent.copy()) +# for x in range(int(prev_elapsed+1), int(current_elapsed), 5): +# gamestateCurrent['elapsed'] = x +# gamestateCurrent['spytime'] = int(prev_spytime + 1) - (x - int(prev_elapsed)) +# if gamestateCurrent['countdown'] == 1: +# gamestateCurrent['countdown_elapsed'] = x - countdown_start +# gamestateList.append(gamestateCurrent.copy()) if mission == 'Fingerprint': gamestateCurrent, change_made, fp_time, print_time = FingerprintHandler(event, gamestateCurrent, fp_time, print_time) elif mission == 'Bug': @@ -178,7 +181,7 @@ def CompileGamestates(directory): if change_made == 1: gamestateCurrent['elapsed'] = event['elapsed_time'] gamestateCurrent['spytime'] = event['time'] - + gamestateList.append(gamestateCurrent.copy()) category = [] prev_elapsed = current_elapsed @@ -189,10 +192,6 @@ def CompileGamestates(directory): csv_writer.writerow(header) count += 1 csv_writer.writerow(x.values()) - - - - return @@ -200,7 +199,7 @@ def CompileGamestatesToDataframe(file): gamestateList = [] valid, timelineList, timelineJSON = GetTimeline(file) - if valid == True: + if valid is True: guest_list = {} hl_count = 0 ll_count = 0 @@ -246,7 +245,6 @@ def CompileGamestatesToDataframe(file): timeadd_time = -1 red_bb = -1 - for event in timelineList: change_made = 0 category = 0 @@ -254,8 +252,8 @@ def CompileGamestatesToDataframe(file): category3 = 0 mission = event['mission'] try: - category = event['category'][0] ###Create a guest list before running through other events; - except: ###done because sniper lights can sometimes occur before cast initializes + category = event['category'][0] ###Create a guest list before running through other events; + except: ###done because sniper lights can sometimes occur before cast initializes pass if category == 'Cast': Cast(event, guest_list) @@ -311,7 +309,7 @@ def CompileGamestatesToDataframe(file): category3 = event['category'][2] except: pass - for x in range(int(prev_elapsed+1), int(current_elapsed), 1): + for x in range(int(prev_elapsed+1), int(current_elapsed), 1): gamestateCurrent['elapsed'] = x gamestateCurrent['spytime'] = int(prev_spytime + 1) - (x - int(prev_elapsed)) ###Creates extra gamestate copies at set intervals between events for smoother gamestate structure over 1 game. for y in time_since_dict: ###Usually used for smoothing casting prediction values, using it for training causes overfitting @@ -354,7 +352,7 @@ def CompileGamestatesToDataframe(file): countdown_start = event['elapsed_time'] else: gamestateCurrent, change_made, gamestateList = HoldingHandler(event, gamestateCurrent, gamestateList) - + if change_made == 1: gamestateCurrent['elapsed'] = event['elapsed_time'] gamestateCurrent['spytime'] = event['time'] ###This is where we add a gamestate to the list if there's been a copy. @@ -367,7 +365,6 @@ def CompileGamestatesToDataframe(file): return gamestates - def CompileFinalGamestates(directory): gamestateList = [] for file in os.listdir(directory): @@ -419,7 +416,6 @@ def CompileFinalGamestates(directory): timeadd_time = -1 red_bb = -1 - for event in timelineList: change_made = 0 category = 0 @@ -427,8 +423,8 @@ def CompileFinalGamestates(directory): category3 = 0 mission = event['mission'] try: - category = event['category'][0] ###Create a guest list before running through other events; - except: ###done because sniper lights can sometimes occur before cast initializes + category = event['category'][0] ###Create a guest list before running through other events; + except: ###done because sniper lights can sometimes occur before cast initializes pass if category == 'Cast': Cast(event, guest_list) @@ -484,7 +480,7 @@ def CompileFinalGamestates(directory): category3 = event['category'][2] except: pass - for x in range(int(prev_elapsed+1), int(current_elapsed), 1): + for x in range(int(prev_elapsed+1), int(current_elapsed), 1): gamestateCurrent['elapsed'] = x gamestateCurrent['spytime'] = int(prev_spytime + 1) - (x - int(prev_elapsed)) ###Creates extra gamestate copies at set intervals between events for smoother gamestate structure over 1 game. for y in time_since_dict: ###Usually used for smoothing casting prediction values, using it for training causes overfitting @@ -527,7 +523,7 @@ def CompileFinalGamestates(directory): countdown_start = event['elapsed_time'] else: gamestateCurrent, change_made, gamestateList = HoldingHandler(event, gamestateCurrent, gamestateList) - + #if change_made == 1: #gamestateCurrent['elapsed'] = event['elapsed_time'] #gamestateCurrent['spytime'] = event['time'] ###This is where we add a gamestate to the list if there's been a copy. @@ -555,7 +551,7 @@ def TimeaddHandler(event, gamestate, timeadd_time): change_made = 0 gamestate['timeadd_count'] = timeadd_count gamestate['green_timeadds'] = green_timeadds - gamestate['red_timeadds'] = red_timeadds + gamestate['red_timeadds'] = red_timeadds return gamestate, change_made, timeadd_time def HoldingHandler(event, gamestate, gamestateList): @@ -598,6 +594,7 @@ def HoldingHandler(event, gamestate, gamestateList): gamestate['has_case'] = has_case gamestate['sips_count'] = sips return gamestate, change_made, gamestateList + def LocationHandler(event, gamestate): eventstring = event['event'] change_made = 1 @@ -618,6 +615,7 @@ def LocationHandler(event, gamestate): change_made = 0 gamestate['spy_loc'] = spy_loc return gamestate, change_made + def ContactHandler(event, gamestate, da_time, bb_time, red_bb): eventstring = event['event'] change_made = 1 @@ -645,7 +643,7 @@ def ContactHandler(event, gamestate, da_time, bb_time, red_bb): change_made = 0 gamestate['bb_count'] = bb_count gamestate['missions_da'] = contact_bool - gamestate['green_bbs'] = green_bbs + gamestate['green_bbs'] = green_bbs gamestate['coughs'] = coughs return gamestate, change_made, da_time, bb_time, red_bb @@ -669,6 +667,7 @@ def SwapHandler(event, gamestate, swap_time): gamestate['missions_swap'] = swap_bool gamestate['green_swap'] = green_swap return gamestate, change_made, swap_time + def PurloinHandler(event, gamestate, purloin_time, delegate_time): eventstring = event['event'] change_made = 1 @@ -731,6 +730,7 @@ def SeduceHandler(event, gamestate, seduce_time): gamestate['flirt_cd'] = seduce_cd gamestate['missions_seduce'] = seduce_bool return gamestate, change_made, seduce_time + def TransferHandler(event, gamestate, micro_time, MFanim_time): eventstring = event['event'] change_made = 1 @@ -751,6 +751,7 @@ def TransferHandler(event, gamestate, micro_time, MFanim_time): gamestate['micro_progress'] = micro_progress gamestate['missions_micro'] = micro_bool return gamestate, change_made, micro_time, MFanim_time + def InspectHandler(event, gamestate, inspect_time, statue_time): eventstring = event['event'] change_made = 1 @@ -768,6 +769,7 @@ def InspectHandler(event, gamestate, inspect_time, statue_time): gamestate['inspects'] = inspect_count gamestate['missions_inspect'] = inspect_bool return gamestate, change_made, inspect_time, statue_time + def BugHandler(event, gamestate, bug_time, bugattempt_time): eventstring = event['event'] change_made = 1 @@ -785,7 +787,6 @@ def BugHandler(event, gamestate, bug_time, bugattempt_time): gamestate['bugs_attempted'] = bug_attempts gamestate['missions_bug'] = bug_bool return gamestate, change_made, bug_time, bugattempt_time - def FingerprintHandler(event, gamestate, fp_time, print_time): eventstring = event['event'] @@ -825,10 +826,11 @@ def FingerprintHandler(event, gamestate, fp_time, print_time): gamestate['difficult_attempts'] = diff_attempts gamestate['difficults_succeeded'] = diffs_succeeded gamestate['book_prints'] = book_prints - gamestate['case_prints'] = case_prints + gamestate['case_prints'] = case_prints gamestate['drink_prints'] = drink_prints gamestate['statue_prints'] = statue_prints return gamestate, change_made, fp_time, print_time + def MissionInitialize(event, gamestate, category): missions_dict = {'Bug':['bug_avail', 'bug_selected'], 'Contact': ['da_avail', 'da_selected'], 'Swap': ['swap_avail', 'swap_selected'], 'Inspect':['inspect_avail', 'inspect_selected'], 'Seduce':['seduce_avail', 'seduce_selected'], 'Purloin':['purloin_avail', 'purloin_selected'], @@ -963,13 +965,10 @@ def SniperLights(event, guest_list, gamestate, light_time, spy_light_change): gamestate['light'] = spy_light return guest_list, gamestate, change_made, spy_light_change, light_time - def Cast(event, guest_list): if event["cast_name"][0] not in guest_list.keys(): guest_data = [event['role'][0], 1] guest_list[event['cast_name'][0]] = guest_data - - - + #CompileFinalGamestates('C:/Users/Aidan/Desktop/SpyPartyPredict/PAX_test_data/test_data') diff --git a/PredictTool/GetReplayJSON.py b/PredictTool/GetReplayJSON.py index a6a3e4a..1db5af6 100644 --- a/PredictTool/GetReplayJSON.py +++ b/PredictTool/GetReplayJSON.py @@ -2,15 +2,16 @@ import json import requests import os -def GetJSON(directory, json_directory): - url = 'http://www.spypartydebrief.com/quadruple_agent_json' + + +def GetJSON(directory, json_directory): + url = 'https://www.spypartydebrief.com/quadruple_agent_json' list_of_files = filter(lambda x: os.path.isfile(os.path.join(directory, x)), - os.listdir(directory)) - list_of_files = sorted( list_of_files, - key = lambda x: os.path.getmtime(os.path.join(directory, x)) - ) - iteration = 1 - for file in list_of_files: + os.listdir(directory)) + list_of_files = sorted(list_of_files, + key=lambda x: os.path.getmtime(os.path.join(directory, x)) + ) + for iteration, file in enumerate(list_of_files): filepath = directory / file print(file) upload_file = open(filepath, 'rb') @@ -28,5 +29,3 @@ def GetJSON(directory, json_directory): dumpfile = json_directory / ("game" + str(iteration)) with open(dumpfile, 'w') as outfile: json.dump(response_json, outfile) - iteration += 1 - diff --git a/PredictTool/Predict_Tool.py b/PredictTool/Predict_Tool.py index b8a8db1..da92abb 100644 --- a/PredictTool/Predict_Tool.py +++ b/PredictTool/Predict_Tool.py @@ -23,7 +23,6 @@ key=lambda x: os.path.getmtime(x) ) for file in list_of_files: - input() print(file.name) PredictLive(file) os.remove(file) diff --git a/PredictTool/predict_live.py b/PredictTool/predict_live.py index 2da9953..30c4774 100644 --- a/PredictTool/predict_live.py +++ b/PredictTool/predict_live.py @@ -5,40 +5,42 @@ CODE_FOLDER = Path(__file__).parent + def get_prediction(gamestate): with open(CODE_FOLDER / 'sp_predict.pkl', 'rb') as pickler: sp_predict = pickle.load(pickler) with open(CODE_FOLDER / 'predict_scaler.pkl', 'rb') as pickler: scaler = pickle.load(pickler) gamestate_data = gamestate[["bug_avail", "da_avail", "swap_avail", "inspect_avail", "seduce_avail", "purloin_avail", "fp_avail", - "micro_avail", "guest_count", "reqmissions", - "elapsed", "spytime", "lowlight", "neutral", "highlight", "flirt", "flirt_cd", "lowlights", - "highlights", "print_count", "difficult_attempts", "difficults_succeeded", "inspects", - "case_prints", "statue_prints", "drink_prints", "book_prints", - "bugs_attempted", "bb_count", "micro_progress", "green_purloin", "delegate_purloin", "green_swap", - "purloin_pend", "delegate_avail", "swap_pend", - "missions_bug", "missions_da", "missions_swap", "missions_inspect", "missions_seduce", "missions_purloin", - "missions_fp", "missions_micro", "conversation", "statue", "elsewhere", - "has_book", "has_drink", "sips_count", "has_case", "timeadd_count", "countdown", "countdown_elapsed", - "Aquarium", "Ballroom", "Courtyard", "Gallery", - "High-Rise", "Library", "Moderne", "Pub", "Redwoods", "Teien", "Terrace", "Veranda", - 'since_bug', 'since_da', 'since_swap', 'since_inspect', 'since_seduce', 'since_purloin', 'since_fp', - 'since_micro', 'since_bb', 'since_light', 'since_statue', 'since_MFanim', 'since_delegate', 'since_print', - 'since_bugattempt', 'since_timeadd', 'green_timeadds', 'red_timeadds', 'green_bbs', 'coughs']] + "micro_avail", "guest_count", "reqmissions", + "elapsed", "spytime", "lowlight", "neutral", "highlight", "flirt", "flirt_cd", "lowlights", + "highlights", "print_count", "difficult_attempts", "difficults_succeeded", "inspects", + "case_prints", "statue_prints", "drink_prints", "book_prints", + "bugs_attempted", "bb_count", "micro_progress", "green_purloin", "delegate_purloin", "green_swap", + "purloin_pend", "delegate_avail", "swap_pend", + "missions_bug", "missions_da", "missions_swap", "missions_inspect", "missions_seduce", "missions_purloin", + "missions_fp", "missions_micro", "conversation", "statue", "elsewhere", + "has_book", "has_drink", "sips_count", "has_case", "timeadd_count", "countdown", "countdown_elapsed", + "Aquarium", "Ballroom", "Courtyard", "Gallery", + "High-Rise", "Library", "Moderne", "Pub", "Redwoods", "Teien", "Terrace", "Veranda", + 'since_bug', 'since_da', 'since_swap', 'since_inspect', 'since_seduce', 'since_purloin', 'since_fp', + 'since_micro', 'since_bb', 'since_light', 'since_statue', 'since_MFanim', 'since_delegate', 'since_print', + 'since_bugattempt', 'since_timeadd', 'green_timeadds', 'red_timeadds', 'green_bbs', 'coughs']] gamestate_data_reshaped = gamestate_data.values.reshape(1, -1) gamestate_data = scaler.transform(gamestate_data_reshaped) return str(sp_predict.predict_proba(gamestate_data)), gamestate['elapsed'], gamestate['uuid'] + + def encode_missing_variables(gamestates): - encode_list = ['lowlight', 'highlight', 'neutral', "Aquarium", "Ballroom", "Courtyard", "Gallery", - "High-Rise", "Library", "Moderne", "Pub", "Redwoods", "Teien", "Terrace", "Veranda","conversation", "statue", "elsewhere"] + encode_list = ['lowlight', 'highlight', 'neutral', "Aquarium", "Ballroom", "Courtyard", "Gallery", + "High-Rise", "Library", "Moderne", "Pub", "Redwoods", "Teien", "Terrace", "Veranda","conversation", "statue", "elsewhere"] for x in encode_list: gamestates[x] = 0 gamestates.loc[gamestates['venue'] == x, x] = 1 gamestates.loc[gamestates['light'] == x, x] = 1 gamestates.loc[gamestates['spy_loc'] == x, x] = 1 return gamestates - def PredictLive(file): @@ -56,40 +58,28 @@ def PredictLive(file): for x in probability_dict: length = (len(probability_dict[x])) halflen = int((length + 1) / 2) - spywin = float(probability_dict[x][halflen : -1]) + spywin = float(probability_dict[x][halflen:-1]) spywin = spywin * 100 spywin = "{:.2f}".format(spywin) probability_dict[x] = spywin - input("Start game") + countdown() + start_time = time() - z = 0 - while z == 0: - if 1 < time() - start_time: - print("3") - z =1 - z = 0 - while z == 0: - if 2 < time() - start_time: - print("2") - z =1 - z = 0 - while z == 0: - if 3 < time() - start_time: - print("1") - z =1 - z = 0 - while z == 0: - if 4 < time() - start_time: - print("Playing it") - z =1 - start_time = time() - for x in probability_dict: - y = 0 - while y == 0: - gametime = time() - start_time - if x < gametime: - print("Spy win chance: " + probability_dict[x] + "%.") - y = 1 + for timestamp in probability_dict: + while timestamp > time() - start_time: + pass + print(f"Spy win chance: {probability_dict[timestamp]}%.") + +def countdown(): + start_time = time() + for wait_till in range(1, 5): + while wait_till > time() - start_time: + pass + if wait_till <= 3: + display_number = 4 - wait_till + print(display_number) + else: + print("Playing it") From 7b0ea9535fd6bcc12ecb9d8919c6524d3173a280 Mon Sep 17 00:00:00 2001 From: Tonlly Date: Fri, 24 Dec 2021 09:17:49 +0100 Subject: [PATCH 2/2] Expand README.md --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a539df6..714bc71 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ -Install the project using pip - all requirements are list in requirements.txt - -Go to the directory containing the project - +# Installation +Install the dependencies using pip – they are all listed in *requirements.txt*. +Go to the directory containing the project and run: `pip3 install -r requirements.txt` +## How to use +Initial run of **Predict_Tool.py** creates a folder *PredictTool/Replays Folder*. Copy your SpyParty replay files in there and run Predict_Tool.py again.