Skip to content

Commit 1f4ba31

Browse files
committed
New tests for lcp_strategy_rational and enummixed_rational
1 parent 90e7ee4 commit 1f4ba31

2 files changed

Lines changed: 121 additions & 25 deletions

File tree

tests/games.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,28 @@ def bet(player, payoffs, pot):
233233
return g
234234

235235

236+
def kuhn_poker_lcp_first_mixed_strategy_prof():
237+
"""
238+
Returns
239+
-------
240+
Data for the first extreme equilibrium in mixed stategies for Kuhn poker found by lcp_solve
241+
"""
242+
alice = [0] * 27
243+
alice[1] = "2/3"
244+
alice[4] = "1/3"
245+
bob = [0] * 64
246+
bob[12] = "2/3"
247+
bob[30] = "1/3"
248+
return [alice, bob]
249+
250+
236251
def create_one_shot_trust_efg() -> gbt.Game:
252+
"""
253+
Returns
254+
-------
255+
Game
256+
One-shot trust game, after Kreps (1990)
257+
"""
237258
g = gbt.Game.new_tree(
238259
players=["Buyer", "Seller"], title="One-shot trust game, after Kreps (1990)"
239260
)

tests/test_nash.py

Lines changed: 100 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -40,19 +40,48 @@ def test_enummixed_double():
4040

4141
@pytest.mark.nash
4242
@pytest.mark.nash_enummixed_strategy
43-
def test_enummixed_rational():
44-
"""Test calls of enumeration of mixed strategy equilibria, rational precision."""
45-
game = games.read_from_file("poker.efg")
43+
@pytest.mark.parametrize(
44+
"game,mixed_strategy_prof_data",
45+
[
46+
# Zero-sum games
47+
(games.create_1_card_poker_efg(), [[["1/3", "2/3", 0, 0], ["2/3", "1/3"]]]),
48+
(games.create_myerson_2_card_poker_efg(), [[["1/3", "2/3", 0, 0], ["2/3", "1/3"]]]),
49+
# Non-zero-sum games
50+
(games.create_one_shot_trust_efg(), [[[0, 1], ["1/2", "1/2"]],
51+
[[0, 1], [0, 1]]]),
52+
(
53+
games.create_EFG_for_nxn_bimatrix_coordination_game(3),
54+
[
55+
[[1, 0, 0], [1, 0, 0]],
56+
[["1/2", "1/2", 0], ["1/2", "1/2", 0]],
57+
[["1/3", "1/3", "1/3"], ["1/3", "1/3", "1/3"]],
58+
[["1/2", 0, "1/2"], ["1/2", 0, "1/2"]],
59+
[[0, 1, 0], [0, 1, 0]],
60+
[[0, "1/2", "1/2"], [0, "1/2", "1/2"]],
61+
[[0, 0, 1], [0, 0, 1]],
62+
],
63+
),
64+
(
65+
games.create_EFG_for_6x6_bimatrix_with_long_LH_paths_and_unique_eq(),
66+
[
67+
[["1/30", "1/6", "3/10", "3/10", "1/6", "1/30"],
68+
["1/6", "1/30", "3/10", "3/10", "1/30", "1/6"]],
69+
],
70+
),
71+
]
72+
)
73+
def test_enummixed_rational(game: gbt.Game, mixed_strategy_prof_data: list):
74+
"""Test calls of enumeration of extreme mixed strategy equilibria, rational precision
75+
76+
Tests max regret being zero (internal consistency) and compares the computed sequence of
77+
extreme equilibria to a previosuly computed sequence (regression test)
78+
"""
4679
result = gbt.nash.enummixed_solve(game, rational=True)
47-
assert len(result.equilibria) == 1
48-
expected = game.mixed_strategy_profile(
49-
rational=True,
50-
data=[
51-
[gbt.Rational(1, 3), gbt.Rational(2, 3), gbt.Rational(0), gbt.Rational(0)],
52-
[gbt.Rational(2, 3), gbt.Rational(1, 3)],
53-
],
54-
)
55-
assert result.equilibria[0] == expected
80+
assert len(result.equilibria) == len(mixed_strategy_prof_data)
81+
for eq, exp in zip(result.equilibria, mixed_strategy_prof_data):
82+
assert eq.max_regret() == 0
83+
expected = game.mixed_strategy_profile(rational=True, data=exp)
84+
assert eq == expected
5685

