import os from misc import unique_combinations, FULL_GAME_DIR import pickle from jobs import ALL_JOBS from random import randint import game # cannot 'import from' because of mutual recursion # THE filename that the gamedata will be stored under GAME_DATA_FILE = os.getcwd() + "/" + 'game_data/game.metadata' # FIX: This should be a singleton class class GameData: def __init__(self): # *_peon_jobs: mafia+necro -> total number of peons with jobs: mafia and necro # # Extra conditions: # controlled = peons controlled by the owning player # uncontrolled = peons not controlled by the owning player (many many more) self.mafiaheavy_controlled_peon_jobs = {} self.mafiaheavy_uncontrolled_peon_jobs = {} self.mafialight_controlled_peon_jobs = {} self.mafialight_uncontrolled_peon_jobs = {} # Keep total number of each type of job around as well # This is stored in each dictionary is a special key self.total_key = 'total' # Used to separate multiple jobs in dict keys self.delimiter = '+' # Init values: all combinations of jobs for comb in unique_combinations(ALL_JOBS): key = self.getkey(comb) for dict in self.get_all_dicts(): dict[key] = 0 # Init the totals to zero for dict in self.get_all_dicts(): dict[self.total_key] = 0 # Returns a random pairing of jobs based on occurance levels in the other games def rand_job_pairing(self, mafia_is_light, peon_is_controlled): dict = self.choose_dict(mafia_is_light, peon_is_controlled) index = randint(0, dict[self.total_key] - 1) sum = 0 # Go through each combination of jobs # If the index is between the running sum and the # of hits for that # combinations of jobs, choose that combination of jobs for comb in unique_combinations(ALL_JOBS): sum += dict[self.getkey(comb)] if sum > index: return comb # Compile all the results from all the games def compile(self): # Get all the games game_names = [file for file in os.listdir(FULL_GAME_DIR) \ if os.path.isfile("%s/%s" % (FULL_GAME_DIR, file))] for game_name in game_names: my_game = game.load_game(game_name) mafia_is_light = my_game.mafia_is_light() for player in my_game.players: for peon in player.peons: if peon.jobs == []: continue self.add_to_chosen_dict(mafia_is_light, \ (peon.name == player.name), \ self.getkey(peon.jobs)) # -- Util functions for dicts -- # def add_to_chosen_dict(self, mafia_is_light, peon_is_controlled, key, value = 1): dict = self.choose_dict(mafia_is_light, peon_is_controlled) dict[key] += value dict[self.total_key] += value def choose_dict(self, mafia_is_light, peon_is_controlled): if mafia_is_light: if peon_is_controlled: return self.mafialight_controlled_peon_jobs else: return self.mafialight_uncontrolled_peon_jobs else: if peon_is_controlled: return self.mafiaheavy_controlled_peon_jobs else: return self.mafiaheavy_uncontrolled_peon_jobs def print_all_dicts(self): for dict in self.get_all_dicts(): keys = dict.keys() keys.sort() for key in keys: print "%s - %s" % (key, dict[key]) print "\n" print "----------------------------\n" def get_all_dicts(self): return [self.mafialight_controlled_peon_jobs, self.mafialight_uncontrolled_peon_jobs, \ self.mafiaheavy_controlled_peon_jobs, self.mafiaheavy_uncontrolled_peon_jobs] def getkey(self, job_combination): job_combination.sort() return self.delimiter.join(job_combination) def save(self): try: f = open(GAME_DATA_FILE, 'w') pickle.dump(self, f) except: my_error('saving the gamedata', 'Could not save gamedata to "%s"' % GAME_DATA_FILE) f.close() # Non-class functions def update_game_data(): gamedata = GameData() gamedata.compile() gamedata.save() def load_game_data(): try: f = open(GAME_DATA_FILE, 'r') game_data = pickle.load(f) except: # Odds are the game data isn't precomputed, so compute it and read it in #f.close() try: os.unlink(GAME_DATA_FILE) except: pass update_game_data() return load_game_data() # could be infinite recursive badness return game_data ## DEBUG #gd = load_game_data() #gd.print_all_dicts() #ml = 1 #c = 0 #dict = gd.choose_dict(ml,c) # #keys = dict.keys() #keys.sort() #for key in keys: # print "%s - %s" % (key, dict[key]) #print "\n" # #for i in xrange(20): # print gd.rand_job_pairing(ml,c)