class TestNormalFormGame_Asym2p: """Test the methods of NormalFormGame with asymmetric two players""" def setUp(self): """Setup a NormalFormGame instance""" self.BoS_bimatrix = np.array([[(3, 2), (1, 1)], [(0, 0), (2, 3)]]) self.g = NormalFormGame(self.BoS_bimatrix) def test_getitem(self): action_profile = (1, 0) assert_array_equal(self.g[action_profile], self.BoS_bimatrix[action_profile]) def test_delete_action(self): action_to_delete = 0 for i, player in enumerate(self.g.players): g_new = self.g.delete_action(i, action_to_delete) actions_to_remain = \ np.setdiff1d(np.arange(player.num_actions), action_to_delete) assert_array_equal( g_new.payoff_profile_array, self.g.payoff_profile_array.take(actions_to_remain, axis=i)) def test_is_nash_pure(self): ok_(not self.g.is_nash((1, 0))) def test_is_nash_mixed(self): ok_(self.g.is_nash(([3 / 4, 1 / 4], [1 / 4, 3 / 4]))) def test_payoff_arrays(self): assert_array_equal(self.g.payoff_arrays[0], self.BoS_bimatrix[:, :, 0]) assert_array_equal(self.g.payoff_arrays[1], self.BoS_bimatrix[:, :, 1].T)
class TestNormalFormGame_1p: """Test for trivial NormalFormGame with a single player""" def setUp(self): """Setup a NormalFormGame instance""" data = [[0], [1], [1]] self.g = NormalFormGame(data) def test_construction(self): """Trivial game: construction""" ok_(self.g.N == 1) assert_array_equal(self.g.players[0].payoff_array, [0, 1, 1]) def test_getitem(self): """Trivial game: __getitem__""" eq_(self.g[0], 0) def test_is_nash_pure(self): """Trivial game: is_nash with pure action""" ok_(self.g.is_nash((1,))) ok_(not self.g.is_nash((0,))) def test_is_nash_mixed(self): """Trivial game: is_nash with mixed action""" ok_(self.g.is_nash(([0, 1 / 2, 1 / 2],)))
def test_normalformgame_constant_payoffs(): g = NormalFormGame((2, 2)) ok_(g.is_nash((0, 0))) ok_(g.is_nash((0, 1))) ok_(g.is_nash((1, 0))) ok_(g.is_nash((1, 1)))
class TestNormalFormGame_1p: """Test for trivial NormalFormGame with a single player""" def setUp(self): """Setup a NormalFormGame instance""" data = [[0], [1], [1]] self.g = NormalFormGame(data) def test_construction(self): """Trivial game: construction""" ok_(self.g.N == 1) assert_array_equal(self.g.players[0].payoff_array, [0, 1, 1]) def test_getitem(self): """Trivial game: __getitem__""" eq_(self.g[0], 0) def test_delete_action(self): actions_to_delete = [1, 2] for i, player in enumerate(self.g.players): g_new = self.g.delete_action(i, actions_to_delete) actions_to_remain = \ np.setdiff1d(np.arange(player.num_actions), actions_to_delete) assert_array_equal( g_new.payoff_profile_array, self.g.payoff_profile_array.take(actions_to_remain, axis=i)) def test_is_nash_pure(self): """Trivial game: is_nash with pure action""" ok_(self.g.is_nash((1, ))) ok_(not self.g.is_nash((0, ))) def test_is_nash_mixed(self): """Trivial game: is_nash with mixed action""" ok_(self.g.is_nash(([0, 1 / 2, 1 / 2], )))
class TestNormalFormGame_3p: """Test the methods of NormalFormGame with three players""" def setUp(self): """Setup a NormalFormGame instance""" payoffs_2opponents = [[[3, 6], [4, 2]], [[1, 0], [5, 7]]] player = Player(payoffs_2opponents) self.g = NormalFormGame([player for i in range(3)]) def test_getitem(self): assert_array_equal(self.g[0, 0, 1], [6, 4, 1]) def test_delete_action(self): action_to_delete = 0 for i, player in enumerate(self.g.players): g_new = self.g.delete_action(i, action_to_delete) actions_to_remain = \ np.setdiff1d(np.arange(player.num_actions), action_to_delete) assert_array_equal( g_new.payoff_profile_array, self.g.payoff_profile_array.take(actions_to_remain, axis=i) ) def test_is_nash_pure(self): ok_(self.g.is_nash((0, 0, 0))) ok_(not self.g.is_nash((0, 0, 1))) def test_is_nash_mixed(self): p = (1 + np.sqrt(65)) / 16 ok_(self.g.is_nash(([1 - p, p], [1 - p, p], [1 - p, p])))
class TestNormalFormGame_3p: """Test the methods of NormalFormGame with three players""" def setUp(self): """Setup a NormalFormGame instance""" payoffs_2opponents = [[[3, 6], [4, 2]], [[1, 0], [5, 7]]] player = Player(payoffs_2opponents) self.g = NormalFormGame([player for i in range(3)]) def test_getitem(self): assert_array_equal(self.g[0, 0, 1], [6, 4, 1]) def test_delete_action(self): action_to_delete = 0 for i, player in enumerate(self.g.players): g_new = self.g.delete_action(i, action_to_delete) actions_to_remain = \ np.setdiff1d(np.arange(player.num_actions), action_to_delete) assert_array_equal( g_new.payoff_profile_array, self.g.payoff_profile_array.take(actions_to_remain, axis=i)) def test_is_nash_pure(self): ok_(self.g.is_nash((0, 0, 0))) ok_(not self.g.is_nash((0, 0, 1))) def test_is_nash_mixed(self): p = (1 + np.sqrt(65)) / 16 ok_(self.g.is_nash(([1 - p, p], [1 - p, p], [1 - p, p])))
class TestNormalFormGame_1p: """Test for trivial NormalFormGame with a single player""" def setUp(self): """Setup a NormalFormGame instance""" data = [[0], [1], [1]] self.g = NormalFormGame(data) def test_construction(self): """Trivial game: construction""" ok_(self.g.N == 1) assert_array_equal(self.g.players[0].payoff_array, [0, 1, 1]) def test_getitem(self): """Trivial game: __getitem__""" eq_(self.g[0], 0) def test_is_nash_pure(self): """Trivial game: is_nash with pure action""" ok_(self.g.is_nash((1,))) ok_(not self.g.is_nash((0,))) def test_is_nash_mixed(self): """Trivial game: is_nash with mixed action""" ok_(self.g.is_nash(([0, 1/2, 1/2],)))
class TestNormalFormGame_Asym2p: """Test the methods of NormalFormGame with asymmetric two players""" def setUp(self): """Setup a NormalFormGame instance""" self.BoS_bimatrix = np.array([[(3, 2), (1, 1)], [(0, 0), (2, 3)]]) self.g = NormalFormGame(self.BoS_bimatrix) def test_getitem(self): action_profile = (1, 0) assert_array_equal(self.g[action_profile], self.BoS_bimatrix[action_profile]) def test_is_nash_pure(self): ok_(not self.g.is_nash((1, 0))) def test_is_nash_mixed(self): ok_(self.g.is_nash(([3/4, 1/4], [1/4, 3/4]))) def test_payoff_arrays(self): assert_array_equal( self.g.payoff_arrays[0], self.BoS_bimatrix[:, :, 0] ) assert_array_equal( self.g.payoff_arrays[1], self.BoS_bimatrix[:, :, 1].T )
class TestNormalFormGame_Sym2p: """Test the methods of NormalFormGame with symmetric two players""" def setUp(self): """Setup a NormalFormGame instance""" coordination_game_matrix = [[4, 0], [3, 2]] self.g = NormalFormGame(coordination_game_matrix) def test_getitem(self): assert_array_equal(self.g[0, 1], [0, 3]) def test_is_nash_pure(self): ok_(self.g.is_nash((0, 0))) def test_is_nash_mixed(self): ok_(self.g.is_nash(([2 / 3, 1 / 3], [2 / 3, 1 / 3])))
class TestNormalFormGame_Asym2p: """Test the methods of NormalFormGame with asymmetric two players""" def setUp(self): """Setup a NormalFormGame instance""" matching_pennies_bimatrix = [[(1, -1), (-1, 1)], [(-1, 1), (1, -1)]] self.g = NormalFormGame(matching_pennies_bimatrix) def test_getitem(self): assert_array_equal(self.g[1, 0], [-1, 1]) def test_is_nash_against_pure(self): ok_(not self.g.is_nash((0, 0))) def test_is_nash_against_mixed(self): ok_(self.g.is_nash(([1 / 2, 1 / 2], [1 / 2, 1 / 2])))
class TestNormalFormGame_3p: """Test the methods of NormalFormGame with three players""" def setUp(self): """Setup a NormalFormGame instance""" payoffs_2opponents = [[[3, 6], [4, 2]], [[1, 0], [5, 7]]] player = Player(payoffs_2opponents) self.g = NormalFormGame([player for i in range(3)]) def test_getitem(self): assert_array_equal(self.g[0, 0, 1], [6, 4, 1]) def test_is_nash_pure(self): ok_(self.g.is_nash((0, 0, 0))) ok_(not self.g.is_nash((0, 0, 1))) def test_is_nash_mixed(self): p = (1 + np.sqrt(65)) / 16 ok_(self.g.is_nash(([1 - p, p], [1 - p, p], [1 - p, p])))
class TestNormalFormGame_Asym2p: """Test the methods of NormalFormGame with asymmetric two players""" def setUp(self): """Setup a NormalFormGame instance""" self.BoS_bimatrix = np.array([[(3, 2), (1, 1)], [(0, 0), (2, 3)]]) self.g = NormalFormGame(self.BoS_bimatrix) def test_getitem(self): action_profile = (1, 0) assert_array_equal(self.g[action_profile], self.BoS_bimatrix[action_profile]) def test_delete_action(self): action_to_delete = 0 for i, player in enumerate(self.g.players): g_new = self.g.delete_action(i, action_to_delete) actions_to_remain = \ np.setdiff1d(np.arange(player.num_actions), action_to_delete) assert_array_equal( g_new.payoff_profile_array, self.g.payoff_profile_array.take(actions_to_remain, axis=i) ) def test_is_nash_pure(self): ok_(not self.g.is_nash((1, 0))) def test_is_nash_mixed(self): ok_(self.g.is_nash(([3/4, 1/4], [1/4, 3/4]))) def test_payoff_arrays(self): assert_array_equal( self.g.payoff_arrays[0], self.BoS_bimatrix[:, :, 0] ) assert_array_equal( self.g.payoff_arrays[1], self.BoS_bimatrix[:, :, 1].T )
def test_random_matrix(self): seed = 12345 rng = np.random.default_rng(seed) size = (10, 15) A = rng.normal(size=size) v, x, y = minmax(A) for z in [x, y]: assert_((z >= 0).all()) assert_allclose(z.sum(), 1) g = NormalFormGame((Player(A), Player(-A.T))) NE = lemke_howson(g) assert_allclose(v, NE[0] @ A @ NE[1]) assert_(g.is_nash((x, y)))
class TestNormalFormGame_1p: """Test for trivial NormalFormGame with a single player""" def setUp(self): """Setup a NormalFormGame instance""" data = [[0], [1], [1]] self.g = NormalFormGame(data) def test_construction(self): """Trivial game: construction""" ok_(self.g.N == 1) assert_array_equal(self.g.players[0].payoff_array, [0, 1, 1]) def test_getitem(self): """Trivial game: __getitem__""" eq_(self.g[0], 0) def test_delete_action(self): actions_to_delete = [1, 2] for i, player in enumerate(self.g.players): g_new = self.g.delete_action(i, actions_to_delete) actions_to_remain = \ np.setdiff1d(np.arange(player.num_actions), actions_to_delete) assert_array_equal( g_new.payoff_profile_array, self.g.payoff_profile_array.take(actions_to_remain, axis=i) ) def test_is_nash_pure(self): """Trivial game: is_nash with pure action""" ok_(self.g.is_nash((1,))) ok_(not self.g.is_nash((0,))) def test_is_nash_mixed(self): """Trivial game: is_nash with mixed action""" ok_(self.g.is_nash(([0, 1/2, 1/2],)))