From 5dc3574b4dcf19474356e5f5d5355b37779a2145 Mon Sep 17 00:00:00 2001 From: Rahul Savani Date: Thu, 30 Nov 2023 19:22:58 +0000 Subject: [PATCH 1/2] cleaned up tests for normalize, payoff, and strategy_value --- src/pygambit/tests/test_mixed.py | 834 ++++++++++++++----------------- 1 file changed, 366 insertions(+), 468 deletions(-) diff --git a/src/pygambit/tests/test_mixed.py b/src/pygambit/tests/test_mixed.py index ca043f108..1631e03dd 100644 --- a/src/pygambit/tests/test_mixed.py +++ b/src/pygambit/tests/test_mixed.py @@ -14,116 +14,86 @@ def _create_strategic_game() -> gbt.Game: game.players["Dan"].strategies[1].label = "defect" return game +def _create_coordination_4x4_nfg() -> gbt.Game: + return gbt.Game.read_game("test_games/coordination_4x4.nfg") -def test_normalize(): - # Test the normalize function of a mixed strategy profile - - game = gbt.Game.read_game("test_games/coordination_4x4.nfg") - - # rational: try to normalize an "all-zero" input - all_zero_rat = [gbt.Rational(0), gbt.Rational(0), gbt.Rational(0), gbt.Rational(0)] - legit_rat = [ - gbt.Rational(1, 1), - gbt.Rational(1, 1), - gbt.Rational(0, 1), - gbt.Rational(1, 1), - ] - unnorm1 = game.mixed_strategy_profile(rational=True, data=[all_zero_rat, legit_rat]) - with pytest.raises(ValueError, match=r'zero'): - unnorm1.normalize() - unnorm2 = game.mixed_strategy_profile(rational=True, data=[legit_rat, all_zero_rat]) +@pytest.mark.parametrize( + "profile", + [ + (_create_coordination_4x4_nfg().mixed_strategy_profile( + rational=True, + data=[[gbt.Rational(0), gbt.Rational(0), gbt.Rational(0), gbt.Rational(0)], + [gbt.Rational(1, 3), gbt.Rational(1, 3), gbt.Rational(1, 3), gbt.Rational(0)]])), + (_create_coordination_4x4_nfg().mixed_strategy_profile( + rational=True, + data=[[gbt.Rational(1), gbt.Rational(0), gbt.Rational(0), gbt.Rational(0)], + [gbt.Rational(0), gbt.Rational(0), gbt.Rational(0), gbt.Rational(0)]])), + (_create_coordination_4x4_nfg().mixed_strategy_profile( + rational=False, + data=[[0, 0, 0, 0], + [1.0, 1.0, 1.0, 1.0]])), + (_create_coordination_4x4_nfg().mixed_strategy_profile( + rational=False, + data=[[1.0, 1.0, 1.0, 1.0], + [0, 0, 0, 0]])), + ], +) +def test_normalize_zero_value_error(profile): with pytest.raises(ValueError, match=r'zero'): - unnorm2.normalize() + profile.normalize() - all_zero_doub = [0, 0, 0, 0] - legit_doub = [1, 1, 0, 1] - # double: try to normalize an "all-zero" input - unnorm1 = game.mixed_strategy_profile( - rational=False, data=[all_zero_doub, legit_doub] - ) - with pytest.raises(ValueError, match=r'zero'): - unnorm1.normalize() - unnorm2 = game.mixed_strategy_profile( - rational=False, data=[legit_doub, all_zero_doub] - ) - with pytest.raises(ValueError, match=r'zero'): - unnorm2.normalize() - - # rational: try to normalize input with a negative entry - neg_entry_rat = [ - gbt.Rational(1), - gbt.Rational(1), - gbt.Rational(0), - gbt.Rational(-1), - ] - unnorm1 = game.mixed_strategy_profile( - rational=True, data=[neg_entry_rat, legit_rat] - ) - with pytest.raises(ValueError, match=r'negative'): - unnorm1.normalize() - unnorm2 = game.mixed_strategy_profile( - rational=True, data=[legit_rat, neg_entry_rat] - ) +@pytest.mark.parametrize( + "profile", + [ + (_create_coordination_4x4_nfg().mixed_strategy_profile( + rational=True, + data=[[gbt.Rational(1), gbt.Rational(1), gbt.Rational(0), gbt.Rational(-1)], + [gbt.Rational(1, 3), gbt.Rational(1, 3), gbt.Rational(1, 3), gbt.Rational(0)]])), + (_create_coordination_4x4_nfg().mixed_strategy_profile( + rational=True, + data=[[gbt.Rational(1), gbt.Rational(0), gbt.Rational(0), gbt.Rational(0)], + [gbt.Rational(1), gbt.Rational(1), gbt.Rational(0), gbt.Rational(-1)]])), + (_create_coordination_4x4_nfg().mixed_strategy_profile( + rational=False, + data=[[0, 0, 0, -1.0], + [1.0, 1.0, 1.0, 1.0]])), + (_create_coordination_4x4_nfg().mixed_strategy_profile( + rational=False, + data=[[1.0, 1.0, 1.0, 1.0], + [0, 0, 0, -1.0]])), + ], +) +def test_normalize_neg_entry_value_error(profile): with pytest.raises(ValueError, match=r'negative'): - unnorm2.normalize() + profile.normalize() - # double: try to normalize input with a negative entry - neg_entry_doub = [1.0, 1.0, 0.0, -1.0] - unnorm1 = game.mixed_strategy_profile( - rational=False, data=[neg_entry_doub, legit_doub] - ) - with pytest.raises(ValueError, match=r'negative'): - unnorm1.normalize() - unnorm2 = game.mixed_strategy_profile( - rational=False, data=[legit_doub, neg_entry_doub] - ) - with pytest.raises(ValueError, match=r'negative'): - unnorm2.normalize() - - # now normalize a legitimate input - legit_rat2 = [ - gbt.Rational(1, 1), - gbt.Rational(2, 1), - gbt.Rational(3, 1), - gbt.Rational(14, 1), - ] - all_one_rat = [ - gbt.Rational(1, 1), - gbt.Rational(1, 1), - gbt.Rational(1, 1), - gbt.Rational(1, 1), - ] - unnorm = game.mixed_strategy_profile(rational=True, data=[legit_rat2, all_one_rat]) - p1 = game.players[0] - p2 = game.players[1] - norm = unnorm.normalize() - assert unnorm[p1] == [1, 2, 3, 14] - assert norm[p1] == [ - gbt.Rational(1, 20), - gbt.Rational(2, 20), - gbt.Rational(3, 20), - gbt.Rational(14, 20), - ] - uniform4_rat = [ - gbt.Rational(1, 4), - gbt.Rational(1, 4), - gbt.Rational(1, 4), - gbt.Rational(1, 4), - ] - assert unnorm[p2] == all_one_rat - assert norm[p2] == uniform4_rat - legit_doub2 = [1.0, 2.0, 3.0, 14.0] - all_one_doub = [1, 1, 1, 1] - unnorm = game.mixed_strategy_profile(rational=False, data=[legit_rat2, all_one_rat]) +@pytest.mark.parametrize( + "profile,expect", + [ + (_create_coordination_4x4_nfg().mixed_strategy_profile( + rational=True, + data=[ + [gbt.Rational(1, 1), gbt.Rational(2, 1), gbt.Rational(3, 1), gbt.Rational(14, 1)], + [gbt.Rational(1), gbt.Rational(1), gbt.Rational(1), gbt.Rational(1)]]), + ([gbt.Rational(1, 20), gbt.Rational(2, 20), gbt.Rational(3, 20), gbt.Rational(14, 20)], + [gbt.Rational(1, 4), gbt.Rational(1, 4), gbt.Rational(1, 4), gbt.Rational(1, 4)])), + (_create_coordination_4x4_nfg().mixed_strategy_profile( + rational=False, + data=[[1.0, 2.0, 3.0, 14.0], [1, 1, 1, 1]]), + ([1 / 20, 2 / 20, 3 / 20, 14 / 20], + [0.25, 0.25, 0.25, 0.25])), + ], +) +def test_normalize(profile, expect): + """Test the normalize function of a mixed strategy profile""" + game = profile.game + norm = profile.normalize() p1 = game.players[0] p2 = game.players[1] - norm = unnorm.normalize() - assert unnorm[p1] == legit_doub2 - assert norm[p1] == [1 / 20, 2 / 20, 3 / 20, 14 / 20] - assert unnorm[p2] == all_one_doub - assert norm[p2] == [0.25, 0.25, 0.25, 0.25] + assert norm[p1] == expect[0] + assert norm[p2] == expect[1] def test_get_probabilities_strategy(): @@ -164,59 +134,28 @@ def test_set_probability_player(): assert profile[game.players[0]] == [gbt.Rational("7/9"), gbt.Rational("2/9")] -def test_payoffs(): - """Test payoffs are 0 in a game initialized with default payoffs""" - game = _create_strategic_game() - assert game.mixed_strategy_profile(rational=False).payoff(game.players[0]) == 0 - assert game.mixed_strategy_profile(rational=True).payoff(game.players[0]) == 0 - - -def test_payoffs_coordination(): - """Test payoffs in a coordination bimatrix game""" - game = gbt.Game.read_game("test_games/coordination_4x4.nfg") - uniform4 = game.mixed_strategy_profile() - for s in game.players[0].strategies: - assert uniform4.strategy_value(s) == 0.25 - for p in game.players: - assert uniform4.payoff(p) == 0.25 - uniform3 = game.mixed_strategy_profile( - rational=True, - data=[ - [ - gbt.Rational(1, 3), - gbt.Rational(1, 3), - gbt.Rational(1, 3), - gbt.Rational(0), - ], - [ - gbt.Rational(1, 3), - gbt.Rational(1, 3), - gbt.Rational(1, 3), - gbt.Rational(0), - ], - ], - ) - for p in game.players: - assert uniform3.payoff(p) == gbt.Rational(1, 3) - uniform3_nonsym = game.mixed_strategy_profile( - rational=True, - data=[ - [ - gbt.Rational(1, 3), - gbt.Rational(1, 3), - gbt.Rational(0), - gbt.Rational(1, 3), - ], - [ - gbt.Rational(1, 3), - gbt.Rational(1, 3), - gbt.Rational(1, 3), - gbt.Rational(0), - ], - ], - ) - for p in game.players: - assert uniform3_nonsym.payoff(p) == gbt.Rational(2, 9) +@pytest.mark.parametrize( + "profile,payoffs", + [ + (_create_strategic_game().mixed_strategy_profile(rational=False), (0, 0)), + (_create_strategic_game().mixed_strategy_profile(rational=True), (0, 0)), + (_create_coordination_4x4_nfg().mixed_strategy_profile(), (0.25, 0.25)), + (_create_coordination_4x4_nfg().mixed_strategy_profile( + rational=True, + data=[[gbt.Rational(1, 3), gbt.Rational(1, 3), gbt.Rational(1, 3), gbt.Rational(0)], + [gbt.Rational(1, 3), gbt.Rational(1, 3), gbt.Rational(1, 3), gbt.Rational(0)]]), + (gbt.Rational(1, 3), gbt.Rational(1, 3))), + (_create_coordination_4x4_nfg().mixed_strategy_profile( + rational=True, + data=[[gbt.Rational(1, 3), gbt.Rational(1, 3), gbt.Rational(0), gbt.Rational(1, 3)], + [gbt.Rational(1, 3), gbt.Rational(1, 3), gbt.Rational(1, 3), gbt.Rational(0)]]), + (gbt.Rational(2, 9), gbt.Rational(2, 9))), + ], +) +def test_payoffs(profile, payoffs): + """Hard-wired tests for MixedStrategyProfile.payoff""" + for payoff, player in zip(payoffs, profile.game.players): + assert profile.payoff(player) == payoff def test_payoffs_by_label(): @@ -225,32 +164,8 @@ def test_payoffs_by_label(): assert game.mixed_strategy_profile(rational=True).payoff("Joe") == 0 -def test_strategy_value(): - game = _create_strategic_game() - strategy = game.players[0].strategies[1] - assert game.mixed_strategy_profile(rational=False).strategy_value(strategy) == 0 - assert game.mixed_strategy_profile(rational=True).strategy_value(strategy) == 0 - - def test_strategy_value_coordination(): game = gbt.Game.read_game("test_games/coordination_4x4.nfg") - uniform4 = game.mixed_strategy_profile() - uniform4_rat = game.mixed_strategy_profile(rational=True) - strategy = game.players[0].strategies[1] - assert uniform4.strategy_value(strategy) == 1 / 4 - assert uniform4_rat.strategy_value(strategy) == 1 / 4 - mixed_strat = game.mixed_strategy_profile( - rational=True, - data=[ - [gbt.Rational(3, 7), gbt.Rational(0), gbt.Rational(0), gbt.Rational(4, 7)], - [ - gbt.Rational(1, 3), - gbt.Rational(1, 3), - gbt.Rational(1, 3), - gbt.Rational(0), - ], - ], - ) assert mixed_strat.strategy_value(game.players[1].strategies[0]) == gbt.Rational( 3, 7 ) @@ -267,143 +182,31 @@ def test_strategy_value_coordination(): @pytest.mark.parametrize( - "bimatrices", + "profile,strategy_values", [ - (np.array([[1, 0], [0, 1]]), np.array([[7, 0], [0, 3]])), - (np.array([[1, 0, -1], [0, 1, 3]]), np.array([[7, 0, 1], [0, 3, -1]])), - (np.array([[1, 9, -1], [12, 1, 3]]), np.array([[7, 9, 1], [4, 3, -1]])), + (_create_strategic_game().mixed_strategy_profile(rational=False), ([0,0],[0,0])), + (_create_strategic_game().mixed_strategy_profile(rational=True), ([0,0],[0,0])), + (_create_coordination_4x4_nfg().mixed_strategy_profile(), + ([0.25, 0.25, 0.25, 0.25],[0.25, 0.25, 0.25, 0.25])), + (_create_coordination_4x4_nfg().mixed_strategy_profile( + rational=True, + data=[[gbt.Rational(1), gbt.Rational(0), gbt.Rational(0), gbt.Rational(0)], + [gbt.Rational(1), gbt.Rational(0), gbt.Rational(0), gbt.Rational(0)]]), + ([gbt.Rational(1), gbt.Rational(0), gbt.Rational(0), gbt.Rational(0)], + [gbt.Rational(1), gbt.Rational(0), gbt.Rational(0), gbt.Rational(0)])), + (_create_coordination_4x4_nfg().mixed_strategy_profile( + rational=True, + data=[[gbt.Rational(3, 7), gbt.Rational(0), gbt.Rational(0), gbt.Rational(4, 7)], + [gbt.Rational(1, 3), gbt.Rational(1, 3), gbt.Rational(1, 3), gbt.Rational(0)]]), + ([gbt.Rational(1, 3), gbt.Rational(1, 3), gbt.Rational(1, 3), gbt.Rational(0)], + [gbt.Rational(3, 7), gbt.Rational(0), gbt.Rational(0), gbt.Rational(4, 7)])), ], ) -def test_payoff_and_strat_value_bimatrices(bimatrices): - """Test payoff and strategy_value functions for pure, support size 2, and uniform complete - mixtures for games specified as pairs of numpy arrays - """ - game = gbt.Game.from_arrays(bimatrices[0], bimatrices[1]) - m = len(game.players[0].strategies) - n = len(game.players[1].strategies) - - # test that payoff gives back entries for pure strategy profiles - for i, j in product(range(m), range(n)): - pure_i = [1 if k == i else 0 for k in range(m)] - pure_j = [1 if L == j else 0 for L in range(n)] - mixed_strat = game.mixed_strategy_profile(rational=True, data=[pure_i, pure_j]) - # stategy_value - for k in range(m): - assert ( - mixed_strat.strategy_value(game.players[0].strategies[k]) - == bimatrices[0][k, j] - ) - for L in range(n): - assert ( - mixed_strat.strategy_value(game.players[1].strategies[L]) - == bimatrices[1][i, L] - ) - # payoff - assert mixed_strat.payoff(game.players[0]) == bimatrices[0][i, j] - assert mixed_strat.payoff(game.players[1]) == bimatrices[1][i, j] - - # test with mixed profiles of support size 2 - for supp1, supp2 in product(combinations(range(m), 2), combinations(range(n), 2)): - strat1 = [gbt.Rational(1, 2) if k in supp1 else 0 for k in range(m)] - strat2 = [gbt.Rational(1, 2) if L in supp2 else 0 for L in range(n)] - mixed_strat = game.mixed_strategy_profile(rational=True, data=[strat1, strat2]) - # strategy value - expect1 = gbt.Rational(1, 2) * bimatrices[0][0, supp2[0]] - expect1 += gbt.Rational(1, 2) * bimatrices[0][0, supp2[1]] - assert mixed_strat.strategy_value(game.players[0].strategies[0]) == expect1 - - expect2 = gbt.Rational(1, 2) * bimatrices[1][supp1[0], 0] - expect2 += gbt.Rational(1, 2) * bimatrices[1][supp1[1], 0] - assert mixed_strat.strategy_value(game.players[1].strategies[0]) == expect2 - - # payoff - expect1 = 0 - for s in supp1: - expect1 += gbt.Rational(1, 4) * bimatrices[0][s, supp2[0]] - expect1 += gbt.Rational(1, 4) * bimatrices[0][s, supp2[1]] - assert mixed_strat.payoff(game.players[0]) == expect1 - - expect2 = 0 - for s in supp2: - expect2 += gbt.Rational(1, 4) * bimatrices[1][supp1[0], s] - expect2 += gbt.Rational(1, 4) * bimatrices[1][supp1[1], s] - assert mixed_strat.payoff(game.players[1]) == expect2 - - # test with uniform full support mixed profiles - uniform = game.mixed_strategy_profile(rational=True) - # strategy_value - for k in range(m): - expect = sum([gbt.Rational(1, n) * bimatrices[0][k, L] for L in range(n)]) - assert uniform.strategy_value(game.players[0].strategies[k]) == expect - for L in range(n): - expect = sum([gbt.Rational(1, m) * bimatrices[1][k, L] for k in range(m)]) - assert uniform.strategy_value(game.players[1].strategies[L]) == expect - # payoff - expect1 = 0 - expect2 = 0 - for i in range(m): - for j in range(n): - expect1 += bimatrices[0][i, j] - expect2 += bimatrices[1][i, j] - expect1 *= gbt.Rational(1, m * n) - expect2 *= gbt.Rational(1, m * n) - assert uniform.payoff(game.players[0]) == expect1 - assert uniform.payoff(game.players[1]) == expect2 - - -@pytest.mark.parametrize( - "bimatrices", - [ - (np.array([[1, 0], [0, 1]]), np.array([[7, 0], [0, 3]])), - (np.array([[1, 0, -1], [0, 1, 3]]), np.array([[7, 0, 1], [0, 3, -1]])), - (np.array([[1, 9, -1], [12, 1, 3]]), np.array([[7, 9, 1], [4, 3, -1]])), - ], -) -def test_lv_bimatrix(bimatrices): - """Test liap values using short alternative code for its computation in bimatrix games""" - - game = gbt.Game.from_arrays(bimatrices[0], bimatrices[1]) - m = len(game.players[0].strategies) - n = len(game.players[1].strategies) - - def compute_liap(): - expect = 0 - payoff1 = mixed_strat.payoff(game.players[0]) - payoff2 = mixed_strat.payoff(game.players[1]) - for k in range(m): - row_payoff = sum( - [gbt.Rational(strat2[L]) * bimatrices[0][k, L] for L in range(n)] - ) - expect += max(row_payoff - payoff1, 0) ** 2 - for L in range(n): - col_payoff = sum( - [gbt.Rational(strat1[k]) * bimatrices[1][k, L] for k in range(m)] - ) - expect += max(col_payoff - payoff2, 0) ** 2 - return expect - - # test for all pure strategies - for i, j in product(range(m), range(n)): - strat1 = [1 if k == i else 0 for k in range(m)] - strat2 = [1 if L == j else 0 for L in range(n)] - mixed_strat = game.mixed_strategy_profile(rational=True, data=[strat1, strat2]) - expect = compute_liap() - assert expect == mixed_strat.liap_value() - - # test for all uniform mixtures on supports of size 2 - for supp1, supp2 in product(combinations(range(m), 2), combinations(range(n), 2)): - strat1 = [gbt.Rational(1, 2) if k in supp1 else 0 for k in range(m)] - strat2 = [gbt.Rational(1, 2) if L in supp2 else 0 for L in range(n)] - mixed_strat = game.mixed_strategy_profile(rational=True, data=[strat1, strat2]) - expect = compute_liap() - assert expect == mixed_strat.liap_value() - - # test for all uniform completely mixed profile - strat1 = [gbt.Rational(1, m) for k in range(m)] - strat2 = [gbt.Rational(1, n) for L in range(n)] - mixed_strat = game.mixed_strategy_profile(rational=True) - expect = compute_liap() - assert expect == mixed_strat.liap_value() +def test_strategy_values(profile, strategy_values): + """Hard-wired tests for MixedStrategyProfile.payoff""" + for strategy_values_for_player, player in zip(strategy_values, profile.game.players): + for i, s in enumerate(player.strategies): + assert profile.strategy_value(s) == strategy_values_for_player[i] def test_strategy_regret(): @@ -447,82 +250,70 @@ def test_as_behavior_error(): _ = game.mixed_strategy_profile(rational=True).as_behavior() -settings = [ - (gbt.Game.read_game("test_games/Cl_BLotto_game.nfg"), - [[gbt.Rational(1, 10), gbt.Rational(4, 10), gbt.Rational(0, 1), - gbt.Rational(1, 8), gbt.Rational(3, 8)], - [gbt.Rational(3, 5), gbt.Rational(0, 5), - gbt.Rational(0, 5), gbt.Rational(2, 5)]], - [[gbt.Rational(2, 10), gbt.Rational(1, 10), gbt.Rational(2, 5), - gbt.Rational(1, 10), gbt.Rational(2, 10)], - [gbt.Rational(3, 5), gbt.Rational(0, 5), - gbt.Rational(0, 5), gbt.Rational(2, 5)]]), - - (gbt.Game.read_game("test_games/basic_extensive_game.efg"), +@pytest.mark.parametrize( + "setting1,setting2,setting3,alpha", + [(((gbt.Game.read_game("test_games/Cl_BLotto_game.nfg")), + [[gbt.Rational(1, 10), gbt.Rational(4, 10), gbt.Rational(0, 1), + gbt.Rational(1, 8), gbt.Rational(3, 8)], + [gbt.Rational(3, 5), gbt.Rational(0, 5), + gbt.Rational(0, 5), gbt.Rational(2, 5)]], + [[gbt.Rational(2, 10), gbt.Rational(1, 10), gbt.Rational(2, 5), + gbt.Rational(1, 10), gbt.Rational(2, 10)], + [gbt.Rational(3, 5), gbt.Rational(0, 5), + gbt.Rational(0, 5), gbt.Rational(2, 5)]]), + ((gbt.Game.read_game("test_games/basic_extensive_game.efg")), [[gbt.Rational(1, 4), gbt.Rational(3, 4)], [gbt.Rational(3, 5), gbt.Rational(2, 5)], [gbt.Rational(5, 6), gbt.Rational(1, 6)]], [[gbt.Rational(3, 8), gbt.Rational(5, 8)], [gbt.Rational(3, 5), gbt.Rational(2, 5)], [gbt.Rational(5, 6), gbt.Rational(1, 6)]]), - - (gbt.Game.from_arrays(np.array([[[3, -1, -5], - [3, 0, -3], - [-1, 1, 4]], - [[-2, -1, -5], - [-3, -1, 0], - [4, -5, -3]], - [[0, 4, -3], - [-2, 4, -5], - [-2, -3, 1]], - [[3, 0, 2], - [1, 3, -5], - [-3, 3, 1]]]), - np.array([[[-4, -3, -5], - [2, -3, 3], - [-5, 2, 2]], - [[3, 0, 3], - [-1, 1, -1], - [3, 0, -3]], - [[0, 3, 2], - [-4, -2, 2], - [0, -5, 2]], - [[-2, 1, -2], - [0, 1, -5], - [-5, -4, 4]]]), - np.array([[[-3, -4, -1], - [-3, 3, 1], - [-5, 3, 2]], - [[1, 4, 3], - [-5, 2, 3], - [0, 4, 0]], - [[-4, -4, 1], - [3, -1, 0], - [-4, -1, -2]], - [[-2, -2, 4], - [2, -5, 1], - [-2, 3, 0]]])), - [[gbt.Rational(1, 4), gbt.Rational(1, 4), gbt.Rational(1, 4), gbt.Rational(1, 4)], - [gbt.Rational(3, 5), gbt.Rational(1, 5), gbt.Rational(1, 5)], - [gbt.Rational(1, 8), gbt.Rational(6, 8), gbt.Rational(1, 8)]], - [[gbt.Rational(2, 5), gbt.Rational(1, 5), gbt.Rational(1, 5), gbt.Rational(1, 5)], - [gbt.Rational(3, 5), gbt.Rational(1, 5), gbt.Rational(1, 5)], - [gbt.Rational(1, 8), gbt.Rational(6, 8), gbt.Rational(1, 8)]]) - ] - -alpha_values = [gbt.Rational(0, 1), gbt.Rational(1, 10), gbt.Rational(1, 5), - gbt.Rational(3, 10), gbt.Rational(2, 5), gbt.Rational(1, 2), - gbt.Rational(3, 5), gbt.Rational(7, 10), gbt.Rational(4, 5), - gbt.Rational(9, 10), gbt.Rational(1, 1)] - - -@pytest.mark.parametrize( - "setting,alpha", - [ - (s, a) for s in settings for a in alpha_values - ] + ((gbt.Game.from_arrays(np.array([[[3, -1, -5], + [3, 0, -3], + [-1, 1, 4]], + [[-2, -1, -5], + [-3, -1, 0], + [4, -5, -3]], + [[0, 4, -3], + [-2, 4, -5], + [-2, -3, 1]], + [[3, 0, 2], + [1, 3, -5], + [-3, 3, 1]]]), + np.array([[[-4, -3, -5], + [2, -3, 3], + [-5, 2, 2]], + [[3, 0, 3], + [-1, 1, -1], + [3, 0, -3]], + [[0, 3, 2], + [-4, -2, 2], + [0, -5, 2]], + [[-2, 1, -2], + [0, 1, -5], + [-5, -4, 4]]]), + np.array([[[-3, -4, -1], + [-3, 3, 1], + [-5, 3, 2]], + [[1, 4, 3], + [-5, 2, 3], + [0, 4, 0]], + [[-4, -4, 1], + [3, -1, 0], + [-4, -1, -2]], + [[-2, -2, 4], + [2, -5, 1], + [-2, 3, 0]]]))), + ([[gbt.Rational(1, 4), gbt.Rational(1, 4), gbt.Rational(1, 4), gbt.Rational(1, 4)], + [gbt.Rational(3, 5), gbt.Rational(1, 5), gbt.Rational(1, 5)], + [gbt.Rational(1, 8), gbt.Rational(6, 8), gbt.Rational(1, 8)]]), + ([[gbt.Rational(2, 5), gbt.Rational(1, 5), gbt.Rational(1, 5), gbt.Rational(1, 5)], + [gbt.Rational(3, 5), gbt.Rational(1, 5), gbt.Rational(1, 5)], + [gbt.Rational(1, 8), gbt.Rational(6, 8), gbt.Rational(1, 8)]])), + [gbt.Rational(0, 1), gbt.Rational(1, 5), gbt.Rational(1, 4), + gbt.Rational(1, 2), gbt.Rational(4, 5), gbt.Rational(1, 1)])] ) -def test_linearity(setting, alpha): +def test_linearity(setting1, setting2, setting3, alpha): """ Test the linearity of the payoffs for nfg and efg. For that, we use the .payoff functionality, which returns the expected @@ -549,7 +340,7 @@ def test_linearity(setting, alpha): # profiles from step II. # V. Verify outcomes. - def game_structure(): + def game_structure(setting): game = setting[0] # Retrive all extreme profiles and store them in a list. @@ -559,99 +350,132 @@ def game_structure(): p2 = [profiles[1][i] for i in range(len(game.players))] # create mixed strategy profiles and store them in a list. - L = [game.mixed_strategy_profile(rational=True, - data=profiles[i]) for i in range(len(profiles))] - return game, L, p1, p2 + L_ms = [game.mixed_strategy_profile(rational=True, + data=profiles[i]) for i in range(len(profiles))] + return game, L_ms, p1, p2 # In this function we create a strategy profile as a convex combination of the strategy # profiles, and the alpha values. - def conv_comb_payoff(): - r = [] - for k in range(len(game.players)): - p = [alpha*p1[k][i] + - (1 - alpha)*p2[k][i] for i in range(len(game.players[k].strategies))] - r.append(p) - mixed_strat = game.mixed_strategy_profile(rational=True, data=r) - - conv_comb_p = [] - for i in range(len(game.players)): - pf1 = L[0].payoff(game.players[i]) - pf2 = L[1].payoff(game.players[i]) - conv_comb_p.append(alpha*pf1 + (1 - alpha)*pf2) - - return mixed_strat, conv_comb_p + def conv_comb_payoff(game, L, p1, p2, alpha): + L_new_ms = [] + L_conv_comb = [] + + # Each new profile is a combination of two strategy profiles. + for j in range(len(alpha)): + r = [] + for k in range(len(game.players)): + p = [alpha[j]*p1[k][i] + + (1 - alpha[j])*p2[k][i] for i in range(len(game.players[k].strategies))] + r.append(p) + mixed_strat = game.mixed_strategy_profile(rational=True, data=r) + + conv_comb_p = [] + for i in range(len(game.players)): + pf1 = L[0].payoff(game.players[i]) + pf2 = L[1].payoff(game.players[i]) + conv_comb_p.append(alpha[j]*pf1 + (1 - alpha[j])*pf2) + + L_new_ms.append(mixed_strat) + L_conv_comb.append(conv_comb_p) + + return L_new_ms, L_conv_comb # In this function we use the .strategy_value functionality. - def conv_comb_strategy_value(): - conv_comb_sv = [] - n_sp_sv = [] + def conv_comb_strategy_value(game, L, mixed_strat, alpha): + L_conv_comb_sv = [] + L_n_sp_sv = [] + for k in range(len(alpha)): + conv_comb_sv = [] + n_sp_sv = [] + for i in range(len(game.players)): + tps = game.players[i].strategies + tmp1_sv = [alpha[k]*L[0].strategy_value(tps[j]) + + (1-alpha[k])*L[1].strategy_value(tps[j]) for j in range(len(tps))] + conv_comb_sv.append(tmp1_sv) + tmp2_sv = [mixed_strat[k].strategy_value(tps[j]) for j in range(len(tps))] + n_sp_sv.append(tmp2_sv) + + L_n_sp_sv.append(n_sp_sv) + L_conv_comb_sv.append(conv_comb_sv) + + return L_n_sp_sv, L_conv_comb_sv + + # Setting 1: 2-player nfg + game, L, p1, p2 = game_structure(setting1) + + mixed_strat, conv_comb = conv_comb_payoff(game, L, p1, p2, alpha) + for j in range(len(alpha)): for i in range(len(game.players)): - tps = game.players[i].strategies - tmp1_sv = [alpha*L[0].strategy_value(tps[j]) + - (1-alpha)*L[1].strategy_value(tps[j]) for j in range(len(tps))] - conv_comb_sv.append(tmp1_sv) - - tmp2_sv = [mixed_strat.strategy_value(tps[j]) for j in range(len(tps))] - n_sp_sv.append(tmp2_sv) + assert ( + mixed_strat[j].payoff(game.players[i]) == conv_comb[j][i] + ) - return n_sp_sv, conv_comb_sv + conv_comb_sv, n_sp_sv = conv_comb_strategy_value(game, L, mixed_strat, alpha) + for j in range(len(alpha)): + assert conv_comb_sv[j] == n_sp_sv[j] - game, L, p1, p2 = game_structure() + # Setting 2: 2-player efg + game, L, p1, p2 = game_structure(setting2) - mixed_strat, conv_comb = conv_comb_payoff() + mixed_strat, conv_comb = conv_comb_payoff(game, L, p1, p2, alpha) + for j in range(len(alpha)): + for i in range(len(game.players)): + assert ( + mixed_strat[j].payoff(game.players[i]) == conv_comb[j][i] + ) - for i in range(len(game.players)): - assert ( - mixed_strat.payoff(game.players[i]) == conv_comb[i] - ) + conv_comb_sv, n_sp_sv = conv_comb_strategy_value(game, L, mixed_strat, alpha) + for j in range(len(alpha)): + assert conv_comb_sv[j] == n_sp_sv[j] - n_sp_sv, conv_comb_sv = conv_comb_strategy_value() + # Setting 3: 3-player nfg + game, L, p1, p2 = game_structure(setting3) - for i in range(len(game.players)): - assert ( - conv_comb_sv[i] == n_sp_sv[i] - ) + mixed_strat, conv_comb = conv_comb_payoff(game, L, p1, p2, alpha) + for j in range(len(alpha)): + for i in range(len(game.players)): + assert ( + mixed_strat[j].payoff(game.players[i]) == conv_comb[j][i] + ) + conv_comb_sv, n_sp_sv = conv_comb_strategy_value(game, L, mixed_strat, alpha) + for j in range(len(alpha)): + assert conv_comb_sv[j] == n_sp_sv[j] @pytest.mark.parametrize( - "setting", - [ - (gbt.Game.from_arrays(np.array([[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]), - np.array([[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]])), - [[gbt.Rational(1, 4), gbt.Rational(1, 2), gbt.Rational(1, 8), gbt.Rational(1, 8)], - [gbt.Rational(2, 5), gbt.Rational(1, 5), gbt.Rational(0, 2), gbt.Rational(2, 5)]], - [gbt.Rational(0, 1), gbt.Rational(0, 1), gbt.Rational(0, 1)]), - - (gbt.Game.from_arrays(np.array([[3, 3], [2, 5], [0, 6]]), - np.array([[3, 3], [3, 6], [3, 1]])), - [[gbt.Rational(1, 2), gbt.Rational(1, 3), gbt.Rational(1, 6)], - [gbt.Rational(2, 5), gbt.Rational(3, 5)]], - [gbt.Rational(47, 150), gbt.Rational(5, 36), gbt.Rational(0, 1)]), - - (gbt.Game.read_game("test_games/coordination_4x4.nfg"), - [[gbt.Rational(1, 3), gbt.Rational(1, 2), gbt.Rational(1, 12), gbt.Rational(1, 12)], - [gbt.Rational(3, 8), gbt.Rational(1, 8), gbt.Rational(1, 4), gbt.Rational(1, 4)]], - [gbt.Rational(245, 2304), gbt.Rational(0, 1), gbt.Rational(0, 1)]), - - (gbt.Game.from_arrays(np.array([[[3, 3], [2, 5]], - [[3, 3], [3, 6]]]), - np.array([[[3, 3], [2, 5]], - [[3, 3], [3, 6]]]), - np.array([[[3, 3], [2, 5]], - [[3, 3], [3, 6]]])), - [[gbt.Rational(3, 4), gbt.Rational(1, 4)], - [gbt.Rational(2, 5), gbt.Rational(3, 5)], - [gbt.Rational(1, 2), gbt.Rational(1, 2)]], - [gbt.Rational(441, 400), gbt.Rational(7, 8), gbt.Rational(0, 1)]), - - (gbt.Game.read_game("test_games/Ultimatum_game.efg"), - [[gbt.Rational(7, 8), gbt.Rational(1, 8)], + "setting1,setting2,setting3,setting4,setting5", + [(((gbt.Game.from_arrays(np.array([[0, 0, 0], [0, 0, 0], [0, 0, 0]]), + np.array([[0, 0, 0], [0, 0, 0], [0, 0, 0]])), + ([[gbt.Rational(1, 4), gbt.Rational(1, 2), gbt.Rational(1, 4)], + [gbt.Rational(2, 5), gbt.Rational(1, 5), gbt.Rational(1, 5)]]), + ([gbt.Rational(0, 1), gbt.Rational(0, 1), gbt.Rational(0, 1)]))), + ((gbt.Game.from_arrays(np.array([[3, 3], [2, 5], [0, 6]]), + np.array([[3, 3], [3, 6], [3, 1]])), + ([[gbt.Rational(1, 2), gbt.Rational(1, 3), gbt.Rational(1, 6)], + [gbt.Rational(2, 5), gbt.Rational(3, 5)]]), + ([gbt.Rational(47, 150), gbt.Rational(5, 36), gbt.Rational(0, 1)]))), + ((gbt.Game.read_game("test_games/coordination_4x4.nfg")), + ([[gbt.Rational(1, 3), gbt.Rational(1, 2), gbt.Rational(1, 12), gbt.Rational(1, 12)], + [gbt.Rational(3, 8), gbt.Rational(1, 8), gbt.Rational(1, 4), gbt.Rational(1, 4)]]), + ([gbt.Rational(245, 2304), gbt.Rational(0, 1), gbt.Rational(0, 1)])), + ((gbt.Game.from_arrays(np.array([[[3, 3], [2, 5]], + [[3, 3], [3, 6]]]), + np.array([[[3, 3], [2, 5]], + [[3, 3], [3, 6]]]), + np.array([[[3, 3], [2, 5]], + [[3, 3], [3, 6]]])), + ([[gbt.Rational(3, 4), gbt.Rational(1, 4)], + [gbt.Rational(2, 5), gbt.Rational(3, 5)], + [gbt.Rational(1, 2), gbt.Rational(1, 2)]]), + ([gbt.Rational(441, 400), gbt.Rational(7, 8), gbt.Rational(0, 1)]))), + ((gbt.Game.read_game("test_games/Ultimatum_game.efg")), + ([[gbt.Rational(7, 8), gbt.Rational(1, 8)], [gbt.Rational(7, 16), gbt.Rational(1, 8), - gbt.Rational(3, 8), gbt.Rational(1, 16)]], - [gbt.Rational(285897, 16384), gbt.Rational(61, 16), gbt.Rational(9, 1)]) - ] + gbt.Rational(3, 8), gbt.Rational(1, 16)]]), + ([gbt.Rational(285897, 16384), gbt.Rational(61, 16), gbt.Rational(9, 1)])) + )] ) -def test_liapunov_value(setting): +def test_liapunov_value(setting1, setting2, setting3, setting4, setting5): """ Test the lyapunov value of a mixed profile for nfg and efg. For that, we use the .liap_value propery, which returns the Lyapunov value @@ -668,12 +492,12 @@ def test_liapunov_value(setting): # I. Pick a setting; each setting has a game, a profile, and three values. # II. Retrieve the game structure and create the mixed strategy profile. # III. Compute the Lyapunov value for - # - a given profile (value[0]). - # - the uniform profile (value[1]). - # - a pure profile, where every player plays her first strategy (value[2]). + # - the given profile. + # - the uniform profile. + # - the pure profile, where every player plays her first strategy. # IV. Verify outcomes. - def game_structure(): + def game_structure(setting): game = setting[0] # Retrive the profiles. @@ -683,12 +507,30 @@ def game_structure(): return game, profiles, v - game, profiles, values = game_structure() + # 2-player degnerate nfg + game, profiles, values = game_structure(setting1) # create mixed strategy profiles mixed_strat = game.mixed_strategy_profile(rational=True, data=profiles[0]) + with pytest.raises(Exception): + assert mixed_strat.liap_value() == values[0] + + # pure strategy profile + p = [] + for i in range(len(game.players)): + p.append([1 if j == 0 else 0 for j in range(len(game.players[i].strategies))]) + + pure_strat = game.mixed_strategy_profile(rational=True, data=p) + assert pure_strat.liap_value() == values[2] + + # 2-player nfg + game, profiles, values = game_structure(setting2) + + # create mixed strategy profiles + mixed_strat = game.mixed_strategy_profile(rational=True, + data=profiles[0]) assert mixed_strat.liap_value() == values[0] # uniform strategy profile @@ -703,8 +545,64 @@ def game_structure(): pure_strat = game.mixed_strategy_profile(rational=True, data=p) assert pure_strat.liap_value() == values[2] - # all-zero profile (does not add to one, so GetLiapValue induces a penalty) - p = [np.zeros(len(game.players[i].strategies)) for i in range(len(game.players))] - all_zero_strat = game.mixed_strategy_profile(rational=True, data=p) - with pytest.raises(Exception): - assert all_zero_strat.liap_value() == 0.0 + # 4x4 coodrination game + game, profiles, values = game_structure(setting3) + + # create mixed strategy profiles + mixed_strat = game.mixed_strategy_profile(rational=True, + data=profiles[0]) + assert mixed_strat.liap_value() == values[0] + + # uniform strategy profile + mixed_strat = game.mixed_strategy_profile(rational=True) + assert mixed_strat.liap_value() == values[1] + + # pure strategy profile + p = [] + for i in range(len(game.players)): + p.append([1 if j == 0 else 0 for j in range(len(game.players[i].strategies))]) + + pure_strat = game.mixed_strategy_profile(rational=True, data=p) + assert pure_strat.liap_value() == values[2] + + # 3-player nfg + game, profiles, values = game_structure(setting4) + + # create mixed strategy profiles + mixed_strat = game.mixed_strategy_profile(rational=True, + data=profiles[0]) + assert mixed_strat.liap_value() == values[0] + + # uniform strategy profile + mixed_strat = game.mixed_strategy_profile(rational=True) + assert mixed_strat.liap_value() == values[1] + + # pure strategy profile + p = [] + for i in range(len(game.players)): + p.append([1 if j == 0 else 0 for j in range(len(game.players[i].strategies))]) + + pure_strat = game.mixed_strategy_profile(rational=True, data=p) + assert pure_strat.liap_value() == values[2] + + # 2-player efg + game, profiles, values = game_structure(setting5) + + assert game.is_perfect_recall + + # create mixed strategy profiles + mixed_strat = game.mixed_strategy_profile(rational=True, + data=profiles[0]) + assert mixed_strat.liap_value() == values[0] + + # uniform strategy profile + mixed_strat = game.mixed_strategy_profile(rational=True) + assert mixed_strat.liap_value() == values[1] + + # pure strategy profile + p = [] + for i in range(len(game.players)): + p.append([1 if j == 0 else 0 for j in range(len(game.players[i].strategies))]) + + pure_strat = game.mixed_strategy_profile(rational=True, data=p) + assert pure_strat.liap_value() == values[2] From c2bf86cf06119b1227e4e8f28480a0b274cffe58 Mon Sep 17 00:00:00 2001 From: Rahul Savani Date: Thu, 30 Nov 2023 19:28:38 +0000 Subject: [PATCH 2/2] removed stale code --- src/pygambit/tests/test_mixed.py | 707 ++++++++++++++++++++++--------- 1 file changed, 495 insertions(+), 212 deletions(-) diff --git a/src/pygambit/tests/test_mixed.py b/src/pygambit/tests/test_mixed.py index 1631e03dd..c8f7a48f0 100644 --- a/src/pygambit/tests/test_mixed.py +++ b/src/pygambit/tests/test_mixed.py @@ -1,6 +1,5 @@ import pytest import numpy as np -from itertools import product, combinations import pygambit import pygambit as gbt @@ -14,76 +13,169 @@ def _create_strategic_game() -> gbt.Game: game.players["Dan"].strategies[1].label = "defect" return game + def _create_coordination_4x4_nfg() -> gbt.Game: return gbt.Game.read_game("test_games/coordination_4x4.nfg") + @pytest.mark.parametrize( "profile", [ - (_create_coordination_4x4_nfg().mixed_strategy_profile( - rational=True, - data=[[gbt.Rational(0), gbt.Rational(0), gbt.Rational(0), gbt.Rational(0)], - [gbt.Rational(1, 3), gbt.Rational(1, 3), gbt.Rational(1, 3), gbt.Rational(0)]])), - (_create_coordination_4x4_nfg().mixed_strategy_profile( - rational=True, - data=[[gbt.Rational(1), gbt.Rational(0), gbt.Rational(0), gbt.Rational(0)], - [gbt.Rational(0), gbt.Rational(0), gbt.Rational(0), gbt.Rational(0)]])), - (_create_coordination_4x4_nfg().mixed_strategy_profile( - rational=False, - data=[[0, 0, 0, 0], - [1.0, 1.0, 1.0, 1.0]])), - (_create_coordination_4x4_nfg().mixed_strategy_profile( - rational=False, - data=[[1.0, 1.0, 1.0, 1.0], - [0, 0, 0, 0]])), + ( + _create_coordination_4x4_nfg().mixed_strategy_profile( + rational=True, + data=[ + [ + gbt.Rational(0), + gbt.Rational(0), + gbt.Rational(0), + gbt.Rational(0), + ], + [ + gbt.Rational(1, 3), + gbt.Rational(1, 3), + gbt.Rational(1, 3), + gbt.Rational(0), + ], + ], + ) + ), + ( + _create_coordination_4x4_nfg().mixed_strategy_profile( + rational=True, + data=[ + [ + gbt.Rational(1), + gbt.Rational(0), + gbt.Rational(0), + gbt.Rational(0), + ], + [ + gbt.Rational(0), + gbt.Rational(0), + gbt.Rational(0), + gbt.Rational(0), + ], + ], + ) + ), + ( + _create_coordination_4x4_nfg().mixed_strategy_profile( + rational=False, data=[[0, 0, 0, 0], [1.0, 1.0, 1.0, 1.0]] + ) + ), + ( + _create_coordination_4x4_nfg().mixed_strategy_profile( + rational=False, data=[[1.0, 1.0, 1.0, 1.0], [0, 0, 0, 0]] + ) + ), ], ) def test_normalize_zero_value_error(profile): - with pytest.raises(ValueError, match=r'zero'): + with pytest.raises(ValueError, match=r"zero"): profile.normalize() @pytest.mark.parametrize( "profile", [ - (_create_coordination_4x4_nfg().mixed_strategy_profile( - rational=True, - data=[[gbt.Rational(1), gbt.Rational(1), gbt.Rational(0), gbt.Rational(-1)], - [gbt.Rational(1, 3), gbt.Rational(1, 3), gbt.Rational(1, 3), gbt.Rational(0)]])), - (_create_coordination_4x4_nfg().mixed_strategy_profile( - rational=True, - data=[[gbt.Rational(1), gbt.Rational(0), gbt.Rational(0), gbt.Rational(0)], - [gbt.Rational(1), gbt.Rational(1), gbt.Rational(0), gbt.Rational(-1)]])), - (_create_coordination_4x4_nfg().mixed_strategy_profile( - rational=False, - data=[[0, 0, 0, -1.0], - [1.0, 1.0, 1.0, 1.0]])), - (_create_coordination_4x4_nfg().mixed_strategy_profile( - rational=False, - data=[[1.0, 1.0, 1.0, 1.0], - [0, 0, 0, -1.0]])), + ( + _create_coordination_4x4_nfg().mixed_strategy_profile( + rational=True, + data=[ + [ + gbt.Rational(1), + gbt.Rational(1), + gbt.Rational(0), + gbt.Rational(-1), + ], + [ + gbt.Rational(1, 3), + gbt.Rational(1, 3), + gbt.Rational(1, 3), + gbt.Rational(0), + ], + ], + ) + ), + ( + _create_coordination_4x4_nfg().mixed_strategy_profile( + rational=True, + data=[ + [ + gbt.Rational(1), + gbt.Rational(0), + gbt.Rational(0), + gbt.Rational(0), + ], + [ + gbt.Rational(1), + gbt.Rational(1), + gbt.Rational(0), + gbt.Rational(-1), + ], + ], + ) + ), + ( + _create_coordination_4x4_nfg().mixed_strategy_profile( + rational=False, data=[[0, 0, 0, -1.0], [1.0, 1.0, 1.0, 1.0]] + ) + ), + ( + _create_coordination_4x4_nfg().mixed_strategy_profile( + rational=False, data=[[1.0, 1.0, 1.0, 1.0], [0, 0, 0, -1.0]] + ) + ), ], ) def test_normalize_neg_entry_value_error(profile): - with pytest.raises(ValueError, match=r'negative'): + with pytest.raises(ValueError, match=r"negative"): profile.normalize() @pytest.mark.parametrize( "profile,expect", [ - (_create_coordination_4x4_nfg().mixed_strategy_profile( - rational=True, - data=[ - [gbt.Rational(1, 1), gbt.Rational(2, 1), gbt.Rational(3, 1), gbt.Rational(14, 1)], - [gbt.Rational(1), gbt.Rational(1), gbt.Rational(1), gbt.Rational(1)]]), - ([gbt.Rational(1, 20), gbt.Rational(2, 20), gbt.Rational(3, 20), gbt.Rational(14, 20)], - [gbt.Rational(1, 4), gbt.Rational(1, 4), gbt.Rational(1, 4), gbt.Rational(1, 4)])), - (_create_coordination_4x4_nfg().mixed_strategy_profile( - rational=False, - data=[[1.0, 2.0, 3.0, 14.0], [1, 1, 1, 1]]), - ([1 / 20, 2 / 20, 3 / 20, 14 / 20], - [0.25, 0.25, 0.25, 0.25])), + ( + _create_coordination_4x4_nfg().mixed_strategy_profile( + rational=True, + data=[ + [ + gbt.Rational(1, 1), + gbt.Rational(2, 1), + gbt.Rational(3, 1), + gbt.Rational(14, 1), + ], + [ + gbt.Rational(1), + gbt.Rational(1), + gbt.Rational(1), + gbt.Rational(1), + ], + ], + ), + ( + [ + gbt.Rational(1, 20), + gbt.Rational(2, 20), + gbt.Rational(3, 20), + gbt.Rational(14, 20), + ], + [ + gbt.Rational(1, 4), + gbt.Rational(1, 4), + gbt.Rational(1, 4), + gbt.Rational(1, 4), + ], + ), + ), + ( + _create_coordination_4x4_nfg().mixed_strategy_profile( + rational=False, data=[[1.0, 2.0, 3.0, 14.0], [1, 1, 1, 1]] + ), + ([1 / 20, 2 / 20, 3 / 20, 14 / 20], [0.25, 0.25, 0.25, 0.25]), + ), ], ) def test_normalize(profile, expect): @@ -139,17 +231,47 @@ def test_set_probability_player(): [ (_create_strategic_game().mixed_strategy_profile(rational=False), (0, 0)), (_create_strategic_game().mixed_strategy_profile(rational=True), (0, 0)), - (_create_coordination_4x4_nfg().mixed_strategy_profile(), (0.25, 0.25)), - (_create_coordination_4x4_nfg().mixed_strategy_profile( - rational=True, - data=[[gbt.Rational(1, 3), gbt.Rational(1, 3), gbt.Rational(1, 3), gbt.Rational(0)], - [gbt.Rational(1, 3), gbt.Rational(1, 3), gbt.Rational(1, 3), gbt.Rational(0)]]), - (gbt.Rational(1, 3), gbt.Rational(1, 3))), - (_create_coordination_4x4_nfg().mixed_strategy_profile( - rational=True, - data=[[gbt.Rational(1, 3), gbt.Rational(1, 3), gbt.Rational(0), gbt.Rational(1, 3)], - [gbt.Rational(1, 3), gbt.Rational(1, 3), gbt.Rational(1, 3), gbt.Rational(0)]]), - (gbt.Rational(2, 9), gbt.Rational(2, 9))), + (_create_coordination_4x4_nfg().mixed_strategy_profile(), (0.25, 0.25)), + ( + _create_coordination_4x4_nfg().mixed_strategy_profile( + rational=True, + data=[ + [ + gbt.Rational(1, 3), + gbt.Rational(1, 3), + gbt.Rational(1, 3), + gbt.Rational(0), + ], + [ + gbt.Rational(1, 3), + gbt.Rational(1, 3), + gbt.Rational(1, 3), + gbt.Rational(0), + ], + ], + ), + (gbt.Rational(1, 3), gbt.Rational(1, 3)), + ), + ( + _create_coordination_4x4_nfg().mixed_strategy_profile( + rational=True, + data=[ + [ + gbt.Rational(1, 3), + gbt.Rational(1, 3), + gbt.Rational(0), + gbt.Rational(1, 3), + ], + [ + gbt.Rational(1, 3), + gbt.Rational(1, 3), + gbt.Rational(1, 3), + gbt.Rational(0), + ], + ], + ), + (gbt.Rational(2, 9), gbt.Rational(2, 9)), + ), ], ) def test_payoffs(profile, payoffs): @@ -164,47 +286,84 @@ def test_payoffs_by_label(): assert game.mixed_strategy_profile(rational=True).payoff("Joe") == 0 -def test_strategy_value_coordination(): - game = gbt.Game.read_game("test_games/coordination_4x4.nfg") - assert mixed_strat.strategy_value(game.players[1].strategies[0]) == gbt.Rational( - 3, 7 - ) - assert mixed_strat.strategy_value(game.players[1].strategies[1]) == 0 - assert mixed_strat.strategy_value(game.players[1].strategies[2]) == 0 - assert mixed_strat.strategy_value(game.players[1].strategies[3]) == gbt.Rational( - 4, 7 - ) - mixed_strat = game.mixed_strategy_profile( - rational=True, data=[[1, 0, 0, 0], [1, 0, 0, 0]] - ) - assert mixed_strat.strategy_value(game.players[1].strategies[0]) == 1 - assert mixed_strat.strategy_value(game.players[1].strategies[1]) == 0 - - @pytest.mark.parametrize( "profile,strategy_values", [ - (_create_strategic_game().mixed_strategy_profile(rational=False), ([0,0],[0,0])), - (_create_strategic_game().mixed_strategy_profile(rational=True), ([0,0],[0,0])), - (_create_coordination_4x4_nfg().mixed_strategy_profile(), - ([0.25, 0.25, 0.25, 0.25],[0.25, 0.25, 0.25, 0.25])), - (_create_coordination_4x4_nfg().mixed_strategy_profile( - rational=True, - data=[[gbt.Rational(1), gbt.Rational(0), gbt.Rational(0), gbt.Rational(0)], - [gbt.Rational(1), gbt.Rational(0), gbt.Rational(0), gbt.Rational(0)]]), - ([gbt.Rational(1), gbt.Rational(0), gbt.Rational(0), gbt.Rational(0)], - [gbt.Rational(1), gbt.Rational(0), gbt.Rational(0), gbt.Rational(0)])), - (_create_coordination_4x4_nfg().mixed_strategy_profile( - rational=True, - data=[[gbt.Rational(3, 7), gbt.Rational(0), gbt.Rational(0), gbt.Rational(4, 7)], - [gbt.Rational(1, 3), gbt.Rational(1, 3), gbt.Rational(1, 3), gbt.Rational(0)]]), - ([gbt.Rational(1, 3), gbt.Rational(1, 3), gbt.Rational(1, 3), gbt.Rational(0)], - [gbt.Rational(3, 7), gbt.Rational(0), gbt.Rational(0), gbt.Rational(4, 7)])), + ( + _create_strategic_game().mixed_strategy_profile(rational=False), + ([0, 0], [0, 0]), + ), + ( + _create_strategic_game().mixed_strategy_profile(rational=True), + ([0, 0], [0, 0]), + ), + ( + _create_coordination_4x4_nfg().mixed_strategy_profile(), + ([0.25, 0.25, 0.25, 0.25], [0.25, 0.25, 0.25, 0.25]), + ), + ( + _create_coordination_4x4_nfg().mixed_strategy_profile( + rational=True, + data=[ + [ + gbt.Rational(1), + gbt.Rational(0), + gbt.Rational(0), + gbt.Rational(0), + ], + [ + gbt.Rational(1), + gbt.Rational(0), + gbt.Rational(0), + gbt.Rational(0), + ], + ], + ), + ( + [gbt.Rational(1), gbt.Rational(0), gbt.Rational(0), gbt.Rational(0)], + [gbt.Rational(1), gbt.Rational(0), gbt.Rational(0), gbt.Rational(0)], + ), + ), + ( + _create_coordination_4x4_nfg().mixed_strategy_profile( + rational=True, + data=[ + [ + gbt.Rational(3, 7), + gbt.Rational(0), + gbt.Rational(0), + gbt.Rational(4, 7), + ], + [ + gbt.Rational(1, 3), + gbt.Rational(1, 3), + gbt.Rational(1, 3), + gbt.Rational(0), + ], + ], + ), + ( + [ + gbt.Rational(1, 3), + gbt.Rational(1, 3), + gbt.Rational(1, 3), + gbt.Rational(0), + ], + [ + gbt.Rational(3, 7), + gbt.Rational(0), + gbt.Rational(0), + gbt.Rational(4, 7), + ], + ), + ), ], ) def test_strategy_values(profile, strategy_values): """Hard-wired tests for MixedStrategyProfile.payoff""" - for strategy_values_for_player, player in zip(strategy_values, profile.game.players): + for strategy_values_for_player, player in zip( + strategy_values, profile.game.players + ): for i, s in enumerate(player.strategies): assert profile.strategy_value(s) == strategy_values_for_player[i] @@ -252,69 +411,121 @@ def test_as_behavior_error(): @pytest.mark.parametrize( "setting1,setting2,setting3,alpha", - [(((gbt.Game.read_game("test_games/Cl_BLotto_game.nfg")), - [[gbt.Rational(1, 10), gbt.Rational(4, 10), gbt.Rational(0, 1), - gbt.Rational(1, 8), gbt.Rational(3, 8)], - [gbt.Rational(3, 5), gbt.Rational(0, 5), - gbt.Rational(0, 5), gbt.Rational(2, 5)]], - [[gbt.Rational(2, 10), gbt.Rational(1, 10), gbt.Rational(2, 5), - gbt.Rational(1, 10), gbt.Rational(2, 10)], - [gbt.Rational(3, 5), gbt.Rational(0, 5), - gbt.Rational(0, 5), gbt.Rational(2, 5)]]), - ((gbt.Game.read_game("test_games/basic_extensive_game.efg")), - [[gbt.Rational(1, 4), gbt.Rational(3, 4)], - [gbt.Rational(3, 5), gbt.Rational(2, 5)], - [gbt.Rational(5, 6), gbt.Rational(1, 6)]], - [[gbt.Rational(3, 8), gbt.Rational(5, 8)], - [gbt.Rational(3, 5), gbt.Rational(2, 5)], - [gbt.Rational(5, 6), gbt.Rational(1, 6)]]), - ((gbt.Game.from_arrays(np.array([[[3, -1, -5], - [3, 0, -3], - [-1, 1, 4]], - [[-2, -1, -5], - [-3, -1, 0], - [4, -5, -3]], - [[0, 4, -3], - [-2, 4, -5], - [-2, -3, 1]], - [[3, 0, 2], - [1, 3, -5], - [-3, 3, 1]]]), - np.array([[[-4, -3, -5], - [2, -3, 3], - [-5, 2, 2]], - [[3, 0, 3], - [-1, 1, -1], - [3, 0, -3]], - [[0, 3, 2], - [-4, -2, 2], - [0, -5, 2]], - [[-2, 1, -2], - [0, 1, -5], - [-5, -4, 4]]]), - np.array([[[-3, -4, -1], - [-3, 3, 1], - [-5, 3, 2]], - [[1, 4, 3], - [-5, 2, 3], - [0, 4, 0]], - [[-4, -4, 1], - [3, -1, 0], - [-4, -1, -2]], - [[-2, -2, 4], - [2, -5, 1], - [-2, 3, 0]]]))), - ([[gbt.Rational(1, 4), gbt.Rational(1, 4), gbt.Rational(1, 4), gbt.Rational(1, 4)], - [gbt.Rational(3, 5), gbt.Rational(1, 5), gbt.Rational(1, 5)], - [gbt.Rational(1, 8), gbt.Rational(6, 8), gbt.Rational(1, 8)]]), - ([[gbt.Rational(2, 5), gbt.Rational(1, 5), gbt.Rational(1, 5), gbt.Rational(1, 5)], - [gbt.Rational(3, 5), gbt.Rational(1, 5), gbt.Rational(1, 5)], - [gbt.Rational(1, 8), gbt.Rational(6, 8), gbt.Rational(1, 8)]])), - [gbt.Rational(0, 1), gbt.Rational(1, 5), gbt.Rational(1, 4), - gbt.Rational(1, 2), gbt.Rational(4, 5), gbt.Rational(1, 1)])] + [ + ( + ( + (gbt.Game.read_game("test_games/Cl_BLotto_game.nfg")), + [ + [ + gbt.Rational(1, 10), + gbt.Rational(4, 10), + gbt.Rational(0, 1), + gbt.Rational(1, 8), + gbt.Rational(3, 8), + ], + [ + gbt.Rational(3, 5), + gbt.Rational(0, 5), + gbt.Rational(0, 5), + gbt.Rational(2, 5), + ], + ], + [ + [ + gbt.Rational(2, 10), + gbt.Rational(1, 10), + gbt.Rational(2, 5), + gbt.Rational(1, 10), + gbt.Rational(2, 10), + ], + [ + gbt.Rational(3, 5), + gbt.Rational(0, 5), + gbt.Rational(0, 5), + gbt.Rational(2, 5), + ], + ], + ), + ( + (gbt.Game.read_game("test_games/basic_extensive_game.efg")), + [ + [gbt.Rational(1, 4), gbt.Rational(3, 4)], + [gbt.Rational(3, 5), gbt.Rational(2, 5)], + [gbt.Rational(5, 6), gbt.Rational(1, 6)], + ], + [ + [gbt.Rational(3, 8), gbt.Rational(5, 8)], + [gbt.Rational(3, 5), gbt.Rational(2, 5)], + [gbt.Rational(5, 6), gbt.Rational(1, 6)], + ], + ), + ( + ( + gbt.Game.from_arrays( + np.array( + [ + [[3, -1, -5], [3, 0, -3], [-1, 1, 4]], + [[-2, -1, -5], [-3, -1, 0], [4, -5, -3]], + [[0, 4, -3], [-2, 4, -5], [-2, -3, 1]], + [[3, 0, 2], [1, 3, -5], [-3, 3, 1]], + ] + ), + np.array( + [ + [[-4, -3, -5], [2, -3, 3], [-5, 2, 2]], + [[3, 0, 3], [-1, 1, -1], [3, 0, -3]], + [[0, 3, 2], [-4, -2, 2], [0, -5, 2]], + [[-2, 1, -2], [0, 1, -5], [-5, -4, 4]], + ] + ), + np.array( + [ + [[-3, -4, -1], [-3, 3, 1], [-5, 3, 2]], + [[1, 4, 3], [-5, 2, 3], [0, 4, 0]], + [[-4, -4, 1], [3, -1, 0], [-4, -1, -2]], + [[-2, -2, 4], [2, -5, 1], [-2, 3, 0]], + ] + ), + ) + ), + ( + [ + [ + gbt.Rational(1, 4), + gbt.Rational(1, 4), + gbt.Rational(1, 4), + gbt.Rational(1, 4), + ], + [gbt.Rational(3, 5), gbt.Rational(1, 5), gbt.Rational(1, 5)], + [gbt.Rational(1, 8), gbt.Rational(6, 8), gbt.Rational(1, 8)], + ] + ), + ( + [ + [ + gbt.Rational(2, 5), + gbt.Rational(1, 5), + gbt.Rational(1, 5), + gbt.Rational(1, 5), + ], + [gbt.Rational(3, 5), gbt.Rational(1, 5), gbt.Rational(1, 5)], + [gbt.Rational(1, 8), gbt.Rational(6, 8), gbt.Rational(1, 8)], + ] + ), + ), + [ + gbt.Rational(0, 1), + gbt.Rational(1, 5), + gbt.Rational(1, 4), + gbt.Rational(1, 2), + gbt.Rational(4, 5), + gbt.Rational(1, 1), + ], + ) + ], ) def test_linearity(setting1, setting2, setting3, alpha): - """ Test the linearity of the payoffs for nfg and efg. + """Test the linearity of the payoffs for nfg and efg. For that, we use the .payoff functionality, which returns the expected payoff to a player if all the players play according to a specified profile. @@ -350,8 +561,10 @@ def game_structure(setting): p2 = [profiles[1][i] for i in range(len(game.players))] # create mixed strategy profiles and store them in a list. - L_ms = [game.mixed_strategy_profile(rational=True, - data=profiles[i]) for i in range(len(profiles))] + L_ms = [ + game.mixed_strategy_profile(rational=True, data=profiles[i]) + for i in range(len(profiles)) + ] return game, L_ms, p1, p2 # In this function we create a strategy profile as a convex combination of the strategy @@ -364,8 +577,10 @@ def conv_comb_payoff(game, L, p1, p2, alpha): for j in range(len(alpha)): r = [] for k in range(len(game.players)): - p = [alpha[j]*p1[k][i] + - (1 - alpha[j])*p2[k][i] for i in range(len(game.players[k].strategies))] + p = [ + alpha[j] * p1[k][i] + (1 - alpha[j]) * p2[k][i] + for i in range(len(game.players[k].strategies)) + ] r.append(p) mixed_strat = game.mixed_strategy_profile(rational=True, data=r) @@ -373,7 +588,7 @@ def conv_comb_payoff(game, L, p1, p2, alpha): for i in range(len(game.players)): pf1 = L[0].payoff(game.players[i]) pf2 = L[1].payoff(game.players[i]) - conv_comb_p.append(alpha[j]*pf1 + (1 - alpha[j])*pf2) + conv_comb_p.append(alpha[j] * pf1 + (1 - alpha[j]) * pf2) L_new_ms.append(mixed_strat) L_conv_comb.append(conv_comb_p) @@ -389,10 +604,15 @@ def conv_comb_strategy_value(game, L, mixed_strat, alpha): n_sp_sv = [] for i in range(len(game.players)): tps = game.players[i].strategies - tmp1_sv = [alpha[k]*L[0].strategy_value(tps[j]) + - (1-alpha[k])*L[1].strategy_value(tps[j]) for j in range(len(tps))] + tmp1_sv = [ + alpha[k] * L[0].strategy_value(tps[j]) + + (1 - alpha[k]) * L[1].strategy_value(tps[j]) + for j in range(len(tps)) + ] conv_comb_sv.append(tmp1_sv) - tmp2_sv = [mixed_strat[k].strategy_value(tps[j]) for j in range(len(tps))] + tmp2_sv = [ + mixed_strat[k].strategy_value(tps[j]) for j in range(len(tps)) + ] n_sp_sv.append(tmp2_sv) L_n_sp_sv.append(n_sp_sv) @@ -406,9 +626,7 @@ def conv_comb_strategy_value(game, L, mixed_strat, alpha): mixed_strat, conv_comb = conv_comb_payoff(game, L, p1, p2, alpha) for j in range(len(alpha)): for i in range(len(game.players)): - assert ( - mixed_strat[j].payoff(game.players[i]) == conv_comb[j][i] - ) + assert mixed_strat[j].payoff(game.players[i]) == conv_comb[j][i] conv_comb_sv, n_sp_sv = conv_comb_strategy_value(game, L, mixed_strat, alpha) for j in range(len(alpha)): @@ -420,9 +638,7 @@ def conv_comb_strategy_value(game, L, mixed_strat, alpha): mixed_strat, conv_comb = conv_comb_payoff(game, L, p1, p2, alpha) for j in range(len(alpha)): for i in range(len(game.players)): - assert ( - mixed_strat[j].payoff(game.players[i]) == conv_comb[j][i] - ) + assert mixed_strat[j].payoff(game.players[i]) == conv_comb[j][i] conv_comb_sv, n_sp_sv = conv_comb_strategy_value(game, L, mixed_strat, alpha) for j in range(len(alpha)): @@ -434,9 +650,7 @@ def conv_comb_strategy_value(game, L, mixed_strat, alpha): mixed_strat, conv_comb = conv_comb_payoff(game, L, p1, p2, alpha) for j in range(len(alpha)): for i in range(len(game.players)): - assert ( - mixed_strat[j].payoff(game.players[i]) == conv_comb[j][i] - ) + assert mixed_strat[j].payoff(game.players[i]) == conv_comb[j][i] conv_comb_sv, n_sp_sv = conv_comb_strategy_value(game, L, mixed_strat, alpha) for j in range(len(alpha)): assert conv_comb_sv[j] == n_sp_sv[j] @@ -444,39 +658,113 @@ def conv_comb_strategy_value(game, L, mixed_strat, alpha): @pytest.mark.parametrize( "setting1,setting2,setting3,setting4,setting5", - [(((gbt.Game.from_arrays(np.array([[0, 0, 0], [0, 0, 0], [0, 0, 0]]), - np.array([[0, 0, 0], [0, 0, 0], [0, 0, 0]])), - ([[gbt.Rational(1, 4), gbt.Rational(1, 2), gbt.Rational(1, 4)], - [gbt.Rational(2, 5), gbt.Rational(1, 5), gbt.Rational(1, 5)]]), - ([gbt.Rational(0, 1), gbt.Rational(0, 1), gbt.Rational(0, 1)]))), - ((gbt.Game.from_arrays(np.array([[3, 3], [2, 5], [0, 6]]), - np.array([[3, 3], [3, 6], [3, 1]])), - ([[gbt.Rational(1, 2), gbt.Rational(1, 3), gbt.Rational(1, 6)], - [gbt.Rational(2, 5), gbt.Rational(3, 5)]]), - ([gbt.Rational(47, 150), gbt.Rational(5, 36), gbt.Rational(0, 1)]))), - ((gbt.Game.read_game("test_games/coordination_4x4.nfg")), - ([[gbt.Rational(1, 3), gbt.Rational(1, 2), gbt.Rational(1, 12), gbt.Rational(1, 12)], - [gbt.Rational(3, 8), gbt.Rational(1, 8), gbt.Rational(1, 4), gbt.Rational(1, 4)]]), - ([gbt.Rational(245, 2304), gbt.Rational(0, 1), gbt.Rational(0, 1)])), - ((gbt.Game.from_arrays(np.array([[[3, 3], [2, 5]], - [[3, 3], [3, 6]]]), - np.array([[[3, 3], [2, 5]], - [[3, 3], [3, 6]]]), - np.array([[[3, 3], [2, 5]], - [[3, 3], [3, 6]]])), - ([[gbt.Rational(3, 4), gbt.Rational(1, 4)], - [gbt.Rational(2, 5), gbt.Rational(3, 5)], - [gbt.Rational(1, 2), gbt.Rational(1, 2)]]), - ([gbt.Rational(441, 400), gbt.Rational(7, 8), gbt.Rational(0, 1)]))), - ((gbt.Game.read_game("test_games/Ultimatum_game.efg")), - ([[gbt.Rational(7, 8), gbt.Rational(1, 8)], - [gbt.Rational(7, 16), gbt.Rational(1, 8), - gbt.Rational(3, 8), gbt.Rational(1, 16)]]), - ([gbt.Rational(285897, 16384), gbt.Rational(61, 16), gbt.Rational(9, 1)])) - )] + [ + ( + ( + ( + gbt.Game.from_arrays( + np.array([[0, 0, 0], [0, 0, 0], [0, 0, 0]]), + np.array([[0, 0, 0], [0, 0, 0], [0, 0, 0]]), + ), + ( + [ + [ + gbt.Rational(1, 4), + gbt.Rational(1, 2), + gbt.Rational(1, 4), + ], + [ + gbt.Rational(2, 5), + gbt.Rational(1, 5), + gbt.Rational(1, 5), + ], + ] + ), + ([gbt.Rational(0, 1), gbt.Rational(0, 1), gbt.Rational(0, 1)]), + ) + ), + ( + ( + gbt.Game.from_arrays( + np.array([[3, 3], [2, 5], [0, 6]]), + np.array([[3, 3], [3, 6], [3, 1]]), + ), + ( + [ + [ + gbt.Rational(1, 2), + gbt.Rational(1, 3), + gbt.Rational(1, 6), + ], + [gbt.Rational(2, 5), gbt.Rational(3, 5)], + ] + ), + ([gbt.Rational(47, 150), gbt.Rational(5, 36), gbt.Rational(0, 1)]), + ) + ), + ( + (gbt.Game.read_game("test_games/coordination_4x4.nfg")), + ( + [ + [ + gbt.Rational(1, 3), + gbt.Rational(1, 2), + gbt.Rational(1, 12), + gbt.Rational(1, 12), + ], + [ + gbt.Rational(3, 8), + gbt.Rational(1, 8), + gbt.Rational(1, 4), + gbt.Rational(1, 4), + ], + ] + ), + ([gbt.Rational(245, 2304), gbt.Rational(0, 1), gbt.Rational(0, 1)]), + ), + ( + ( + gbt.Game.from_arrays( + np.array([[[3, 3], [2, 5]], [[3, 3], [3, 6]]]), + np.array([[[3, 3], [2, 5]], [[3, 3], [3, 6]]]), + np.array([[[3, 3], [2, 5]], [[3, 3], [3, 6]]]), + ), + ( + [ + [gbt.Rational(3, 4), gbt.Rational(1, 4)], + [gbt.Rational(2, 5), gbt.Rational(3, 5)], + [gbt.Rational(1, 2), gbt.Rational(1, 2)], + ] + ), + ([gbt.Rational(441, 400), gbt.Rational(7, 8), gbt.Rational(0, 1)]), + ) + ), + ( + (gbt.Game.read_game("test_games/Ultimatum_game.efg")), + ( + [ + [gbt.Rational(7, 8), gbt.Rational(1, 8)], + [ + gbt.Rational(7, 16), + gbt.Rational(1, 8), + gbt.Rational(3, 8), + gbt.Rational(1, 16), + ], + ] + ), + ( + [ + gbt.Rational(285897, 16384), + gbt.Rational(61, 16), + gbt.Rational(9, 1), + ] + ), + ), + ) + ], ) def test_liapunov_value(setting1, setting2, setting3, setting4, setting5): - """ Test the lyapunov value of a mixed profile for nfg and efg. + """Test the lyapunov value of a mixed profile for nfg and efg. For that, we use the .liap_value propery, which returns the Lyapunov value of a strategy profile. @@ -501,7 +789,7 @@ def game_structure(setting): game = setting[0] # Retrive the profiles. - profiles = [setting[i] for i in range(1, len(setting)-1)] + profiles = [setting[i] for i in range(1, len(setting) - 1)] v = setting[-1] @@ -511,8 +799,7 @@ def game_structure(setting): game, profiles, values = game_structure(setting1) # create mixed strategy profiles - mixed_strat = game.mixed_strategy_profile(rational=True, - data=profiles[0]) + mixed_strat = game.mixed_strategy_profile(rational=True, data=profiles[0]) with pytest.raises(Exception): assert mixed_strat.liap_value() == values[0] @@ -529,8 +816,7 @@ def game_structure(setting): game, profiles, values = game_structure(setting2) # create mixed strategy profiles - mixed_strat = game.mixed_strategy_profile(rational=True, - data=profiles[0]) + mixed_strat = game.mixed_strategy_profile(rational=True, data=profiles[0]) assert mixed_strat.liap_value() == values[0] # uniform strategy profile @@ -549,8 +835,7 @@ def game_structure(setting): game, profiles, values = game_structure(setting3) # create mixed strategy profiles - mixed_strat = game.mixed_strategy_profile(rational=True, - data=profiles[0]) + mixed_strat = game.mixed_strategy_profile(rational=True, data=profiles[0]) assert mixed_strat.liap_value() == values[0] # uniform strategy profile @@ -569,8 +854,7 @@ def game_structure(setting): game, profiles, values = game_structure(setting4) # create mixed strategy profiles - mixed_strat = game.mixed_strategy_profile(rational=True, - data=profiles[0]) + mixed_strat = game.mixed_strategy_profile(rational=True, data=profiles[0]) assert mixed_strat.liap_value() == values[0] # uniform strategy profile @@ -591,8 +875,7 @@ def game_structure(setting): assert game.is_perfect_recall # create mixed strategy profiles - mixed_strat = game.mixed_strategy_profile(rational=True, - data=profiles[0]) + mixed_strat = game.mixed_strategy_profile(rational=True, data=profiles[0]) assert mixed_strat.liap_value() == values[0] # uniform strategy profile