5786

5887
@pytest.mark.nash
@@ -219,19 +248,65 @@ def test_lcp_strategy_double():
219248

220249
@pytest.mark.nash
221250
@pytest.mark.nash_lcp_strategy
222-
def test_lcp_strategy_rational():
223-
"""Test calls of LCP for mixed strategy equilibria, rational precision."""
224-
game = games.read_from_file("poker.efg")
225-
result = gbt.nash.lcp_solve(game, use_strategic=True, rational=True)
226-
assert len(result.equilibria) == 1
227-
expected = game.mixed_strategy_profile(
228-
rational=True,
229-
data=[
230-
[gbt.Rational(1, 3), gbt.Rational(2, 3), gbt.Rational(0), gbt.Rational(0)],
231-
[gbt.Rational(2, 3), gbt.Rational(1, 3)],
232-
],
233-
)
234-
assert result.equilibria[0] == expected
251+
@pytest.mark.parametrize(
252+
"game,mixed_strategy_prof_data,stop_after",
253+
[
254+
# Zero-sum games
255+
(games.create_1_card_poker_efg(), [[["1/3", "2/3", 0, 0], ["2/3", "1/3"]]], None),
256+
(games.create_myerson_2_card_poker_efg(), [[["1/3", "2/3", 0, 0], ["2/3", "1/3"]]], None),
257+
(games.create_kuhn_poker_efg(), [games.kuhn_poker_lcp_first_mixed_strategy_prof()], 1),
258+
# Non-zero-sum games
259+
(games.create_one_shot_trust_efg(), [[[0, 1], ["1/2", "1/2"]]], None),
260+
(
261+
games.create_EFG_for_nxn_bimatrix_coordination_game(3),
262+
[
263+
[[1, 0, 0], [1, 0, 0]],
264+
[["1/2", "1/2", 0], ["1/2", "1/2", 0]],
265+
[[0, 1, 0], [0, 1, 0]],
266+
[[0, "1/2", "1/2"], [0, "1/2", "1/2"]],
267+
[["1/3", "1/3", "1/3"], ["1/3", "1/3", "1/3"]],
268+
[["1/2", 0, "1/2"], ["1/2", 0, "1/2"]],
269+
[[0, 0, 1], [0, 0, 1]],
270+
],
271+
None,
272+
),
273+
(
274+
games.create_EFG_for_nxn_bimatrix_coordination_game(4),
275+
[[[1, 0, 0, 0], [1, 0, 0, 0]]],
276+
1,
277+
),
278+
(
279+
games.create_EFG_for_6x6_bimatrix_with_long_LH_paths_and_unique_eq(),
280+
[
281+
[["1/30", "1/6", "3/10", "3/10", "1/6", "1/30"],
282+
["1/6", "1/30", "3/10", "3/10", "1/30", "1/6"]],
283+
],
284+
None
285+
),
286+
]
287+
)
288+
def test_lcp_strategy_rational(game: gbt.Game, mixed_strategy_prof_data: list,
289+
stop_after: typing.Union[None, int]):
290+
"""Test calls of LCP for mixed strategy equilibria, rational precision
291+
using max_regret (internal consistency); and comparison to a set of previously
292+
computed equilibria using this function (regression test).
293+
294+
This sequence will correspond to the full set of all computed equilibria if stop_after
295+
is None, else the first stop_after-many equilibria.
296+
"""
297+
result = gbt.nash.lcp_solve(game, use_strategic=True, rational=True, stop_after=stop_after)
298+
299+
if stop_after:
300+
result = gbt.nash.lcp_solve(game, use_strategic=True, stop_after=stop_after)
301+
assert len(result.equilibria) == stop_after
302+
else:
303+
# compute all
304+
result = gbt.nash.lcp_solve(game, use_strategic=True)
305+
assert len(result.equilibria) == len(mixed_strategy_prof_data)
306+
for eq, exp in zip(result.equilibria, mixed_strategy_prof_data):
307+
assert eq.max_regret() == 0
308+
expected = game.mixed_strategy_profile(rational=True, data=exp)
309+
assert eq == expected
235310

236311

237312
def test_lcp_behavior_double():

0 commit comments

Comments
 (0)