def rbfgame_json(json): """Read an rbf game from json""" utils.check(json['type'].split('.', 1)[0] == 'rbf', 'incorrect type') base = rsgame.empty_json(json) offsets = base.payoff_from_json(json['offsets']) coefs = base.payoff_from_json(json['coefs']) lengths = np.empty((base.num_strats,) * 2) for role, strats in json['lengths'].items(): for strat, pay in strats.items(): ind = base.role_strat_index(role, strat) base.payoff_from_json(pay, lengths[ind]) profiles = [None] * base.num_strats for role, strats in json['profiles'].items(): for strat, profs in strats.items(): ind = base.role_strat_index(role, strat) profiles[ind] = np.stack([ base.profile_from_json(p, verify=False) for p in profs]) alphas = [None] * base.num_strats for role, strats in json['alphas'].items(): for strat, alph in strats.items(): ind = base.role_strat_index(role, strat) alphas[ind] = np.array(alph) sizes = np.fromiter( # pragma: no branch (a.size for a in alphas), int, base.num_strats) return _RbfGpGame( base.role_names, base.strat_names, base.num_role_players, offsets, coefs, lengths, sizes, np.concatenate(profiles), np.concatenate(alphas))
async def aopen(self): # pylint: disable=too-many-locals """Open the eosched""" gu.check(not self._is_open, "already open") try: game = await self._api.get_game(self._game_id) obs = await game.get_observations() gu.check( rsgame.empty_copy(self._game) == rsgame.empty_json(obs), "egtaonline game didn't match specified game", ) conf = dict(obs.get("configuration", ()) or ()) profiles = obs.get("profiles", ()) or () # Parse profiles num_profs = len(profiles) num_pays = 0 for jprof in profiles: pid = jprof["id"] prof, spays = self._game.profsamplepay_from_json(jprof) spays.setflags(write=False) hprof = gu.hash_array(prof) pays = asyncio.Queue() num_spays = len(spays) num_pays += num_spays for pay in spays: pays.put_nowait(pay) data = ([num_spays], [num_spays], [0], [pid], pays) self._profiles[hprof] = data self._prof_ids[pid] = data logging.info( "found %d existing profiles with %d payoffs in game %d", num_profs, num_pays, self._game_id, ) # Create and start scheduler self._sched = await obs.create_generic_scheduler( "egta_" + eu.random_string(20), True, self._obs_memory, self._obs_time, self._simult_obs, 1, conf, ) logging.warning( "created scheduler %d for running simulations of game %d: " "https://%s/generic_schedulers/%d", self._sched["id"], self._game_id, self._api.domain, self._sched["id"], ) self._fetcher = asyncio.ensure_future(self._fetch()) self._is_open = True except Exception as ex: await self.aclose() raise ex return self
def rbfgame_json(json): """Read an rbf game from json""" utils.check(json['type'].split('.', 1)[0] == 'rbf', 'incorrect type') base = rsgame.empty_json(json) offsets = base.payoff_from_json(json['offsets']) coefs = base.payoff_from_json(json['coefs']) lengths = np.empty((base.num_strats, ) * 2) for role, strats in json['lengths'].items(): for strat, pay in strats.items(): ind = base.role_strat_index(role, strat) base.payoff_from_json(pay, lengths[ind]) profiles = [None] * base.num_strats for role, strats in json['profiles'].items(): for strat, profs in strats.items(): ind = base.role_strat_index(role, strat) profiles[ind] = np.stack( [base.profile_from_json(p, verify=False) for p in profs]) alphas = [None] * base.num_strats for role, strats in json['alphas'].items(): for strat, alph in strats.items(): ind = base.role_strat_index(role, strat) alphas[ind] = np.array(alph) sizes = np.fromiter( # pragma: no branch (a.size for a in alphas), int, base.num_strats) return _RbfGpGame(base.role_names, base.strat_names, base.num_role_players, offsets, coefs, lengths, sizes, np.concatenate(profiles), np.concatenate(alphas))
def aggfn_json(json): # pylint: disable=too-many-locals """Read an Aggfn from json Json versions of the game will generally have 'type': 'aggfn...' in them, but as long as the proper fields exist, this will succeed.""" base = rsgame.empty_json(json) _, version = json.get('type', '.3').split('.', 1) utils.check(version == '3', 'parsing versions below 3 is currently unsupported') num_functions = len(json['function_tables']) function_inputs = np.empty((base.num_strats, num_functions), bool) action_weights = np.empty((num_functions, base.num_strats)) function_table = np.empty((num_functions, ) + tuple(base.num_role_players + 1)) offsets = np.empty(base.num_strats) base.payoff_from_json(json.get('offsets', {}), offsets) for inps, jinps in zip(function_inputs.T, json['function_inputs']): base.restriction_from_json(jinps, inps, verify=False) for weights, jweights in zip(action_weights, json['action_weights']): base.payoff_from_json(jweights, weights) function_table.fill(0) for table, jtable in zip(function_table, json['function_tables']): for elem in jtable: copy = elem.copy() value = copy.pop('value') table[tuple(int(i) for i in base.role_from_json(copy))] = value return aggfn_replace(base, action_weights, function_inputs, function_table, offsets)
def matgame_json(json): """Read a matrix game from json In general, the json will have 'type': 'matrix...' to indicate that it's a matrix game, but if the other fields are correct, this will still succeed. """ # This uses the fact that roles are always in lexicographic order base = rsgame.empty_json(json) matrix = np.empty(tuple(base.num_role_strats) + (base.num_roles,), float) _mat_from_json(base, json['payoffs'], matrix, 0) return matgame_replace(base, matrix)
def loadj(obj): # pylint: disable=too-many-branches,too-many-return-statements """Read a game from serializable python objects Parameters ---------- json : {...} The python object representation of a game encoded as json. Any valid game will be read and returned. """ game_type, _ = obj.get('type', 'samplegame.').split('.', 1) if game_type == 'add': from gameanalysis import rsgame return rsgame.add_json(obj) elif game_type == 'aggfn': from gameanalysis import aggfn return aggfn.aggfn_json(obj) elif game_type == 'canon': from gameanalysis import canongame return canongame.canon_json(obj) elif game_type == 'const': from gameanalysis import rsgame return rsgame.const_json(obj) elif game_type == 'empty' or game_type == 'emptygame': from gameanalysis import rsgame return rsgame.empty_json(obj) elif game_type == 'game': from gameanalysis import paygame return paygame.game_json(obj) elif game_type == 'matrix': from gameanalysis import matgame return matgame.matgame_json(obj) elif game_type == 'neighbor': from gameanalysis import learning return learning.neighbor_json(obj) elif game_type == 'point': from gameanalysis import learning return learning.point_json(obj) elif game_type == 'rbf': from gameanalysis import learning return learning.rbfgame_json(obj) elif game_type == 'sample': from gameanalysis import learning return learning.sample_json(obj) elif game_type == 'samplegame': from gameanalysis import paygame return paygame.samplegame_json(obj) else: raise ValueError('unknown game type {}'.format(game_type))
async def create_scheduler( # pylint: disable=too-many-arguments game, mem, time, auth=None, count=1, sleep=600, # pylint: disable-msg=redefined-builtin max=100): """Create an egtaonline scheduler""" game_id = int(game) mem = int(mem) time = int(time) count = int(count) sleep = float(sleep) max_sims = int(max) async with api.api(auth_token=auth) as egta: game = await egta.get_game(game_id) summ = await game.get_summary() game = rsgame.empty_json(summ) return ApiWrapper(game, egta, game_id, sleep, count, max_sims, mem, time)
def fix_game(jgame): """Fixture for a standard game""" # XXX This line exists to fool duplication check return rsgame.empty_json(jgame)
def fix_game(jgame): """Fixture a game""" return rsgame.empty_json(jgame)