def test_random_matgame_hash_eq(strats): """Test hash and eq""" payoffs = rand.random(tuple(strats) + (len(strats),)) matg = matgame.matgame(payoffs) copy = matgame.matgame_copy(matg) assert hash(copy) == hash(matg) assert copy == matg game = paygame.game_copy(matg) copy = matgame.matgame_copy(game) assert hash(copy) == hash(matg) assert copy == matg
def test_random_matgame_hash_eq(strats): """Test hash and eq""" payoffs = rand.random(tuple(strats) + (len(strats), )) matg = matgame.matgame(payoffs) copy = matgame.matgame_copy(matg) assert hash(copy) == hash(matg) assert copy == matg game = paygame.game_copy(matg) copy = matgame.matgame_copy(game) assert hash(copy) == hash(matg) assert copy == matg
def dump(game, filelike): """Dump game to gambit file""" utils.check(game.is_complete(), 'gambit games must be complete') game = matgame.matgame_copy(game) filelike.write('NFG 1 R "gameanalysis game"\n{ ') for role in game.role_names: filelike.write('"') filelike.write(role.replace('"', '\\"')) filelike.write('" ') filelike.write('}\n{\n') for strats in game.strat_names: filelike.write(' { ') for strat in strats: filelike.write('"') filelike.write(strat.replace('"', '\\"')) filelike.write('" ') filelike.write('}\n') filelike.write('}\n\n{\n') perm = tuple(range(game.num_roles - 1, -1, -1)) + (game.num_roles, ) pays = np.transpose(game.payoff_matrix(), perm) for outcome in pays.reshape((-1, game.num_roles)): filelike.write(' { "" ') filelike.write(', '.join(map(str, outcome))) filelike.write(' }\n') filelike.write('}\n1') for i in range(2, game.num_profiles + 1): filelike.write(' ') filelike.write(str(i))
def test_serialize_copy_role_lengths(): """Test role lengths""" game = full_game(['a', 'b'], [1, 1], [['1', '2'], ['3', '4', '5']]) matg = matgame.matgame_copy(game) expected = matgame.matgame_names(['a', 'b'], [['1', '2'], ['3', '4', '5']], np.zeros((2, 3, 2))) assert utils.is_sorted(matg.role_names) assert matg == expected game = full_game(['a', 'b'], [2, 1], [['1', '2'], ['3', '4', '5']]) matg = matgame.matgame_copy(game) expected = matgame.matgame_names(['ap0', 'ap1', 'bp0'], [['1', '2'], ['1', '2'], ['3', '4', '5']], np.zeros((2, 2, 3, 3))) assert utils.is_sorted(matg.role_names) assert matg == expected
def dump(game, filelike): """Dump game to gambit file""" utils.check(game.is_complete(), 'gambit games must be complete') game = matgame.matgame_copy(game) filelike.write('NFG 1 R "gameanalysis game"\n{ ') for role in game.role_names: filelike.write('"') filelike.write(role.replace('"', '\\"')) filelike.write('" ') filelike.write('}\n{\n') for strats in game.strat_names: filelike.write(' { ') for strat in strats: filelike.write('"') filelike.write(strat.replace('"', '\\"')) filelike.write('" ') filelike.write('}\n') filelike.write('}\n\n{\n') perm = tuple(range(game.num_roles - 1, -1, -1)) + (game.num_roles,) pays = np.transpose(game.payoff_matrix(), perm) for outcome in pays.reshape((-1, game.num_roles)): filelike.write(' { "" ') filelike.write(', '.join(map(str, outcome))) filelike.write(' }\n') filelike.write('}\n1') for i in range(2, game.num_profiles + 1): filelike.write(' ') filelike.write(str(i))
def polymatrix_game( num_players, num_strats, matrix_game=independent_game, players_per_matrix=2): """Creates a polymatrix game Each player's payoff in each profile is a sum over independent games played against each set of opponents. Each k-tuple of players plays an instance of the specified random k-player matrix game. Parameters ---------- num_players : int The number of players. num_strats : int The number of strategies per player. matrix_game : (players_per_matrix, num_strats) -> Game, optional A function to generate games between sub groups of players. players_per_matrix : int, optional The number of players that interact simultaneously. Notes ----- The actual roles and strategies of matrix game are ignored. """ payoffs = np.zeros([num_strats] * num_players + [num_players]) for players in itertools.combinations(range(num_players), players_per_matrix): sub_payoffs = matgame.matgame_copy(matrix_game( [num_strats] * players_per_matrix)).payoff_matrix() new_shape = np.array([1] * num_players + [players_per_matrix]) new_shape[list(players)] = num_strats payoffs[..., list(players)] += sub_payoffs.reshape(new_shape) return matgame.matgame(payoffs)
def test_conv_game_gambit_inv(game, game_str): """Test game to gambit and back""" with stdin(game_str), stdout() as out, stderr() as err: assert run('conv', 'gambit'), err.getvalue() with stdin(out.getvalue()), stdout() as out, stderr() as err: assert run('conv', 'game'), err.getvalue() copy = gamereader.loads(out.getvalue()) assert copy == paygame.game_copy(matgame.matgame_copy(game))
def test_serialize_copy_role_lengths(): """Test role lengths""" game = full_game( ['a', 'b'], [1, 1], [['1', '2'], ['3', '4', '5']]) matg = matgame.matgame_copy(game) expected = matgame.matgame_names( ['a', 'b'], [['1', '2'], ['3', '4', '5']], np.zeros((2, 3, 2))) assert utils.is_sorted(matg.role_names) assert matg == expected game = full_game( ['a', 'b'], [2, 1], [['1', '2'], ['3', '4', '5']]) matg = matgame.matgame_copy(game) expected = matgame.matgame_names( ['ap0', 'ap1', 'bp0'], [['1', '2'], ['1', '2'], ['3', '4', '5']], np.zeros((2, 2, 3, 3))) assert utils.is_sorted(matg.role_names) assert matg == expected
def test_serialize_copy_role_lengths_natural(): """Test natural role lengths""" game = full_game(['q', 'qq'], [2, 1], [['1', '2'], ['3', '4', '5']]) matg = matgame.matgame_copy(game) expected = matgame.matgame_names(['qp0', 'qp1', 'qqp0'], [['1', '2'], ['1', '2'], ['3', '4', '5']], np.zeros((2, 2, 3, 3))) assert utils.is_sorted(matg.role_names) assert matg == expected
def test_random_serialize_copy_role_lengths(_): """Test serialization copy""" num_roles = random.randint(2, 3) roles = random_names(num_roles) strats = tuple( random_names(random.randint(2, 3)) for _ in range(num_roles)) players = [random.randint(1, 3) for _ in range(num_roles)] game = full_game(roles, players, strats) matg = matgame.matgame_copy(game) assert utils.is_sorted(matg.role_names)
def test_random_serialize_copy_role_lengths(_): """Test serialization copy""" num_roles = random.randint(2, 3) roles = random_names(num_roles) strats = tuple(random_names(random.randint(2, 3)) for _ in range(num_roles)) players = [random.randint(1, 3) for _ in range(num_roles)] game = full_game(roles, players, strats) matg = matgame.matgame_copy(game) assert utils.is_sorted(matg.role_names)
def test_serialize_copy_role_lengths_natural(): """Test natural role lengths""" game = full_game( ['q', 'qq'], [2, 1], [['1', '2'], ['3', '4', '5']]) matg = matgame.matgame_copy(game) expected = matgame.matgame_names( ['qp0', 'qp1', 'qqp0'], [['1', '2'], ['1', '2'], ['3', '4', '5']], np.zeros((2, 2, 3, 3))) assert utils.is_sorted(matg.role_names) assert matg == expected
def test_random_matgame_copy(players, strats): """Test copy""" game = gamegen.game(players, strats) matg = matgame.matgame_copy(game) inds = np.cumsum(game.num_role_players[:-1] * game.num_role_strats[:-1]) mprofs = matg.random_profiles(20) mpays = matg.get_payoffs(mprofs) mpays = np.concatenate( [m.reshape(20, p, -1).mean(1).filled(0) for m, p in zip(np.split(np.ma.masked_array(mpays, mprofs == 0), inds, 1), game.num_role_players)], 1) profs = np.concatenate( [m.reshape(20, p, -1).sum(1) for m, p in zip(np.split(mprofs, inds, 1), game.num_role_players)], 1) pays = game.get_payoffs(profs) assert np.allclose(mpays, pays)
def test_random_matgame_copy(players, strats): """Test copy""" game = gamegen.game(players, strats) matg = matgame.matgame_copy(game) inds = np.cumsum(game.num_role_players[:-1] * game.num_role_strats[:-1]) mprofs = matg.random_profiles(20) mpays = matg.get_payoffs(mprofs) mpays = np.concatenate([ m.reshape(20, p, -1).mean(1).filled(0) for m, p in zip( np.split(np.ma.masked_array(mpays, mprofs == 0), inds, 1), game.num_role_players) ], 1) profs = np.concatenate([ m.reshape(20, p, -1).sum(1) for m, p in zip(np.split(mprofs, inds, 1), game.num_role_players) ], 1) pays = game.get_payoffs(profs) assert np.allclose(mpays, pays)
def test_random_identity_test(players, strats, _): """Test that dumping and loading is identity""" game = matgame.matgame_copy(gamegen.game(players, strats)) string = gambit.dumps(game) copy = gambit.loads(string) assert game == copy
lambda game, out: json.dump( paygame.game_copy(game).to_json(), out)), 'samplegame': ( ['samp'], 'Multiple payoffs per profile', """Convert a game to a format with a sparse mapping of profiles to potentially several samples of payoff data. There should be little reason to convert a non-samplegame to a samplegame as all profiles will have exactly one sample.""", lambda game, out: json.dump( paygame.samplegame_copy(game).to_json(), out)), 'matgame': ( ['mat'], 'Asymmetric format', """Convert a game to a compact representation for asymmetric games. If the input game is not asymmetric, role names will be duplicated and modified to allow for the conversion. This will only work if the input game is complete.""", lambda game, out: json.dump( matgame.matgame_copy(game).to_json(), out)), 'norm': ( [], 'Normalize payoffs to [0, 1]', """Modify the input game by scaling all payoffs to the range [0, 1]. In the rare event that a single role always gets the same payoffs, it's payoffs will be made zero. The game type is unchanged. This doesn't guarantee that the maximum and minimum payoffs are one and zero respectively, only that they're in the range.""", lambda game, out: json.dump(game.normalize().to_json(), out)), 'string': ( ['str'], 'String representation', """Convert a game to its string representation. This form is more human readable than the full serialization formats and may be more useful for 'inspecting' a game.""", lambda game, out: out.write(str(game))), 'gambit': (
([], 'Sparse payoff format', """Convert a game to a sparse mapping of profiles to their corresponding payoff data.""", lambda game, out: json.dump(paygame.game_copy(game).to_json(), out)), 'samplegame': (['samp'], 'Multiple payoffs per profile', """Convert a game to a format with a sparse mapping of profiles to potentially several samples of payoff data. There should be little reason to convert a non-samplegame to a samplegame as all profiles will have exactly one sample.""", lambda game, out: json.dump(paygame.samplegame_copy(game).to_json(), out) ), 'matgame': (['mat'], 'Asymmetric format', """Convert a game to a compact representation for asymmetric games. If the input game is not asymmetric, role names will be duplicated and modified to allow for the conversion. This will only work if the input game is complete.""", lambda game, out: json.dump(matgame.matgame_copy(game).to_json(), out)), 'norm': ([], 'Normalize payoffs to [0, 1]', """Modify the input game by scaling all payoffs to the range [0, 1]. In the rare event that a single role always gets the same payoffs, it's payoffs will be made zero. The game type is unchanged. This doesn't guarantee that the maximum and minimum payoffs are one and zero respectively, only that they're in the range.""", lambda game, out: json.dump(game.normalize().to_json(), out)), 'string': (['str'], 'String representation', """Convert a game to its string representation. This form is more human readable than the full serialization formats and may be more useful for 'inspecting' a game.""", lambda game, out: out.write(str(game))), 'gambit': ([], 'Gambit format', """Convert a game to gambit 'nfg' format. Internally this first converts the game to a 'matgame', and as a