From 9e399c4a949d03ec2ee3b7a62afed98b951327be Mon Sep 17 00:00:00 2001 From: Rahul Savani Date: Wed, 12 Nov 2025 19:37:47 +0000 Subject: [PATCH 01/17] remove use of poker.efg in test suite --- tests/games.py | 10 ---------- tests/test_extensive.py | 2 +- tests/test_nash.py | 39 +++++++++++++++------------------------ tests/test_node.py | 20 ++++++++++---------- 4 files changed, 26 insertions(+), 45 deletions(-) diff --git a/tests/games.py b/tests/games.py index f428edb17..55f621ffd 100644 --- a/tests/games.py +++ b/tests/games.py @@ -113,16 +113,6 @@ def create_mixed_behav_game_efg() -> gbt.Game: return read_from_file("mixed_behavior_game.efg") -def create_1_card_poker_efg() -> gbt.Game: - """ - Returns - ------- - Game - One-card two-player poker game, as used in the user guide - """ - return read_from_file("poker.efg") - - def create_myerson_2_card_poker_efg() -> gbt.Game: """ Returns diff --git a/tests/test_extensive.py b/tests/test_extensive.py index 25a47b8eb..6d86dd463 100644 --- a/tests/test_extensive.py +++ b/tests/test_extensive.py @@ -54,7 +54,7 @@ def test_game_add_players_nolabel(): ("e01.efg", True), ("e02.efg", True), ("cent3.efg", True), - ("poker.efg", True), + ("myerson_2_card_poker.efg", True), ("basic_extensive_game.efg", True), # Games with perfect recall from generated games (game_input is a gbt.Game object) diff --git a/tests/test_nash.py b/tests/test_nash.py index 4d35c57d8..49a078888 100644 --- a/tests/test_nash.py +++ b/tests/test_nash.py @@ -19,20 +19,20 @@ def test_enumpure_strategy(): """Test calls of enumeration of pure strategies.""" - game = games.read_from_file("poker.efg") + game = games.read_from_file("myerson_2_card_poker.efg") assert len(gbt.nash.enumpure_solve(game, use_strategic=True).equilibria) == 0 def test_enumpure_agent(): """Test calls of enumeration of pure agent strategies.""" - game = games.read_from_file("poker.efg") + game = games.read_from_file("myerson_2_card_poker.efg") assert len(gbt.nash.enumpure_solve(game, use_strategic=False).equilibria) == 0 def test_enummixed_double(): """Test calls of enumeration of mixed strategy equilibria for 2-player games, floating-point. """ - game = games.read_from_file("poker.efg") + game = games.read_from_file("myerson_2_card_poker.efg") result = gbt.nash.enummixed_solve(game, rational=False) assert len(result.equilibria) == 1 # For floating-point results are not exact, so we skip testing exact values for now @@ -44,7 +44,6 @@ def test_enummixed_double(): "game,mixed_strategy_prof_data", [ # Zero-sum games - (games.create_1_card_poker_efg(), [[["1/3", "2/3", 0, 0], ["2/3", "1/3"]]]), (games.create_myerson_2_card_poker_efg(), [[["1/3", "2/3", 0, 0], ["2/3", "1/3"]]]), # Non-zero-sum games (games.create_one_shot_trust_efg(), [[[0, 1], ["1/2", "1/2"]], @@ -90,11 +89,6 @@ def test_enummixed_rational(game: gbt.Game, mixed_strategy_prof_data: list): "game,mixed_behav_prof_data,stop_after", [ # 2-player zero-sum games - ( - games.create_1_card_poker_efg(), - [[[[1, 0], ["1/3", "2/3"]], [["2/3", "1/3"]]]], - None, - ), ( games.create_myerson_2_card_poker_efg(), [[[[1, 0], ["1/3", "2/3"]], [["2/3", "1/3"]]]], @@ -240,7 +234,7 @@ def are_the_same(game, found, candidate): def test_lcp_strategy_double(): """Test calls of LCP for mixed strategy equilibria, floating-point.""" - game = games.read_from_file("poker.efg") + game = games.read_from_file("myerson_2_card_poker.efg") result = gbt.nash.lcp_solve(game, use_strategic=True, rational=False) assert len(result.equilibria) == 1 # For floating-point results are not exact, so we skip testing exact values for now @@ -252,7 +246,6 @@ def test_lcp_strategy_double(): "game,mixed_strategy_prof_data,stop_after", [ # Zero-sum games - (games.create_1_card_poker_efg(), [[["1/3", "2/3", 0, 0], ["2/3", "1/3"]]], None), (games.create_myerson_2_card_poker_efg(), [[["1/3", "2/3", 0, 0], ["2/3", "1/3"]]], None), (games.create_kuhn_poker_efg(), [games.kuhn_poker_lcp_first_mixed_strategy_prof()], 1), # Non-zero-sum games @@ -311,7 +304,7 @@ def test_lcp_strategy_rational(game: gbt.Game, mixed_strategy_prof_data: list, def test_lcp_behavior_double(): """Test calls of LCP for mixed behavior equilibria, floating-point.""" - game = games.read_from_file("poker.efg") + game = games.read_from_file("myerson_2_card_poker.efg") result = gbt.nash.lcp_solve(game, use_strategic=False, rational=False) assert len(result.equilibria) == 1 # For floating-point results are not exact, so we skip testing exact values for now @@ -323,7 +316,6 @@ def test_lcp_behavior_double(): "game,mixed_behav_prof_data", [ # Zero-sum games (also tested with lp solve) - (games.create_1_card_poker_efg(), [[[1, 0], ["1/3", "2/3"]], [["2/3", "1/3"]]]), (games.create_myerson_2_card_poker_efg(), [[[1, 0], ["1/3", "2/3"]], [["2/3", "1/3"]]]), ( games.create_kuhn_poker_efg(), @@ -380,7 +372,7 @@ def test_lcp_behavior_rational(game: gbt.Game, mixed_behav_prof_data: list): def test_lp_strategy_double(): """Test calls of LP for mixed strategy equilibria, floating-point.""" - game = games.read_from_file("poker.efg") + game = games.read_from_file("myerson_2_card_poker.efg") result = gbt.nash.lp_solve(game, use_strategic=True, rational=False) assert len(result.equilibria) == 1 # For floating-point results are not exact, so we skip testing exact values for now @@ -390,7 +382,7 @@ def test_lp_strategy_double(): @pytest.mark.nash_lp_strategy def test_lp_strategy_rational(): """Test calls of LP for mixed strategy equilibria, rational precision.""" - game = games.read_from_file("poker.efg") + game = games.read_from_file("myerson_2_card_poker.efg") result = gbt.nash.lp_solve(game, use_strategic=True, rational=True) assert len(result.equilibria) == 1 expected = game.mixed_strategy_profile( @@ -405,7 +397,7 @@ def test_lp_strategy_rational(): def test_lp_behavior_double(): """Test calls of LP for mixed behavior equilibria, floating-point.""" - game = games.read_from_file("poker.efg") + game = games.read_from_file("myerson_2_card_poker.efg") result = gbt.nash.lp_solve(game, use_strategic=False, rational=False) assert len(result.equilibria) == 1 # For floating-point results are not exact, so we skip testing exact values for now @@ -420,7 +412,6 @@ def test_lp_behavior_double(): games.create_two_player_perfect_info_win_lose_efg(), [[[0, 1], [1, 0]], [[1, 0], [1, 0]]], ), - (games.create_1_card_poker_efg(), [[[1, 0], ["1/3", "2/3"]], [["2/3", "1/3"]]]), ( games.create_myerson_2_card_poker_efg(), [[[1, 0], ["1/3", "2/3"]], [["2/3", "1/3"]]], @@ -456,47 +447,47 @@ def test_lp_behavior_rational(game: gbt.Game, mixed_behav_prof_data: list): def test_liap_strategy(): """Test calls of liap for mixed strategy equilibria.""" - game = games.read_from_file("poker.efg") + game = games.read_from_file("myerson_2_card_poker.efg") _ = gbt.nash.liap_solve(game.mixed_strategy_profile()) def test_liap_behavior(): """Test calls of liap for mixed behavior equilibria.""" - game = games.read_from_file("poker.efg") + game = games.read_from_file("myerson_2_card_poker.efg") _ = gbt.nash.liap_solve(game.mixed_behavior_profile()) def test_simpdiv_strategy(): """Test calls of simplicial subdivision for mixed strategy equilibria.""" - game = games.read_from_file("poker.efg") + game = games.read_from_file("myerson_2_card_poker.efg") result = gbt.nash.simpdiv_solve(game.mixed_strategy_profile(rational=True)) assert len(result.equilibria) == 1 def test_ipa_strategy(): """Test calls of IPA for mixed strategy equilibria.""" - game = games.read_from_file("poker.efg") + game = games.read_from_file("myerson_2_card_poker.efg") result = gbt.nash.ipa_solve(game) assert len(result.equilibria) == 1 def test_gnm_strategy(): """Test calls of GNM for mixed strategy equilibria.""" - game = games.read_from_file("poker.efg") + game = games.read_from_file("myerson_2_card_poker.efg") result = gbt.nash.gnm_solve(game) assert len(result.equilibria) == 1 def test_logit_strategy(): """Test calls of logit for mixed strategy equilibria.""" - game = games.read_from_file("poker.efg") + game = games.read_from_file("myerson_2_card_poker.efg") result = gbt.nash.logit_solve(game, use_strategic=True) assert len(result.equilibria) == 1 def test_logit_behavior(): """Test calls of logit for behavior equilibria.""" - game = games.read_from_file("poker.efg") + game = games.read_from_file("myerson_2_card_poker.efg") result = gbt.nash.logit_solve(game, use_strategic=False) assert len(result.equilibria) == 1 diff --git a/tests/test_node.py b/tests/test_node.py index 8636a7559..3f20da2c7 100644 --- a/tests/test_node.py +++ b/tests/test_node.py @@ -791,26 +791,26 @@ def test_node_plays(): def test_node_children_action_label(): - game = games.read_from_file("poker.efg") - assert game.root.children["Red"] == game.root.children[0] - assert game.root.children["Black"].children["Fold"] == game.root.children[1].children[1] + game = games.read_from_file("myerson_2_card_poker.efg") + assert game.root.children["RED"] == game.root.children[0] + assert game.root.children["BLACK"].children["FOLD"] == game.root.children[1].children[1] def test_node_children_action(): - game = games.read_from_file("poker.efg") - assert game.root.children[game.root.infoset.actions["Red"]] == game.root.children[0] + game = games.read_from_file("myerson_2_card_poker.efg") + assert game.root.children[game.root.infoset.actions["RED"]] == game.root.children[0] def test_node_children_nonexistent_action(): - game = games.read_from_file("poker.efg") + game = games.read_from_file("myerson_2_card_poker.efg") with pytest.raises(ValueError): - _ = game.root.children["Green"] + _ = game.root.children["GREEN"] def test_node_children_other_infoset_action(): - game = games.read_from_file("poker.efg") + game = games.read_from_file("myerson_2_card_poker.efg") with pytest.raises(ValueError): - _ = game.root.children[game.root.children[0].infoset.actions["Raise"]] + _ = game.root.children[game.root.children[0].infoset.actions["RAISE"]] @pytest.mark.parametrize( @@ -821,7 +821,7 @@ def test_node_children_other_infoset_action(): pytest.param(games.read_from_file("cent3.efg")), pytest.param(games.read_from_file("e01.efg")), pytest.param(games.read_from_file("e02.efg")), - pytest.param(games.read_from_file("poker.efg")), + pytest.param(games.read_from_file("myerson_2_card_poker.efg")), pytest.param(gbt.Game.new_tree()), ], ) From eba5da527fe9289c8beb2cd729a7de626ca9754c Mon Sep 17 00:00:00 2001 From: rahulsavani Date: Thu, 13 Nov 2025 18:30:10 +0000 Subject: [PATCH 02/17] myerson_2_card_poker.efg -> stripped_down_poker.efg --- tests/games.py | 15 +- tests/test_actions.py | 28 +- tests/test_behav.py | 456 +++++++++++----------- tests/test_extensive.py | 10 +- tests/test_games/myerson_2_card_poker.efg | 14 - tests/test_games/poker.efg | 14 - tests/test_mixed.py | 190 ++++----- tests/test_nash.py | 40 +- tests/test_node.py | 20 +- 9 files changed, 378 insertions(+), 409 deletions(-) delete mode 100644 tests/test_games/myerson_2_card_poker.efg delete mode 100644 tests/test_games/poker.efg diff --git a/tests/games.py b/tests/games.py index 55f621ffd..d08178be2 100644 --- a/tests/games.py +++ b/tests/games.py @@ -113,17 +113,20 @@ def create_mixed_behav_game_efg() -> gbt.Game: return read_from_file("mixed_behavior_game.efg") -def create_myerson_2_card_poker_efg() -> gbt.Game: +def create_stripped_down_poker_efg() -> gbt.Game: """ Returns ------- Game - Simplied "stripped down" version of Myerson 2-card poker: - Two-player extensive poker game with a chance move with two moves, - then player 1 can raise or fold; after raising player 2 is in an infoset with two nodes - and can choose to meet or pass + Stripped-Down Poker: A Classroom Game with Signaling and Bluffing + Reiley et al (2008) + + Two-player extensive-form poker game between Fred and Alice + Chance deals King or Queen to Fred + Fred can then Bet or Fold; after raising Alice is in an infoset with two nodes + and can choose to Call or Fold """ - return read_from_file("myerson_2_card_poker.efg") + return read_from_file("stripped_down_poker.efg") def create_kuhn_poker_efg() -> gbt.Game: diff --git a/tests/test_actions.py b/tests/test_actions.py index 971a65cbb..72cb506a5 100644 --- a/tests/test_actions.py +++ b/tests/test_actions.py @@ -7,7 +7,7 @@ @pytest.mark.parametrize( "game,label", - [(games.create_myerson_2_card_poker_efg(), "random label")] + [(games.create_stripped_down_poker_efg(), "random label")] ) def test_set_action_label(game: gbt.Game, label: str): game.root.infoset.actions[0].label = label @@ -16,9 +16,9 @@ def test_set_action_label(game: gbt.Game, label: str): @pytest.mark.parametrize( "game,inprobs,outprobs", - [(games.create_myerson_2_card_poker_efg(), + [(games.create_stripped_down_poker_efg(), [0.75, 0.25], [0.75, 0.25]), - (games.create_myerson_2_card_poker_efg(), + (games.create_stripped_down_poker_efg(), ["16/17", "1/17"], [gbt.Rational("16/17"), gbt.Rational("1/17")])] ) def test_set_chance_valid_probability(game: gbt.Game, inprobs: list, outprobs: list): @@ -29,9 +29,9 @@ def test_set_chance_valid_probability(game: gbt.Game, inprobs: list, outprobs: l @pytest.mark.parametrize( "game,inprobs", - [(games.create_myerson_2_card_poker_efg(), [0.75, -0.10]), - (games.create_myerson_2_card_poker_efg(), [0.75, 0.40]), - (games.create_myerson_2_card_poker_efg(), ["foo", "bar"])] + [(games.create_stripped_down_poker_efg(), [0.75, -0.10]), + (games.create_stripped_down_poker_efg(), [0.75, 0.40]), + (games.create_stripped_down_poker_efg(), ["foo", "bar"])] ) def test_set_chance_improper_probability(game: gbt.Game, inprobs: list): with pytest.raises(ValueError): @@ -40,8 +40,8 @@ def test_set_chance_improper_probability(game: gbt.Game, inprobs: list): @pytest.mark.parametrize( "game,inprobs", - [(games.create_myerson_2_card_poker_efg(), [0.25, 0.75, 0.25]), - (games.create_myerson_2_card_poker_efg(), [1.00])] + [(games.create_stripped_down_poker_efg(), [0.25, 0.75, 0.25]), + (games.create_stripped_down_poker_efg(), [1.00])] ) def test_set_chance_bad_dimension(game: gbt.Game, inprobs: list): with pytest.raises(IndexError): @@ -50,7 +50,7 @@ def test_set_chance_bad_dimension(game: gbt.Game, inprobs: list): @pytest.mark.parametrize( "game", - [games.create_myerson_2_card_poker_efg()] + [games.create_stripped_down_poker_efg()] ) def test_set_chance_personal(game: gbt.Game): with pytest.raises(gbt.UndefinedOperationError): @@ -59,7 +59,7 @@ def test_set_chance_personal(game: gbt.Game): @pytest.mark.parametrize( "game", - [games.create_myerson_2_card_poker_efg()] + [games.create_stripped_down_poker_efg()] ) def test_action_precedes(game: gbt.Game): child = game.root.children[0] @@ -69,7 +69,7 @@ def test_action_precedes(game: gbt.Game): @pytest.mark.parametrize( "game", - [games.create_myerson_2_card_poker_efg()] + [games.create_stripped_down_poker_efg()] ) def test_action_precedes_nonnode(game: gbt.Game): with pytest.raises(TypeError): @@ -78,7 +78,7 @@ def test_action_precedes_nonnode(game: gbt.Game): @pytest.mark.parametrize( "game", - [games.create_myerson_2_card_poker_efg()] + [games.create_stripped_down_poker_efg()] ) def test_action_delete_personal(game: gbt.Game): node = game.players[0].infosets[0].members[0] @@ -90,7 +90,7 @@ def test_action_delete_personal(game: gbt.Game): @pytest.mark.parametrize( "game", - [games.create_myerson_2_card_poker_efg()] + [games.create_stripped_down_poker_efg()] ) def test_action_delete_last(game: gbt.Game): node = game.players[0].infosets[0].members[0] @@ -103,7 +103,7 @@ def test_action_delete_last(game: gbt.Game): @pytest.mark.parametrize( "game", [games.read_from_file("chance_root_3_moves_only_one_nonzero_prob.efg"), - games.create_myerson_2_card_poker_efg(), + games.create_stripped_down_poker_efg(), games.read_from_file("chance_root_5_moves_no_nonterm_player_nodes.efg")] ) def test_action_delete_chance(game: gbt.Game): diff --git a/tests/test_behav.py b/tests/test_behav.py index 4514997be..dbf096167 100644 --- a/tests/test_behav.py +++ b/tests/test_behav.py @@ -28,10 +28,10 @@ def _set_action_probs(profile: gbt.MixedBehaviorProfile, probs: list, rational_f (games.create_mixed_behav_game_efg(), 0, "3", True), (games.create_mixed_behav_game_efg(), 1, "3", True), (games.create_mixed_behav_game_efg(), 2, "13/4", True), - (games.create_myerson_2_card_poker_efg(), 0, -1.25, False), - (games.create_myerson_2_card_poker_efg(), 1, 1.25, True), - (games.create_myerson_2_card_poker_efg(), 0, "-5/4", True), - (games.create_myerson_2_card_poker_efg(), 1, "5/4", True) + (games.create_stripped_down_poker_efg(), 0, -0.25, False), + (games.create_stripped_down_poker_efg(), 1, 0.25, True), + (games.create_stripped_down_poker_efg(), 0, "-1/4", True), + (games.create_stripped_down_poker_efg(), 1, "1/4", True) ] ) def test_payoff_reference(game: gbt.Game, player_idx: int, payoff: typing.Union[str, float], @@ -49,10 +49,10 @@ def test_payoff_reference(game: gbt.Game, player_idx: int, payoff: typing.Union[ (games.create_mixed_behav_game_efg(), "Player 1", "3", True), (games.create_mixed_behav_game_efg(), "Player 2", "3", True), (games.create_mixed_behav_game_efg(), "Player 3", "13/4", True), - (games.create_myerson_2_card_poker_efg(), "Player 1", -1.25, False), - (games.create_myerson_2_card_poker_efg(), "Player 2", 1.25, False), - (games.create_myerson_2_card_poker_efg(), "Player 1", "-5/4", True), - (games.create_myerson_2_card_poker_efg(), "Player 2", "5/4", True), + (games.create_stripped_down_poker_efg(), "Fred", -0.25, False), + (games.create_stripped_down_poker_efg(), "Alice", 0.25, False), + (games.create_stripped_down_poker_efg(), "Fred", "-1/4", True), + (games.create_stripped_down_poker_efg(), "Alice", "1/4", True), ] ) def test_payoff_by_label_reference(game: gbt.Game, label: str, payoff: typing.Union[str, float], @@ -66,8 +66,8 @@ def test_payoff_by_label_reference(game: gbt.Game, label: str, payoff: typing.Un "game,rational_flag", [(games.create_mixed_behav_game_efg(), False), (games.create_mixed_behav_game_efg(), True), - (games.create_myerson_2_card_poker_efg(), False), - (games.create_myerson_2_card_poker_efg(), True), + (games.create_stripped_down_poker_efg(), False), + (games.create_stripped_down_poker_efg(), True), ] ) def test_is_defined_at(game: gbt.Game, rational_flag: bool): @@ -85,12 +85,12 @@ def test_is_defined_at(game: gbt.Game, rational_flag: bool): (games.create_mixed_behav_game_efg(), "Infoset 1:1", True), (games.create_mixed_behav_game_efg(), "Infoset 2:1", True), (games.create_mixed_behav_game_efg(), "Infoset 3:1", True), - (games.create_myerson_2_card_poker_efg(), "(1,1)", False), - (games.create_myerson_2_card_poker_efg(), "(1,2)", False), - (games.create_myerson_2_card_poker_efg(), "(2,1)", False), - (games.create_myerson_2_card_poker_efg(), "(1,1)", True), - (games.create_myerson_2_card_poker_efg(), "(1,2)", True), - (games.create_myerson_2_card_poker_efg(), "(2,1)", True), + (games.create_stripped_down_poker_efg(), "(1,1)", False), + (games.create_stripped_down_poker_efg(), "(1,2)", False), + (games.create_stripped_down_poker_efg(), "(2,1)", False), + (games.create_stripped_down_poker_efg(), "(1,1)", True), + (games.create_stripped_down_poker_efg(), "(1,2)", True), + (games.create_stripped_down_poker_efg(), "(2,1)", True), ] ) def test_is_defined_at_by_label(game: gbt.Game, label: str, rational_flag: bool): @@ -113,18 +113,18 @@ def test_is_defined_at_by_label(game: gbt.Game, label: str, rational_flag: bool) (games.create_mixed_behav_game_efg(), 1, 0, 1, "1/2", True), (games.create_mixed_behav_game_efg(), 2, 0, 0, "1/2", True), (games.create_mixed_behav_game_efg(), 2, 0, 1, "1/2", True), - (games.create_myerson_2_card_poker_efg(), 0, 0, 0, 0.5, False), - (games.create_myerson_2_card_poker_efg(), 0, 0, 1, 0.5, False), - (games.create_myerson_2_card_poker_efg(), 0, 1, 0, 0.5, False), - (games.create_myerson_2_card_poker_efg(), 0, 1, 1, 0.5, False), - (games.create_myerson_2_card_poker_efg(), 1, 0, 0, 0.5, False), - (games.create_myerson_2_card_poker_efg(), 1, 0, 1, 0.5, False), - (games.create_myerson_2_card_poker_efg(), 0, 0, 0, "1/2", True), - (games.create_myerson_2_card_poker_efg(), 0, 0, 1, "1/2", True), - (games.create_myerson_2_card_poker_efg(), 0, 1, 0, "1/2", True), - (games.create_myerson_2_card_poker_efg(), 0, 1, 1, "1/2", True), - (games.create_myerson_2_card_poker_efg(), 1, 0, 0, "1/2", True), - (games.create_myerson_2_card_poker_efg(), 1, 0, 1, "1/2", True), + (games.create_stripped_down_poker_efg(), 0, 0, 0, 0.5, False), + (games.create_stripped_down_poker_efg(), 0, 0, 1, 0.5, False), + (games.create_stripped_down_poker_efg(), 0, 1, 0, 0.5, False), + (games.create_stripped_down_poker_efg(), 0, 1, 1, 0.5, False), + (games.create_stripped_down_poker_efg(), 1, 0, 0, 0.5, False), + (games.create_stripped_down_poker_efg(), 1, 0, 1, 0.5, False), + (games.create_stripped_down_poker_efg(), 0, 0, 0, "1/2", True), + (games.create_stripped_down_poker_efg(), 0, 0, 1, "1/2", True), + (games.create_stripped_down_poker_efg(), 0, 1, 0, "1/2", True), + (games.create_stripped_down_poker_efg(), 0, 1, 1, "1/2", True), + (games.create_stripped_down_poker_efg(), 1, 0, 0, "1/2", True), + (games.create_stripped_down_poker_efg(), 1, 0, 1, "1/2", True), ] ) def test_profile_indexing_by_player_infoset_action_idx_reference(game: gbt.Game, player_idx: int, @@ -152,10 +152,8 @@ def test_profile_indexing_by_player_infoset_action_idx_reference(game: gbt.Game, (games.create_mixed_behav_game_efg(), "D2", "1/2", True), (games.create_mixed_behav_game_efg(), "U3", "1/2", True), (games.create_mixed_behav_game_efg(), "D3", "1/2", True), - (games.create_myerson_2_card_poker_efg(), "MEET", 0.5, False), - (games.create_myerson_2_card_poker_efg(), "PASS", 0.5, False), - (games.create_myerson_2_card_poker_efg(), "MEET", "1/2", True), - (games.create_myerson_2_card_poker_efg(), "PASS", "1/2", True), + (games.create_stripped_down_poker_efg(), "Call", 0.5, False), + (games.create_stripped_down_poker_efg(), "Call", "1/2", True), ] ) def test_profile_indexing_by_action_label_reference(game: gbt.Game, action_label: str, @@ -171,14 +169,14 @@ def test_profile_indexing_by_action_label_reference(game: gbt.Game, action_label "game,action_label,rational_flag,error", [(games.create_mixed_behav_game_efg(), "U4", True, KeyError), (games.create_mixed_behav_game_efg(), "U4", False, KeyError), - (games.create_myerson_2_card_poker_efg(), "RAISE", True, ValueError), - (games.create_myerson_2_card_poker_efg(), "RAISE", False, ValueError), - (games.create_myerson_2_card_poker_efg(), "FOLD", True, ValueError), - (games.create_myerson_2_card_poker_efg(), "FOLD", False, ValueError), - (games.create_myerson_2_card_poker_efg(), "RAISEFOLD", True, KeyError), - (games.create_myerson_2_card_poker_efg(), "RAISEFOLD", False, KeyError), - (games.create_myerson_2_card_poker_efg(), "MISSING", True, KeyError), - (games.create_myerson_2_card_poker_efg(), "MISSING", False, KeyError), + (games.create_stripped_down_poker_efg(), "Bet", True, ValueError), + (games.create_stripped_down_poker_efg(), "Bet", False, ValueError), + (games.create_stripped_down_poker_efg(), "Fold", True, ValueError), + (games.create_stripped_down_poker_efg(), "Fold", False, ValueError), + (games.create_stripped_down_poker_efg(), "BetFold", True, KeyError), + (games.create_stripped_down_poker_efg(), "BetFold", False, KeyError), + (games.create_stripped_down_poker_efg(), "MISSING", True, KeyError), + (games.create_stripped_down_poker_efg(), "MISSING", False, KeyError), ] ) def test_profile_indexing_by_invalid_action_label(game: gbt.Game, action_label: str, @@ -214,14 +212,14 @@ def test_profile_indexing_by_invalid_infoset_label(rational_flag: bool): (games.create_mixed_behav_game_efg(), "Infoset 1:1", "D1", 0.5, False), (games.create_mixed_behav_game_efg(), "Infoset 1:1", "U1", "1/2", True), (games.create_mixed_behav_game_efg(), "Infoset 1:1", "D1", "1/2", True), - (games.create_myerson_2_card_poker_efg(), "(1,1)", "RAISE", 0.5, False), - (games.create_myerson_2_card_poker_efg(), "(1,1)", "FOLD", 0.5, False), - (games.create_myerson_2_card_poker_efg(), "(1,2)", "RAISE", 0.5, False), - (games.create_myerson_2_card_poker_efg(), "(1,2)", "FOLD", 0.5, False), - (games.create_myerson_2_card_poker_efg(), "(2,1)", "MEET", 0.5, False), - (games.create_myerson_2_card_poker_efg(), "(2,1)", "PASS", 0.5, False), - (games.create_myerson_2_card_poker_efg(), "(2,1)", "MEET", "1/2", True), - (games.create_myerson_2_card_poker_efg(), "(2,1)", "PASS", "1/2", True), + (games.create_stripped_down_poker_efg(), "(1,1)", "Bet", 0.5, False), + (games.create_stripped_down_poker_efg(), "(1,1)", "Fold", 0.5, False), + (games.create_stripped_down_poker_efg(), "(1,2)", "Bet", 0.5, False), + (games.create_stripped_down_poker_efg(), "(1,2)", "Fold", 0.5, False), + (games.create_stripped_down_poker_efg(), "(2,1)", "Call", 0.5, False), + (games.create_stripped_down_poker_efg(), "(2,1)", "Fold", 0.5, False), + (games.create_stripped_down_poker_efg(), "(2,1)", "Call", "1/2", True), + (games.create_stripped_down_poker_efg(), "(2,1)", "Fold", "1/2", True), ] ) def test_profile_indexing_by_infoset_and_action_labels_reference(game: gbt.Game, @@ -243,14 +241,14 @@ def test_profile_indexing_by_infoset_and_action_labels_reference(game: gbt.Game, (games.create_mixed_behav_game_efg(), "Player 1", "Infoset 1:1", "D1", 0.5, False), (games.create_mixed_behav_game_efg(), "Player 1", "Infoset 1:1", "U1", "1/2", True), (games.create_mixed_behav_game_efg(), "Player 1", "Infoset 1:1", "D1", "1/2", True), - (games.create_myerson_2_card_poker_efg(), "Player 1", "(1,1)", "RAISE", 0.5, False), - (games.create_myerson_2_card_poker_efg(), "Player 1", "(1,1)", "FOLD", 0.5, False), - (games.create_myerson_2_card_poker_efg(), "Player 1", "(1,2)", "RAISE", 0.5, False), - (games.create_myerson_2_card_poker_efg(), "Player 1", "(1,2)", "FOLD", 0.5, False), - (games.create_myerson_2_card_poker_efg(), "Player 2", "(2,1)", "MEET", 0.5, False), - (games.create_myerson_2_card_poker_efg(), "Player 2", "(2,1)", "PASS", 0.5, False), - (games.create_myerson_2_card_poker_efg(), "Player 2", "(2,1)", "MEET", "1/2", True), - (games.create_myerson_2_card_poker_efg(), "Player 2", "(2,1)", "PASS", "1/2", True), + (games.create_stripped_down_poker_efg(), "Fred", "(1,1)", "Bet", 0.5, False), + (games.create_stripped_down_poker_efg(), "Fred", "(1,1)", "Fold", 0.5, False), + (games.create_stripped_down_poker_efg(), "Fred", "(1,2)", "Bet", 0.5, False), + (games.create_stripped_down_poker_efg(), "Fred", "(1,2)", "Fold", 0.5, False), + (games.create_stripped_down_poker_efg(), "Alice", "(2,1)", "Call", 0.5, False), + (games.create_stripped_down_poker_efg(), "Alice", "(2,1)", "Fold", 0.5, False), + (games.create_stripped_down_poker_efg(), "Alice", "(2,1)", "Call", "1/2", True), + (games.create_stripped_down_poker_efg(), "Alice", "(2,1)", "Fold", "1/2", True), ] ) def test_profile_indexing_by_player_infoset_action_labels_reference(game: gbt.Game, @@ -273,8 +271,8 @@ def test_profile_indexing_by_player_infoset_action_labels_reference(game: gbt.Ga (games.create_mixed_behav_game_efg(), "1:1", "U2", False), (games.create_mixed_behav_game_efg(), "1:1", "U4", True), # U4 isn't in the game (games.create_mixed_behav_game_efg(), "1:1", "U4", False), - (games.create_myerson_2_card_poker_efg(), "(1,1)", "MEET", True), # MEET at different iset - (games.create_myerson_2_card_poker_efg(), "(1,1)", "MEET", False), + (games.create_stripped_down_poker_efg(), "(1,1)", "MEET", True), # MEET at different iset + (games.create_stripped_down_poker_efg(), "(1,1)", "MEET", False), ] ) def test_profile_indexing_by_invalid_infoset_or_action_label(game: gbt.Game, infoset_label: str, @@ -292,12 +290,12 @@ def test_profile_indexing_by_invalid_infoset_or_action_label(game: gbt.Game, inf (games.create_mixed_behav_game_efg(), 0, 0, ["1/2", "1/2"], True), (games.create_mixed_behav_game_efg(), 1, 0, ["1/2", "1/2"], True), (games.create_mixed_behav_game_efg(), 2, 0, ["1/2", "1/2"], True), - (games.create_myerson_2_card_poker_efg(), 0, 0, [0.5, 0.5], False), - (games.create_myerson_2_card_poker_efg(), 0, 1, [0.5, 0.5], False), - (games.create_myerson_2_card_poker_efg(), 1, 0, [0.5, 0.5], False), - (games.create_myerson_2_card_poker_efg(), 0, 0, ["1/2", "1/2"], True), - (games.create_myerson_2_card_poker_efg(), 0, 1, ["1/2", "1/2"], True), - (games.create_myerson_2_card_poker_efg(), 1, 0, ["1/2", "1/2"], True), + (games.create_stripped_down_poker_efg(), 0, 0, [0.5, 0.5], False), + (games.create_stripped_down_poker_efg(), 0, 1, [0.5, 0.5], False), + (games.create_stripped_down_poker_efg(), 1, 0, [0.5, 0.5], False), + (games.create_stripped_down_poker_efg(), 0, 0, ["1/2", "1/2"], True), + (games.create_stripped_down_poker_efg(), 0, 1, ["1/2", "1/2"], True), + (games.create_stripped_down_poker_efg(), 1, 0, ["1/2", "1/2"], True), ] ) def test_profile_indexing_by_player_and_infoset_idx_reference(game: gbt.Game, @@ -318,12 +316,12 @@ def test_profile_indexing_by_player_and_infoset_idx_reference(game: gbt.Game, (games.create_mixed_behav_game_efg(), 0, "Infoset 1:1", ["1/2", "1/2"], True), (games.create_mixed_behav_game_efg(), 1, "Infoset 2:1", ["1/2", "1/2"], True), (games.create_mixed_behav_game_efg(), 2, "Infoset 3:1", ["1/2", "1/2"], True), - (games.create_myerson_2_card_poker_efg(), 0, "(1,1)", [0.5, 0.5], False), - (games.create_myerson_2_card_poker_efg(), 0, "(1,2)", [0.5, 0.5], False), - (games.create_myerson_2_card_poker_efg(), 1, "(2,1)", [0.5, 0.5], False), - (games.create_myerson_2_card_poker_efg(), 0, "(1,1)", ["1/2", "1/2"], True), - (games.create_myerson_2_card_poker_efg(), 0, "(1,2)", ["1/2", "1/2"], True), - (games.create_myerson_2_card_poker_efg(), 1, "(2,1)", ["1/2", "1/2"], True), + (games.create_stripped_down_poker_efg(), 0, "(1,1)", [0.5, 0.5], False), + (games.create_stripped_down_poker_efg(), 0, "(1,2)", [0.5, 0.5], False), + (games.create_stripped_down_poker_efg(), 1, "(2,1)", [0.5, 0.5], False), + (games.create_stripped_down_poker_efg(), 0, "(1,1)", ["1/2", "1/2"], True), + (games.create_stripped_down_poker_efg(), 0, "(1,2)", ["1/2", "1/2"], True), + (games.create_stripped_down_poker_efg(), 1, "(2,1)", ["1/2", "1/2"], True), ] ) def test_profile_indexing_by_player_idx_infoset_label_reference(game: gbt.Game, player_idx: int, @@ -340,8 +338,8 @@ def test_profile_indexing_by_player_idx_infoset_label_reference(game: gbt.Game, "game,player_label,infoset_label,rational_flag", [(games.create_mixed_behav_game_efg(), "Player 1", "1:1", True), # correct: "Infoset 1:1" (games.create_mixed_behav_game_efg(), "Player 1", "1:1", False), - (games.create_myerson_2_card_poker_efg(), "Player 1", "(2,1)", True), # wrong player - (games.create_myerson_2_card_poker_efg(), "Player 1", "(2,1)", False), + (games.create_stripped_down_poker_efg(), "Player 1", "(2,1)", True), # wrong player + (games.create_stripped_down_poker_efg(), "Player 1", "(2,1)", False), ] ) def test_profile_indexing_by_player_and_invalid_infoset_label(game: gbt.Game, @@ -357,8 +355,8 @@ def test_profile_indexing_by_player_and_invalid_infoset_label(game: gbt.Game, "game,player_label,action_label,rational_flag", [(games.create_mixed_behav_game_efg(), "Player 1", "U2", True), (games.create_mixed_behav_game_efg(), "Player 1", "U2", False), - (games.create_myerson_2_card_poker_efg(), "Player 1", "MEET", True), - (games.create_myerson_2_card_poker_efg(), "Player 1", "MEET", False), + (games.create_stripped_down_poker_efg(), "Player 1", "MEET", True), + (games.create_stripped_down_poker_efg(), "Player 1", "MEET", False), ] ) def test_profile_indexing_by_player_and_invalid_action_label(game: gbt.Game, @@ -378,10 +376,10 @@ def test_profile_indexing_by_player_and_invalid_action_label(game: gbt.Game, (games.create_mixed_behav_game_efg(), 0, [["1/2", "1/2"]], True), (games.create_mixed_behav_game_efg(), 1, [["1/2", "1/2"]], True), (games.create_mixed_behav_game_efg(), 2, [["1/2", "1/2"]], True), - (games.create_myerson_2_card_poker_efg(), 0, [[0.5, 0.5], [0.5, 0.5]], False), - (games.create_myerson_2_card_poker_efg(), 1, [[0.5, 0.5]], False), - (games.create_myerson_2_card_poker_efg(), 0, [["1/2", "1/2"], ["1/2", "1/2"]], True), - (games.create_myerson_2_card_poker_efg(), 1, [["1/2", "1/2"]], True), + (games.create_stripped_down_poker_efg(), 0, [[0.5, 0.5], [0.5, 0.5]], False), + (games.create_stripped_down_poker_efg(), 1, [[0.5, 0.5]], False), + (games.create_stripped_down_poker_efg(), 0, [["1/2", "1/2"], ["1/2", "1/2"]], True), + (games.create_stripped_down_poker_efg(), 1, [["1/2", "1/2"]], True), ] ) def test_profile_indexing_by_player_idx_reference(game: gbt.Game, player_idx: int, @@ -402,11 +400,11 @@ def test_profile_indexing_by_player_idx_reference(game: gbt.Game, player_idx: in (games.create_mixed_behav_game_efg(), "Player 1", [["1/2", "1/2"]], True), (games.create_mixed_behav_game_efg(), "Player 2", [["1/2", "1/2"]], True), (games.create_mixed_behav_game_efg(), "Player 3", [["1/2", "1/2"]], True), - (games.create_myerson_2_card_poker_efg(), "Player 1", [[0.5, 0.5], [0.5, 0.5]], False), - (games.create_myerson_2_card_poker_efg(), "Player 2", [[0.5, 0.5]], False), - (games.create_myerson_2_card_poker_efg(), "Player 1", [["1/2", "1/2"], ["1/2", "1/2"]], + (games.create_stripped_down_poker_efg(), "Fred", [[0.5, 0.5], [0.5, 0.5]], False), + (games.create_stripped_down_poker_efg(), "Alice", [[0.5, 0.5]], False), + (games.create_stripped_down_poker_efg(), "Fred", [["1/2", "1/2"], ["1/2", "1/2"]], True), - (games.create_myerson_2_card_poker_efg(), "Player 2", [["1/2", "1/2"]], True), + (games.create_stripped_down_poker_efg(), "Alice", [["1/2", "1/2"]], True), ] ) def test_profile_indexing_by_player_label_reference(game: gbt.Game, player_label: str, @@ -431,18 +429,18 @@ def test_profile_indexing_by_player_label_reference(game: gbt.Game, player_label (games.create_mixed_behav_game_efg(), 3, "9/13", True), (games.create_mixed_behav_game_efg(), 4, "1/98", True), (games.create_mixed_behav_game_efg(), 5, "97/98", True), - (games.create_myerson_2_card_poker_efg(), 0, 0.1, False), - (games.create_myerson_2_card_poker_efg(), 1, 0.2, False), - (games.create_myerson_2_card_poker_efg(), 2, 0.3, False), - (games.create_myerson_2_card_poker_efg(), 3, 0.4, False), - (games.create_myerson_2_card_poker_efg(), 4, 0.5, False), - (games.create_myerson_2_card_poker_efg(), 5, 0.6, False), - (games.create_myerson_2_card_poker_efg(), 0, "1/10", True), - (games.create_myerson_2_card_poker_efg(), 1, "2/10", True), - (games.create_myerson_2_card_poker_efg(), 2, "3/10", True), - (games.create_myerson_2_card_poker_efg(), 3, "4/10", True), - (games.create_myerson_2_card_poker_efg(), 4, "5/10", True), - (games.create_myerson_2_card_poker_efg(), 5, "6/10", True), + (games.create_stripped_down_poker_efg(), 0, 0.1, False), + (games.create_stripped_down_poker_efg(), 1, 0.2, False), + (games.create_stripped_down_poker_efg(), 2, 0.3, False), + (games.create_stripped_down_poker_efg(), 3, 0.4, False), + (games.create_stripped_down_poker_efg(), 4, 0.5, False), + (games.create_stripped_down_poker_efg(), 5, 0.6, False), + (games.create_stripped_down_poker_efg(), 0, "1/10", True), + (games.create_stripped_down_poker_efg(), 1, "2/10", True), + (games.create_stripped_down_poker_efg(), 2, "3/10", True), + (games.create_stripped_down_poker_efg(), 3, "4/10", True), + (games.create_stripped_down_poker_efg(), 4, "5/10", True), + (games.create_stripped_down_poker_efg(), 5, "6/10", True), ] ) def test_set_probabilities_action(game: gbt.Game, action_idx: int, prob: typing.Union[str, float], @@ -469,10 +467,8 @@ def test_set_probabilities_action(game: gbt.Game, action_idx: int, prob: typing. (games.create_mixed_behav_game_efg(), "D2", "9/13", True), (games.create_mixed_behav_game_efg(), "U3", "1/98", True), (games.create_mixed_behav_game_efg(), "D3", "97/98", True), - (games.create_myerson_2_card_poker_efg(), "MEET", 0.3, False), - (games.create_myerson_2_card_poker_efg(), "PASS", 0.4, False), - (games.create_myerson_2_card_poker_efg(), "MEET", "3/10", True), - (games.create_myerson_2_card_poker_efg(), "PASS", "4/10", True), + (games.create_stripped_down_poker_efg(), "Call", 0.3, False), + (games.create_stripped_down_poker_efg(), "Call", "3/10", True), ] ) def test_set_probabilities_action_by_label(game: gbt.Game, label: str, @@ -491,12 +487,12 @@ def test_set_probabilities_action_by_label(game: gbt.Game, label: str, (games.create_mixed_behav_game_efg(), 0, 0, ["7/9", "2/9"], True), (games.create_mixed_behav_game_efg(), 1, 0, ["4/13", "9/13"], True), (games.create_mixed_behav_game_efg(), 2, 0, ["1/98", "97/98"], True), - (games.create_myerson_2_card_poker_efg(), 0, 0, [0.1, 0.9], False), - (games.create_myerson_2_card_poker_efg(), 0, 1, [0.2, 0.8], False), - (games.create_myerson_2_card_poker_efg(), 1, 0, [0.3, 0.7], False), - (games.create_myerson_2_card_poker_efg(), 0, 0, ["1/10", "9/10"], True), - (games.create_myerson_2_card_poker_efg(), 0, 1, ["2/10", "8/10"], True), - (games.create_myerson_2_card_poker_efg(), 1, 0, ["3/10", "7/10"], True), + (games.create_stripped_down_poker_efg(), 0, 0, [0.1, 0.9], False), + (games.create_stripped_down_poker_efg(), 0, 1, [0.2, 0.8], False), + (games.create_stripped_down_poker_efg(), 1, 0, [0.3, 0.7], False), + (games.create_stripped_down_poker_efg(), 0, 0, ["1/10", "9/10"], True), + (games.create_stripped_down_poker_efg(), 0, 1, ["2/10", "8/10"], True), + (games.create_stripped_down_poker_efg(), 1, 0, ["3/10", "7/10"], True), ] ) def test_set_probabilities_infoset(game: gbt.Game, player_idx: int, infoset_idx: int, probs: list, @@ -517,12 +513,12 @@ def test_set_probabilities_infoset(game: gbt.Game, player_idx: int, infoset_idx: (games.create_mixed_behav_game_efg(), "Infoset 1:1", ["7/9", "2/9"], True), (games.create_mixed_behav_game_efg(), "Infoset 2:1", ["4/13", "9/13"], True), (games.create_mixed_behav_game_efg(), "Infoset 3:1", ["1/98", "97/98"], True), - (games.create_myerson_2_card_poker_efg(), "(1,1)", [0.1, 0.9], False), - (games.create_myerson_2_card_poker_efg(), "(1,2)", [0.2, 0.8], False), - (games.create_myerson_2_card_poker_efg(), "(2,1)", [0.3, 0.7], False), - (games.create_myerson_2_card_poker_efg(), "(1,1)", ["1/10", "9/10"], True), - (games.create_myerson_2_card_poker_efg(), "(1,2)", ["2/10", "8/10"], True), - (games.create_myerson_2_card_poker_efg(), "(2,1)", ["3/10", "7/10"], True), + (games.create_stripped_down_poker_efg(), "(1,1)", [0.1, 0.9], False), + (games.create_stripped_down_poker_efg(), "(1,2)", [0.2, 0.8], False), + (games.create_stripped_down_poker_efg(), "(2,1)", [0.3, 0.7], False), + (games.create_stripped_down_poker_efg(), "(1,1)", ["1/10", "9/10"], True), + (games.create_stripped_down_poker_efg(), "(1,2)", ["2/10", "8/10"], True), + (games.create_stripped_down_poker_efg(), "(2,1)", ["3/10", "7/10"], True), ] ) def test_set_probabilities_infoset_by_label(game: gbt.Game, infoset_label: str, probs: list, @@ -542,10 +538,10 @@ def test_set_probabilities_infoset_by_label(game: gbt.Game, infoset_label: str, (games.create_mixed_behav_game_efg(), 0, [["7/9", "2/9"]], True), (games.create_mixed_behav_game_efg(), 1, [["4/13", "9/13"]], True), (games.create_mixed_behav_game_efg(), 2, [["1/98", "97/98"]], True), - (games.create_myerson_2_card_poker_efg(), 0, [[0.1, 0.9], [0.5, 0.5]], False), - (games.create_myerson_2_card_poker_efg(), 1, [[0.6, 0.4]], False), - (games.create_myerson_2_card_poker_efg(), 0, [["1/3", "2/3"], ["1/2", "1/2"]], True), - (games.create_myerson_2_card_poker_efg(), 1, [["2/3", "1/3"]], True), + (games.create_stripped_down_poker_efg(), 0, [[0.1, 0.9], [0.5, 0.5]], False), + (games.create_stripped_down_poker_efg(), 1, [[0.6, 0.4]], False), + (games.create_stripped_down_poker_efg(), 0, [["1/3", "2/3"], ["1/2", "1/2"]], True), + (games.create_stripped_down_poker_efg(), 1, [["2/3", "1/3"]], True), ] ) def test_set_probabilities_player(game: gbt.Game, player_idx: int, behav_data: list, @@ -566,11 +562,11 @@ def test_set_probabilities_player(game: gbt.Game, player_idx: int, behav_data: l (games.create_mixed_behav_game_efg(), "Player 1", [["7/9", "2/9"]], True), (games.create_mixed_behav_game_efg(), "Player 2", [["4/13", "9/13"]], True), (games.create_mixed_behav_game_efg(), "Player 3", [["1/98", "97/98"]], True), - (games.create_myerson_2_card_poker_efg(), "Player 1", [[0.1, 0.9], [0.5, 0.5]], False), - (games.create_myerson_2_card_poker_efg(), "Player 2", [[0.6, 0.4]], False), - (games.create_myerson_2_card_poker_efg(), "Player 1", [["1/3", "2/3"], ["1/2", "1/2"]], + (games.create_stripped_down_poker_efg(), "Fred", [[0.1, 0.9], [0.5, 0.5]], False), + (games.create_stripped_down_poker_efg(), "Alice", [[0.6, 0.4]], False), + (games.create_stripped_down_poker_efg(), "Fred", [["1/3", "2/3"], ["1/2", "1/2"]], True), - (games.create_myerson_2_card_poker_efg(), "Player 2", [["2/3", "1/3"]], True), + (games.create_stripped_down_poker_efg(), "Alice", [["2/3", "1/3"]], True), ] ) def test_set_probabilities_player_by_label(game: gbt.Game, player_label: str, behav_data: list, @@ -614,28 +610,28 @@ def test_set_probabilities_player_by_label(game: gbt.Game, player_label: str, be (games.create_mixed_behav_game_efg(), 12, 0.25, False), (games.create_mixed_behav_game_efg(), 13, 0.125, False), (games.create_mixed_behav_game_efg(), 14, 0.125, False), - (games.create_myerson_2_card_poker_efg(), 0, "1", True), - (games.create_myerson_2_card_poker_efg(), 1, "1/2", True), - (games.create_myerson_2_card_poker_efg(), 2, "1/4", True), - (games.create_myerson_2_card_poker_efg(), 3, "1/8", True), - (games.create_myerson_2_card_poker_efg(), 4, "1/8", True), - (games.create_myerson_2_card_poker_efg(), 5, "1/4", True), - (games.create_myerson_2_card_poker_efg(), 6, "1/2", True), - (games.create_myerson_2_card_poker_efg(), 7, "1/4", True), - (games.create_myerson_2_card_poker_efg(), 8, "1/8", True), - (games.create_myerson_2_card_poker_efg(), 9, "1/8", True), - (games.create_myerson_2_card_poker_efg(), 10, "1/4", True), - (games.create_myerson_2_card_poker_efg(), 0, 1.0, False), - (games.create_myerson_2_card_poker_efg(), 1, 0.5, False), - (games.create_myerson_2_card_poker_efg(), 2, 0.25, False), - (games.create_myerson_2_card_poker_efg(), 3, 0.125, False), - (games.create_myerson_2_card_poker_efg(), 4, 0.125, False), - (games.create_myerson_2_card_poker_efg(), 5, 0.25, False), - (games.create_myerson_2_card_poker_efg(), 6, 0.5, False), - (games.create_myerson_2_card_poker_efg(), 7, 0.25, False), - (games.create_myerson_2_card_poker_efg(), 8, 0.125, False), - (games.create_myerson_2_card_poker_efg(), 9, 0.125, False), - (games.create_myerson_2_card_poker_efg(), 10, 0.25, False)] + (games.create_stripped_down_poker_efg(), 0, "1", True), + (games.create_stripped_down_poker_efg(), 1, "1/2", True), + (games.create_stripped_down_poker_efg(), 2, "1/4", True), + (games.create_stripped_down_poker_efg(), 3, "1/8", True), + (games.create_stripped_down_poker_efg(), 4, "1/8", True), + (games.create_stripped_down_poker_efg(), 5, "1/4", True), + (games.create_stripped_down_poker_efg(), 6, "1/2", True), + (games.create_stripped_down_poker_efg(), 7, "1/4", True), + (games.create_stripped_down_poker_efg(), 8, "1/8", True), + (games.create_stripped_down_poker_efg(), 9, "1/8", True), + (games.create_stripped_down_poker_efg(), 10, "1/4", True), + (games.create_stripped_down_poker_efg(), 0, 1.0, False), + (games.create_stripped_down_poker_efg(), 1, 0.5, False), + (games.create_stripped_down_poker_efg(), 2, 0.25, False), + (games.create_stripped_down_poker_efg(), 3, 0.125, False), + (games.create_stripped_down_poker_efg(), 4, 0.125, False), + (games.create_stripped_down_poker_efg(), 5, 0.25, False), + (games.create_stripped_down_poker_efg(), 6, 0.5, False), + (games.create_stripped_down_poker_efg(), 7, 0.25, False), + (games.create_stripped_down_poker_efg(), 8, 0.125, False), + (games.create_stripped_down_poker_efg(), 9, 0.125, False), + (games.create_stripped_down_poker_efg(), 10, 0.25, False)] ) def test_realiz_prob_nodes_reference(game: gbt.Game, node_idx: int, realiz_prob: typing.Union[str, float], rational_flag: bool): @@ -653,12 +649,12 @@ def test_realiz_prob_nodes_reference(game: gbt.Game, node_idx: int, (games.create_mixed_behav_game_efg(), 0, 0, "1", True), (games.create_mixed_behav_game_efg(), 1, 0, "1", True), (games.create_mixed_behav_game_efg(), 2, 0, "1", True), - (games.create_myerson_2_card_poker_efg(), 0, 0, 0.5, False), - (games.create_myerson_2_card_poker_efg(), 0, 1, 0.5, False), - (games.create_myerson_2_card_poker_efg(), 1, 0, 0.5, False), - (games.create_myerson_2_card_poker_efg(), 0, 0, "1/2", True), - (games.create_myerson_2_card_poker_efg(), 0, 1, "1/2", True), - (games.create_myerson_2_card_poker_efg(), 1, 0, "1/2", True), + (games.create_stripped_down_poker_efg(), 0, 0, 0.5, False), + (games.create_stripped_down_poker_efg(), 0, 1, 0.5, False), + (games.create_stripped_down_poker_efg(), 1, 0, 0.5, False), + (games.create_stripped_down_poker_efg(), 0, 0, "1/2", True), + (games.create_stripped_down_poker_efg(), 0, 1, "1/2", True), + (games.create_stripped_down_poker_efg(), 1, 0, "1/2", True), ] ) def test_infoset_prob_reference(game: gbt.Game, player_idx: int, infoset_idx: int, @@ -676,12 +672,12 @@ def test_infoset_prob_reference(game: gbt.Game, player_idx: int, infoset_idx: in (games.create_mixed_behav_game_efg(), "Infoset 1:1", "1", True), (games.create_mixed_behav_game_efg(), "Infoset 2:1", "1", True), (games.create_mixed_behav_game_efg(), "Infoset 3:1", "1", True), - (games.create_myerson_2_card_poker_efg(), "(1,1)", 0.5, False), - (games.create_myerson_2_card_poker_efg(), "(1,2)", 0.5, False), - (games.create_myerson_2_card_poker_efg(), "(2,1)", 0.5, False), - (games.create_myerson_2_card_poker_efg(), "(1,1)", "1/2", True), - (games.create_myerson_2_card_poker_efg(), "(1,2)", "1/2", True), - (games.create_myerson_2_card_poker_efg(), "(2,1)", "1/2", True), + (games.create_stripped_down_poker_efg(), "(1,1)", 0.5, False), + (games.create_stripped_down_poker_efg(), "(1,2)", 0.5, False), + (games.create_stripped_down_poker_efg(), "(2,1)", 0.5, False), + (games.create_stripped_down_poker_efg(), "(1,1)", "1/2", True), + (games.create_stripped_down_poker_efg(), "(1,2)", "1/2", True), + (games.create_stripped_down_poker_efg(), "(2,1)", "1/2", True), ] ) def test_infoset_prob_by_label_reference(game: gbt.Game, label: str, @@ -698,12 +694,12 @@ def test_infoset_prob_by_label_reference(game: gbt.Game, label: str, (games.create_mixed_behav_game_efg(), 0, 0, "3", True), (games.create_mixed_behav_game_efg(), 1, 0, "3", True), (games.create_mixed_behav_game_efg(), 2, 0, "13/4", True), - (games.create_myerson_2_card_poker_efg(), 0, 0, -0.75, False), - (games.create_myerson_2_card_poker_efg(), 0, 1, -1.75, False), - (games.create_myerson_2_card_poker_efg(), 1, 0, 0.5, False), - (games.create_myerson_2_card_poker_efg(), 0, 0, "-3/4", True), - (games.create_myerson_2_card_poker_efg(), 0, 1, "-7/4", True), - (games.create_myerson_2_card_poker_efg(), 1, 0, "1/2", True), + (games.create_stripped_down_poker_efg(), 0, 0, 0.25, False), + (games.create_stripped_down_poker_efg(), 0, 1, -0.75, False), + (games.create_stripped_down_poker_efg(), 1, 0, -0.5, False), + (games.create_stripped_down_poker_efg(), 0, 0, "1/4", True), + (games.create_stripped_down_poker_efg(), 0, 1, "-3/4", True), + (games.create_stripped_down_poker_efg(), 1, 0, "-1/2", True), ] ) def test_infoset_payoff_reference(game: gbt.Game, player_idx: int, infoset_idx: int, @@ -721,12 +717,12 @@ def test_infoset_payoff_reference(game: gbt.Game, player_idx: int, infoset_idx: (games.create_mixed_behav_game_efg(), "Infoset 1:1", "3", True), (games.create_mixed_behav_game_efg(), "Infoset 2:1", "3", True), (games.create_mixed_behav_game_efg(), "Infoset 3:1", "13/4", True), - (games.create_myerson_2_card_poker_efg(), "(1,1)", -0.75, False), - (games.create_myerson_2_card_poker_efg(), "(1,2)", -1.75, False), - (games.create_myerson_2_card_poker_efg(), "(2,1)", 0.5, False), - (games.create_myerson_2_card_poker_efg(), "(1,1)", "-3/4", True), - (games.create_myerson_2_card_poker_efg(), "(1,2)", "-7/4", True), - (games.create_myerson_2_card_poker_efg(), "(2,1)", "1/2", True), + (games.create_stripped_down_poker_efg(), "(1,1)", 0.25, False), + (games.create_stripped_down_poker_efg(), "(1,2)", -0.75, False), + (games.create_stripped_down_poker_efg(), "(2,1)", -0.5, False), + (games.create_stripped_down_poker_efg(), "(1,1)", "1/4", True), + (games.create_stripped_down_poker_efg(), "(1,2)", "-3/4", True), + (games.create_stripped_down_poker_efg(), "(2,1)", "-1/2", True), ] ) def test_infoset_payoff_by_label_reference(game: gbt.Game, label: str, @@ -750,18 +746,18 @@ def test_infoset_payoff_by_label_reference(game: gbt.Game, label: str, (games.create_mixed_behav_game_efg(), 1, 0, 1, "3/1", True), (games.create_mixed_behav_game_efg(), 2, 0, 0, "7/2", True), (games.create_mixed_behav_game_efg(), 2, 0, 1, "3/1", True), - (games.create_myerson_2_card_poker_efg(), 0, 0, 0, 0.5, False), - (games.create_myerson_2_card_poker_efg(), 0, 0, 1, -2, False), - (games.create_myerson_2_card_poker_efg(), 0, 1, 0, -1.5, False), - (games.create_myerson_2_card_poker_efg(), 0, 1, 1, -2, False), - (games.create_myerson_2_card_poker_efg(), 1, 0, 0, 1, False), - (games.create_myerson_2_card_poker_efg(), 1, 0, 1, 0, False), - (games.create_myerson_2_card_poker_efg(), 0, 0, 0, "1/2", True), - (games.create_myerson_2_card_poker_efg(), 0, 0, 1, "-2", True), - (games.create_myerson_2_card_poker_efg(), 0, 1, 0, "-3/2", True), - (games.create_myerson_2_card_poker_efg(), 0, 1, 1, "-2", True), - (games.create_myerson_2_card_poker_efg(), 1, 0, 0, "1", True), - (games.create_myerson_2_card_poker_efg(), 1, 0, 1, "0", True), + (games.create_stripped_down_poker_efg(), 0, 0, 0, 1.5, False), + (games.create_stripped_down_poker_efg(), 0, 0, 1, -1, False), + (games.create_stripped_down_poker_efg(), 0, 1, 0, -0.5, False), + (games.create_stripped_down_poker_efg(), 0, 1, 1, -1, False), + (games.create_stripped_down_poker_efg(), 1, 0, 0, 0, False), + (games.create_stripped_down_poker_efg(), 1, 0, 1, -1, False), + (games.create_stripped_down_poker_efg(), 0, 0, 0, "3/2", True), + (games.create_stripped_down_poker_efg(), 0, 0, 1, -1, True), + (games.create_stripped_down_poker_efg(), 0, 1, 0, "-1/2", True), + (games.create_stripped_down_poker_efg(), 0, 1, 1, -1, True), + (games.create_stripped_down_poker_efg(), 1, 0, 0, 0, True), + (games.create_stripped_down_poker_efg(), 1, 0, 1, -1, True), ] ) def test_action_payoff_reference(game: gbt.Game, player_idx: int, infoset_idx: int, @@ -786,10 +782,8 @@ def test_action_payoff_reference(game: gbt.Game, player_idx: int, infoset_idx: i (games.create_mixed_behav_game_efg(), "D2", "3", True), (games.create_mixed_behav_game_efg(), "U3", "7/2", True), (games.create_mixed_behav_game_efg(), "D3", "3", True), - (games.create_myerson_2_card_poker_efg(), "MEET", 1, False), - (games.create_myerson_2_card_poker_efg(), "PASS", 0, False), - (games.create_myerson_2_card_poker_efg(), "MEET", "1", True), - (games.create_myerson_2_card_poker_efg(), "PASS", "0", True), + (games.create_stripped_down_poker_efg(), "Call", 0, False), + (games.create_stripped_down_poker_efg(), "Call", "0", True), ] ) def test_action_value_by_label_reference(game: gbt.Game, label: str, @@ -802,8 +796,8 @@ def test_action_value_by_label_reference(game: gbt.Game, label: str, "game,rational_flag", [(games.create_mixed_behav_game_efg(), False), (games.create_mixed_behav_game_efg(), True), - (games.create_myerson_2_card_poker_efg(), False), - (games.create_myerson_2_card_poker_efg(), True), + (games.create_stripped_down_poker_efg(), False), + (games.create_stripped_down_poker_efg(), True), ] ) def test_regret_consistency(game: gbt.Game, rational_flag: bool): @@ -851,16 +845,16 @@ def test_regret_consistency(game: gbt.Game, rational_flag: bool): (games.create_mixed_behav_game_efg(), 2, 0, 1, ["2/5", "3/5", "1/2", "1/2", "1/3", "2/3"], True, ZERO, 0), # uniform - (games.create_myerson_2_card_poker_efg(), 0, 0, 0, None, False, TOL, 0), - (games.create_myerson_2_card_poker_efg(), 0, 0, 1, None, False, TOL, 2.5), # 1.5 - (-1) - (games.create_myerson_2_card_poker_efg(), 0, 1, 0, None, False, TOL, 0), - (games.create_myerson_2_card_poker_efg(), 0, 1, 1, None, False, TOL, 0.5), # -0.5 - (-1) - (games.create_myerson_2_card_poker_efg(), 1, 0, 0, None, False, TOL, 0), - (games.create_myerson_2_card_poker_efg(), 1, 0, 1, None, False, TOL, 1), # -0 - (-1) + (games.create_stripped_down_poker_efg(), 0, 0, 0, None, False, TOL, 0), + (games.create_stripped_down_poker_efg(), 0, 0, 1, None, False, TOL, 2.5), # 1.5 - (-1) + (games.create_stripped_down_poker_efg(), 0, 1, 0, None, False, TOL, 0), + (games.create_stripped_down_poker_efg(), 0, 1, 1, None, False, TOL, 0.5), # -0.5 - (-1) + (games.create_stripped_down_poker_efg(), 1, 0, 0, None, False, TOL, 0), + (games.create_stripped_down_poker_efg(), 1, 0, 1, None, False, TOL, 1), # -0 - (-1) # mixed Nash equilibrium - (games.create_myerson_2_card_poker_efg(), 0, 0, 0, ["1", "0", "1/3", "2/3", "2/3", "1/3"], + (games.create_stripped_down_poker_efg(), 0, 0, 0, ["1", "0", "1/3", "2/3", "2/3", "1/3"], True, ZERO, 0), - (games.create_myerson_2_card_poker_efg(), 0, 0, 1, ["1", "0", "1/3", "2/3", "2/3", "1/3"], + (games.create_stripped_down_poker_efg(), 0, 0, 1, ["1", "0", "1/3", "2/3", "2/3", "1/3"], True, ZERO, "8/3"), # (2/3*2 + 1/3*1) - (-1) ] ) @@ -880,8 +874,8 @@ def test_regret_reference(game: gbt.Game, player_idx: int, infoset_idx: int, act "game,rational_flag", [(games.create_mixed_behav_game_efg(), False), (games.create_mixed_behav_game_efg(), True), - (games.create_myerson_2_card_poker_efg(), False), - (games.create_myerson_2_card_poker_efg(), True), + (games.create_stripped_down_poker_efg(), False), + (games.create_stripped_down_poker_efg(), True), ] ) def test_martingale_property_of_node_value(game: gbt.Game, rational_flag: bool): @@ -905,8 +899,8 @@ def test_martingale_property_of_node_value(game: gbt.Game, rational_flag: bool): "game,rational_flag", [(games.create_mixed_behav_game_efg(), False), (games.create_mixed_behav_game_efg(), True), - (games.create_myerson_2_card_poker_efg(), False), - (games.create_myerson_2_card_poker_efg(), True)] + (games.create_stripped_down_poker_efg(), False), + (games.create_stripped_down_poker_efg(), True)] ) def test_node_value_consistency(game: gbt.Game, rational_flag: bool): """Test that the profile's node value at the root for each player matches the profile's payoff @@ -937,14 +931,14 @@ def test_node_value_consistency(game: gbt.Game, rational_flag: bool): (games.create_mixed_behav_game_efg(), [0.0, 1.0, 0.0, 1.0, 0.0, 1.0], False, 29.0), (games.create_mixed_behav_game_efg(), ["0", "1", "0", "1", "0", "1"], True, "29"), # uniform (non-Nash): - (games.create_myerson_2_card_poker_efg(), None, True, "15/8"), - (games.create_myerson_2_card_poker_efg(), None, False, 1.875), + (games.create_stripped_down_poker_efg(), None, True, "15/8"), + (games.create_stripped_down_poker_efg(), None, False, 1.875), # mixed Nash equilibrium (only rational tested): - (games.create_myerson_2_card_poker_efg(), ["1", "0", "1/3", "2/3", "2/3", "1/3"], True, 0), + (games.create_stripped_down_poker_efg(), ["1", "0", "1/3", "2/3", "2/3", "1/3"], True, 0), # non-Nash pure profile: # Raise at 1:1, Raise at 1:2, Meet at 2:1 - (games.create_myerson_2_card_poker_efg(), ["1", "0", "1", "0", "1", "0"], True, 1), - (games.create_myerson_2_card_poker_efg(), [1.0, 0.0, 1.0, 0.0, 1.0, 0.0], False, 1.0), + (games.create_stripped_down_poker_efg(), ["1", "0", "1", "0", "1", "0"], True, 1), + (games.create_stripped_down_poker_efg(), [1.0, 0.0, 1.0, 0.0, 1.0, 0.0], False, 1.0), ] ) def test_liap_value_reference(game: gbt.Game, action_probs: typing.Union[None, list], @@ -977,17 +971,17 @@ def test_liap_value_reference(game: gbt.Game, action_probs: typing.Union[None, l "8/25", True), (games.create_mixed_behav_game_efg(), ZERO, ["4/5", "1/5", "2/5", "3/5", "0", "1"], 2, 1, "12/25", True), - (games.create_myerson_2_card_poker_efg(), ZERO, ["4/5", "1/5", "2/5", "3/5", "0", "1"], + (games.create_stripped_down_poker_efg(), ZERO, ["4/5", "1/5", "2/5", "3/5", "0", "1"], 0, 0, "1", True), - (games.create_myerson_2_card_poker_efg(), ZERO, ["4/5", "1/5", "2/5", "3/5", "0", "1"], + (games.create_stripped_down_poker_efg(), ZERO, ["4/5", "1/5", "2/5", "3/5", "0", "1"], 1, 0, "1", True), - (games.create_myerson_2_card_poker_efg(), ZERO, ["4/5", "1/5", "2/5", "3/5", "0", "1"], + (games.create_stripped_down_poker_efg(), ZERO, ["4/5", "1/5", "2/5", "3/5", "0", "1"], 2, 0, "2/3", True), - (games.create_myerson_2_card_poker_efg(), ZERO, ["4/5", "1/5", "2/5", "3/5", "0", "1"], + (games.create_stripped_down_poker_efg(), ZERO, ["4/5", "1/5", "2/5", "3/5", "0", "1"], 2, 1, "1/3", True), - (games.create_myerson_2_card_poker_efg(), ZERO, ["1", "0", "2/5", "3/5", "0", "1"], + (games.create_stripped_down_poker_efg(), ZERO, ["1", "0", "2/5", "3/5", "0", "1"], 2, 0, "5/7", True), - (games.create_myerson_2_card_poker_efg(), ZERO, ["1", "0", "2/5", "3/5", "0", "1"], + (games.create_stripped_down_poker_efg(), ZERO, ["1", "0", "2/5", "3/5", "0", "1"], 2, 1, "2/7", True), ] ) @@ -1003,8 +997,8 @@ def test_node_belief_reference(game: gbt.Game, tol: typing.Union[gbt.Rational, f @pytest.mark.parametrize( "game,rational_flag", - [(games.create_myerson_2_card_poker_efg(), True), - (games.create_myerson_2_card_poker_efg(), False), + [(games.create_stripped_down_poker_efg(), True), + (games.create_stripped_down_poker_efg(), False), ] ) def test_payoff_value_error_with_chance_player(game: gbt.Game, rational_flag: bool): @@ -1016,8 +1010,8 @@ def test_payoff_value_error_with_chance_player(game: gbt.Game, rational_flag: bo @pytest.mark.parametrize( "game,rational_flag", - [(games.create_myerson_2_card_poker_efg(), True), - (games.create_myerson_2_card_poker_efg(), False), + [(games.create_stripped_down_poker_efg(), True), + (games.create_stripped_down_poker_efg(), False), ] ) def test_infoset_value_error_with_chance_player_infoset(game: gbt.Game, rational_flag: bool): @@ -1029,8 +1023,8 @@ def test_infoset_value_error_with_chance_player_infoset(game: gbt.Game, rational @pytest.mark.parametrize( "game,rational_flag", - [(games.create_myerson_2_card_poker_efg(), True), - (games.create_myerson_2_card_poker_efg(), False), + [(games.create_stripped_down_poker_efg(), True), + (games.create_stripped_down_poker_efg(), False), ] ) def test_action_value_error_with_chance_player_action(game: gbt.Game, rational_flag: bool): @@ -1083,9 +1077,9 @@ def _get_and_check_answers(game: gbt.Game, action_probs1: tuple, action_probs2: lambda x, y: x.belief(y), lambda x: x.nodes), (games.create_mixed_behav_game_efg(), PROBS_1A_rat, PROBS_2A_rat, True, lambda x, y: x.belief(y), lambda x: x.nodes), - (games.create_myerson_2_card_poker_efg(), PROBS_1B_doub, PROBS_2B_doub, False, + (games.create_stripped_down_poker_efg(), PROBS_1B_doub, PROBS_2B_doub, False, lambda x, y: x.belief(y), lambda x: x.nodes), - (games.create_myerson_2_card_poker_efg(), PROBS_1A_rat, PROBS_2A_rat, True, + (games.create_stripped_down_poker_efg(), PROBS_1A_rat, PROBS_2A_rat, True, lambda x, y: x.belief(y), lambda x: x.nodes), ###################################################################################### # realiz_prob (at nodes) @@ -1093,9 +1087,9 @@ def _get_and_check_answers(game: gbt.Game, action_probs1: tuple, action_probs2: lambda x, y: x.realiz_prob(y), lambda x: x.nodes), (games.create_mixed_behav_game_efg(), PROBS_1A_rat, PROBS_2A_rat, True, lambda x, y: x.realiz_prob(y), lambda x: x.nodes), - (games.create_myerson_2_card_poker_efg(), PROBS_1B_doub, PROBS_2B_doub, False, + (games.create_stripped_down_poker_efg(), PROBS_1B_doub, PROBS_2B_doub, False, lambda x, y: x.realiz_prob(y), lambda x: x.nodes), - (games.create_myerson_2_card_poker_efg(), PROBS_1A_rat, PROBS_2A_rat, True, + (games.create_stripped_down_poker_efg(), PROBS_1A_rat, PROBS_2A_rat, True, lambda x, y: x.realiz_prob(y), lambda x: x.nodes), ###################################################################################### # infoset_prob @@ -1103,9 +1097,9 @@ def _get_and_check_answers(game: gbt.Game, action_probs1: tuple, action_probs2: lambda x, y: x.infoset_prob(y), lambda x: x.infosets), (games.create_mixed_behav_game_efg(), PROBS_1A_rat, PROBS_2A_rat, True, lambda x, y: x.infoset_prob(y), lambda x: x.infosets), - (games.create_myerson_2_card_poker_efg(), PROBS_1B_doub, PROBS_2B_doub, False, + (games.create_stripped_down_poker_efg(), PROBS_1B_doub, PROBS_2B_doub, False, lambda x, y: x.infoset_prob(y), lambda x: x.infosets), - (games.create_myerson_2_card_poker_efg(), PROBS_1A_rat, PROBS_2A_rat, True, + (games.create_stripped_down_poker_efg(), PROBS_1A_rat, PROBS_2A_rat, True, lambda x, y: x.infoset_prob(y), lambda x: x.infosets), ###################################################################################### # infoset_value @@ -1113,9 +1107,9 @@ def _get_and_check_answers(game: gbt.Game, action_probs1: tuple, action_probs2: lambda x, y: x.infoset_value(y), lambda x: x.infosets), (games.create_mixed_behav_game_efg(), PROBS_1A_rat, PROBS_2A_rat, True, lambda x, y: x.infoset_value(y), lambda x: x.infosets), - (games.create_myerson_2_card_poker_efg(), PROBS_1B_doub, PROBS_2B_doub, False, + (games.create_stripped_down_poker_efg(), PROBS_1B_doub, PROBS_2B_doub, False, lambda x, y: x.infoset_value(y), lambda x: x.infosets), - (games.create_myerson_2_card_poker_efg(), PROBS_1A_rat, PROBS_2A_rat, True, + (games.create_stripped_down_poker_efg(), PROBS_1A_rat, PROBS_2A_rat, True, lambda x, y: x.infoset_value(y), lambda x: x.infosets), ###################################################################################### # action_value @@ -1123,9 +1117,9 @@ def _get_and_check_answers(game: gbt.Game, action_probs1: tuple, action_probs2: lambda x, y: x.action_value(y), lambda x: x.actions), (games.create_mixed_behav_game_efg(), PROBS_1A_rat, PROBS_2A_rat, True, lambda x, y: x.action_value(y), lambda x: x.actions), - (games.create_myerson_2_card_poker_efg(), PROBS_1B_doub, PROBS_2B_doub, False, + (games.create_stripped_down_poker_efg(), PROBS_1B_doub, PROBS_2B_doub, False, lambda x, y: x.action_value(y), lambda x: x.actions), - (games.create_myerson_2_card_poker_efg(), PROBS_1A_rat, PROBS_2A_rat, True, + (games.create_stripped_down_poker_efg(), PROBS_1A_rat, PROBS_2A_rat, True, lambda x, y: x.action_value(y), lambda x: x.actions), ###################################################################################### # regret (for actions) @@ -1133,9 +1127,9 @@ def _get_and_check_answers(game: gbt.Game, action_probs1: tuple, action_probs2: lambda x, y: x.action_regret(y), lambda x: x.actions), (games.create_mixed_behav_game_efg(), PROBS_1A_rat, PROBS_2A_rat, True, lambda x, y: x.action_regret(y), lambda x: x.actions), - (games.create_myerson_2_card_poker_efg(), PROBS_1B_doub, PROBS_2B_doub, False, + (games.create_stripped_down_poker_efg(), PROBS_1B_doub, PROBS_2B_doub, False, lambda x, y: x.action_regret(y), lambda x: x.actions), - (games.create_myerson_2_card_poker_efg(), PROBS_1A_rat, PROBS_2A_rat, True, + (games.create_stripped_down_poker_efg(), PROBS_1A_rat, PROBS_2A_rat, True, lambda x, y: x.action_regret(y), lambda x: x.actions), ###################################################################################### # node_value @@ -1145,10 +1139,10 @@ def _get_and_check_answers(game: gbt.Game, action_probs1: tuple, action_probs2: (games.create_mixed_behav_game_efg(), PROBS_1A_rat, PROBS_2A_rat, True, lambda x, y: x.node_value(player=y[0], node=y[1]), lambda x: list(product(x.players, x.nodes))), - (games.create_myerson_2_card_poker_efg(), PROBS_1B_doub, PROBS_2B_doub, False, + (games.create_stripped_down_poker_efg(), PROBS_1B_doub, PROBS_2B_doub, False, lambda x, y: x.node_value(player=y[0], node=y[1]), lambda x: list(product(x.players, x.nodes))), - (games.create_myerson_2_card_poker_efg(), PROBS_1A_rat, PROBS_2A_rat, True, + (games.create_stripped_down_poker_efg(), PROBS_1A_rat, PROBS_2A_rat, True, lambda x, y: x.node_value(player=y[0], node=y[1]), lambda x: list(product(x.players, x.nodes))), ###################################################################################### @@ -1157,9 +1151,9 @@ def _get_and_check_answers(game: gbt.Game, action_probs1: tuple, action_probs2: lambda x, y: x.liap_value(), lambda x: [1]), (games.create_mixed_behav_game_efg(), PROBS_1A_rat, PROBS_2A_rat, True, lambda x, y: x.liap_value(), lambda x: [1]), - (games.create_myerson_2_card_poker_efg(), PROBS_1B_doub, PROBS_2B_doub, False, + (games.create_stripped_down_poker_efg(), PROBS_1B_doub, PROBS_2B_doub, False, lambda x, y: x.liap_value(), lambda x: [1]), - (games.create_myerson_2_card_poker_efg(), PROBS_1A_rat, PROBS_2A_rat, True, + (games.create_stripped_down_poker_efg(), PROBS_1A_rat, PROBS_2A_rat, True, lambda x, y: x.liap_value(), lambda x: [1]), ] ) @@ -1176,10 +1170,10 @@ def test_profile_order_consistency(game: gbt.Game, "game,rational_flag,data", [(games.create_mixed_behav_game_efg(), True, [[[0, 1]], [[0, 1]], [[1, 0]]]), (games.create_mixed_behav_game_efg(), True, [[["1/5", "4/5"]], [["1/4", "3/4"]], [[1, 0]]]), - (games.create_myerson_2_card_poker_efg(), True, [[[1/5, 4/5], [3/5, 2/5]], [[1/4, 3/4]]]), + (games.create_stripped_down_poker_efg(), True, [[[1/5, 4/5], [3/5, 2/5]], [[1/4, 3/4]]]), (games.create_mixed_behav_game_efg(), False, [[[0, 1]], [[1, 0]], [[1, 0]]]), (games.create_mixed_behav_game_efg(), False, [[[1/5, 4/5]], [[1/4, 3/4]], [[1, 0]]]), - (games.create_myerson_2_card_poker_efg(), False, [[[1/5, 4/5], [3/5, 2/5]], [[1/4, 3/4]]]) + (games.create_stripped_down_poker_efg(), False, [[[1/5, 4/5], [3/5, 2/5]], [[1/4, 3/4]]]) ] ) def test_specific_profile(game: gbt.Game, rational_flag: bool, data: list): @@ -1197,7 +1191,7 @@ def test_specific_profile(game: gbt.Game, rational_flag: bool, data: list): [[[0, 1, 0]], [[1, 0]], [["1/2", "1/2"]]]), (games.create_mixed_behav_game_efg(), True, [[[0, 1]], [[1, 0]], [[1, 0]], [[0, 1]]]), - (games.create_myerson_2_card_poker_efg(), True, + (games.create_stripped_down_poker_efg(), True, [[["1/5", "4/5"], ["3/5", "2/5"]], [["1/4", "3/4"], ["1/4", "3/4"]]]), (games.create_el_farol_bar_game_efg(), True, [[4/9, 5/9], [0], [1/2, 1/2], [11/12, 1/12], [1/2, 1/2]]), @@ -1207,7 +1201,7 @@ def test_specific_profile(game: gbt.Game, rational_flag: bool, data: list): [[[0, 1, 0]], [[1, 0]], [[1, 0]]]), (games.create_mixed_behav_game_efg(), False, [[[0, 1]], [[1, 0]], [[1, 0]], [[0, 1]]]), - (games.create_myerson_2_card_poker_efg(), False, + (games.create_stripped_down_poker_efg(), False, [[[1/5, 4/5], [3/5, 2/5]], [[1/4, 3/4], [1/4, 3/4]]]), (games.create_el_farol_bar_game_efg(), False, [[4/9, 5/9], [0], [1/2, 1/2], [11/12, 1/12], [1/2, 1/2]]), diff --git a/tests/test_extensive.py b/tests/test_extensive.py index 6d86dd463..416621732 100644 --- a/tests/test_extensive.py +++ b/tests/test_extensive.py @@ -54,7 +54,7 @@ def test_game_add_players_nolabel(): ("e01.efg", True), ("e02.efg", True), ("cent3.efg", True), - ("myerson_2_card_poker.efg", True), + ("stripped_down_poker.efg", True), ("basic_extensive_game.efg", True), # Games with perfect recall from generated games (game_input is a gbt.Game object) @@ -283,13 +283,13 @@ def test_outcome_index_exception_label(): ), ], ), - # Stripped down "Myerson" 2-card poker; 2 player zero-sum game with chance at the root + # Stripped-down poker; 2 player zero-sum game with chance at the root ( - games.create_myerson_2_card_poker_efg(), + games.create_stripped_down_poker_efg(), [["11", "12", "21", "22"], ["1", "2"]], [ - np.array([[-1, 0], ["-1/2", -1], ["-5/2", -1], [-2, -2]]), - np.array([[1, 0], ["1/2", 1], ["5/2", 1], [2, 2]]), + np.array([[0, 1], ["1/2", 0], ["-3/2", 0], [-1, -1]]), + np.array([[0, -1], ["-1/2", 0], ["3/2", 0], [1, 1]]), ], ), # Nature playing at the root, 2 players, no reduction, non-generic payoffs diff --git a/tests/test_games/myerson_2_card_poker.efg b/tests/test_games/myerson_2_card_poker.efg deleted file mode 100644 index f0b1707b2..000000000 --- a/tests/test_games/myerson_2_card_poker.efg +++ /dev/null @@ -1,14 +0,0 @@ -EFG 2 R "" { "Player 1" "Player 2" } -"" - -c "" 1 "(0,1)" { "RED" 0.500000 "BLACK" 0.500000 } 1 "Outcome 3" { -1, 1 } -p "" 1 1 "(1,1)" { "RAISE" "FOLD" } 0 -p "" 2 1 "(2,1)" { "MEET" "PASS" } 0 -t "" 2 "Outcome 2" { 2, -2 } -t "" 3 "Outcome 1" { 1, -1 } -t "" 1 "Outcome 3" { -1, 1 } -p "" 1 2 "(1,2)" { "RAISE" "FOLD" } 0 -p "" 2 1 "(2,1)" { "MEET" "PASS" } 0 -t "" 4 "Outcome 4" { -2, 2 } -t "" 3 "Outcome 1" { 1, -1 } -t "" 1 "Outcome 3" { -1, 1 } diff --git a/tests/test_games/poker.efg b/tests/test_games/poker.efg deleted file mode 100644 index b55de5be1..000000000 --- a/tests/test_games/poker.efg +++ /dev/null @@ -1,14 +0,0 @@ -EFG 2 R "A simple Poker game" { "Fred" "Alice" } -"This is a simple game of one-card poker from Myerson (1991)." - -c "" 1 "" { "Red" 1/2 "Black" 1/2 } 0 -p "" 1 1 "" { "Raise" "Fold" } 0 -p "" 2 1 "" { "Meet" "Pass" } 0 -t "" 1 "Win Big" { 2, -2 } -t "" 2 "Win" { 1, -1 } -t "" 2 "Win" { 1, -1 } -p "" 1 2 "" { "Raise" "Fold" } 0 -p "" 2 1 "" { "Meet" "Pass" } 0 -t "" 3 "Lose Big" { -2, 2 } -t "" 2 "Win" { 1, -1 } -t "" 4 "Lose" { -1, 1 } diff --git a/tests/test_mixed.py b/tests/test_mixed.py index 43dd8a09b..b37763d74 100644 --- a/tests/test_mixed.py +++ b/tests/test_mixed.py @@ -107,13 +107,13 @@ def test_normalize(game, profile_data, expected_data, rational_flag): (games.create_coord_4x4_nfg(outcome_version=True), "1-1", 0.25, False), (games.create_coord_4x4_nfg(outcome_version=True), "1-1", "1/4", True), ############################################################################### - # myerson 2 card poker efg - (games.create_myerson_2_card_poker_efg(), "11", 0.25, False), - (games.create_myerson_2_card_poker_efg(), "12", 0.15, False), - (games.create_myerson_2_card_poker_efg(), "21", 0.99, False), - (games.create_myerson_2_card_poker_efg(), "11", "1/4", True), - (games.create_myerson_2_card_poker_efg(), "12", "3/4", True), - (games.create_myerson_2_card_poker_efg(), "21", "7/9", True), + # stripped-down poker efg + (games.create_stripped_down_poker_efg(), "11", 0.25, False), + (games.create_stripped_down_poker_efg(), "12", 0.15, False), + (games.create_stripped_down_poker_efg(), "21", 0.99, False), + (games.create_stripped_down_poker_efg(), "11", "1/4", True), + (games.create_stripped_down_poker_efg(), "12", "3/4", True), + (games.create_stripped_down_poker_efg(), "21", "7/9", True), ], ) def test_set_and_get_probability_by_strategy_label(game: gbt.Game, strategy_label: str, @@ -137,11 +137,11 @@ def test_set_and_get_probability_by_strategy_label(game: gbt.Game, strategy_labe (games.create_coord_4x4_nfg(), P1, False, [0.25, 0, 0, 0.75]), (games.create_coord_4x4_nfg(), P1, True, ["1/4", 0, 0, "3/4"]), ############################################################################## - # myerson 2 card poker efg - (games.create_myerson_2_card_poker_efg(), P1, False, [0.25, 0.75, 0, 0]), - (games.create_myerson_2_card_poker_efg(), P2, False, [1, 0]), - (games.create_myerson_2_card_poker_efg(), P1, True, ["1/4", "3/4", 0, 0]), - (games.create_myerson_2_card_poker_efg(), P2, True, [1, 0]), + # stripped-down poker efg + (games.create_stripped_down_poker_efg(), "Fred", False, [0.25, 0.75, 0, 0]), + (games.create_stripped_down_poker_efg(), "Alice", False, [1, 0]), + (games.create_stripped_down_poker_efg(), "Fred", True, ["1/4", "3/4", 0, 0]), + (games.create_stripped_down_poker_efg(), "Alice", True, [1, 0]), ], ) def test_set_and_get_probabilities_by_player_label(game: gbt.Game, player_label: str, @@ -156,21 +156,21 @@ def test_set_and_get_probabilities_by_player_label(game: gbt.Game, player_label: "game,player_label,strategy_label,prob,rational_flag", [ ############################################################################## - # myerson 2 card poker efg + # stripped-down poker efg # Player 1 - (games.create_myerson_2_card_poker_efg(), P1, "11", 0.25, False), - (games.create_myerson_2_card_poker_efg(), P1, "12", 0.25, False), - (games.create_myerson_2_card_poker_efg(), P1, "21", 0.25, False), - (games.create_myerson_2_card_poker_efg(), P1, "22", 0.25, False), - (games.create_myerson_2_card_poker_efg(), P1, "11", "1/4", True), - (games.create_myerson_2_card_poker_efg(), P1, "12", "1/4", True), - (games.create_myerson_2_card_poker_efg(), P1, "21", "1/4", True), - (games.create_myerson_2_card_poker_efg(), P1, "22", "1/4", True), + (games.create_stripped_down_poker_efg(), "Fred", "11", 0.25, False), + (games.create_stripped_down_poker_efg(), "Fred", "12", 0.25, False), + (games.create_stripped_down_poker_efg(), "Fred", "21", 0.25, False), + (games.create_stripped_down_poker_efg(), "Fred", "22", 0.25, False), + (games.create_stripped_down_poker_efg(), "Fred", "11", "1/4", True), + (games.create_stripped_down_poker_efg(), "Fred", "12", "1/4", True), + (games.create_stripped_down_poker_efg(), "Fred", "21", "1/4", True), + (games.create_stripped_down_poker_efg(), "Fred", "22", "1/4", True), # Player 2 - (games.create_myerson_2_card_poker_efg(), P2, "1", 0.5, False), - (games.create_myerson_2_card_poker_efg(), P2, "2", 0.5, False), - (games.create_myerson_2_card_poker_efg(), P2, "1", "1/2", True), - (games.create_myerson_2_card_poker_efg(), P2, "2", "1/2", True), + (games.create_stripped_down_poker_efg(), "Alice", "1", 0.5, False), + (games.create_stripped_down_poker_efg(), "Alice", "2", 0.5, False), + (games.create_stripped_down_poker_efg(), "Alice", "1", "1/2", True), + (games.create_stripped_down_poker_efg(), "Alice", "2", "1/2", True), ############################################################################## # coordination 4x4 nfg outcome version with strategy labels (games.create_coord_4x4_nfg(outcome_version=True), P1, "1-1", "1/4", True), @@ -190,13 +190,13 @@ def test_profile_indexing_by_player_and_strategy_label_reference(game: gbt.Game, "game,player_label,strategy_label,rational_flag", [ ############################################################################## - # myerson 2 card poker efg - (games.create_myerson_2_card_poker_efg(), P2, "11", True), - (games.create_myerson_2_card_poker_efg(), P2, "11", False), - (games.create_myerson_2_card_poker_efg(), P1, "1", True), - (games.create_myerson_2_card_poker_efg(), P1, "1", False), - (games.create_myerson_2_card_poker_efg(), P1, "2", True), - (games.create_myerson_2_card_poker_efg(), P1, "2", False), + # stripped-down poker efg + (games.create_stripped_down_poker_efg(), "Alice", "11", True), + (games.create_stripped_down_poker_efg(), "Alice", "11", False), + (games.create_stripped_down_poker_efg(), "Fred", "1", True), + (games.create_stripped_down_poker_efg(), "Fred", "1", False), + (games.create_stripped_down_poker_efg(), "Fred", "2", True), + (games.create_stripped_down_poker_efg(), "Fred", "2", False), ############################################################################## # coordination 4x4 nfg outcome version with strategy labels (games.create_coord_4x4_nfg(outcome_version=True), P1, "2-1", True), @@ -216,8 +216,8 @@ def test_profile_indexing_by_player_and_invalid_strategy_label(game: gbt.Game, "game,strategy_label,rational_flag,error,message", [ ############################################################################## - # myerson 2 card poker efg - (games.create_myerson_2_card_poker_efg(), "13", True, KeyError, "player or strategy"), + # stripped-down poker efg + (games.create_stripped_down_poker_efg(), "13", True, KeyError, "player or strategy"), ############################################################################## # coordination 4x4 nfg payoff version (default strategy labels created with duplicates) (games.create_coord_4x4_nfg(), "1", True, ValueError, "multiple strategies"), @@ -249,21 +249,21 @@ def test_profile_indexing_by_player_and_duplicate_strategy_label(): "game,strategy_label,prob,rational_flag", [ ########################################################################### - # myerson 2 card poker efg + # stripped-down poker efg # Player 1 - (games.create_myerson_2_card_poker_efg(), "11", 0.25, False), - (games.create_myerson_2_card_poker_efg(), "12", 0.25, False), - (games.create_myerson_2_card_poker_efg(), "21", 0.25, False), - (games.create_myerson_2_card_poker_efg(), "22", 0.25, False), - (games.create_myerson_2_card_poker_efg(), "11", "1/4", True), - (games.create_myerson_2_card_poker_efg(), "12", "1/4", True), - (games.create_myerson_2_card_poker_efg(), "21", "1/4", True), - (games.create_myerson_2_card_poker_efg(), "22", "1/4", True), + (games.create_stripped_down_poker_efg(), "11", 0.25, False), + (games.create_stripped_down_poker_efg(), "12", 0.25, False), + (games.create_stripped_down_poker_efg(), "21", 0.25, False), + (games.create_stripped_down_poker_efg(), "22", 0.25, False), + (games.create_stripped_down_poker_efg(), "11", "1/4", True), + (games.create_stripped_down_poker_efg(), "12", "1/4", True), + (games.create_stripped_down_poker_efg(), "21", "1/4", True), + (games.create_stripped_down_poker_efg(), "22", "1/4", True), # Player 2 - (games.create_myerson_2_card_poker_efg(), "1", 0.5, False), - (games.create_myerson_2_card_poker_efg(), "2", 0.5, False), - (games.create_myerson_2_card_poker_efg(), "1", "1/2", True), - (games.create_myerson_2_card_poker_efg(), "2", "1/2", True), + (games.create_stripped_down_poker_efg(), "1", 0.5, False), + (games.create_stripped_down_poker_efg(), "2", 0.5, False), + (games.create_stripped_down_poker_efg(), "1", "1/2", True), + (games.create_stripped_down_poker_efg(), "2", "1/2", True), ############################################################################ # coordination 4x4 nfg outcome version with strategy labels # Player 1 @@ -294,11 +294,11 @@ def test_profile_indexing_by_strategy_label_reference(game: gbt.Game, strategy_l (games.create_mixed_behav_game_efg(), P2, ["1/2", "1/2"], True), (games.create_mixed_behav_game_efg(), P3, ["1/2", "1/2"], True), ############################################################################ - # myerson 2 card poker efg - (games.create_myerson_2_card_poker_efg(), P1, [0.25, 0.25, 0.25, 0.25], False), - (games.create_myerson_2_card_poker_efg(), P2, [0.5, 0.5], False), - (games.create_myerson_2_card_poker_efg(), P1, ["1/4", "1/4", "1/4", "1/4"], True), - (games.create_myerson_2_card_poker_efg(), P2, ["1/2", "1/2"], True), + # stripped-down poker efg + (games.create_stripped_down_poker_efg(), "Fred", [0.25, 0.25, 0.25, 0.25], False), + (games.create_stripped_down_poker_efg(), "Alice", [0.5, 0.5], False), + (games.create_stripped_down_poker_efg(), "Fred", ["1/4", "1/4", "1/4", "1/4"], True), + (games.create_stripped_down_poker_efg(), "Alice", ["1/2", "1/2"], True), ############################################################################ # coordination 4x4 nfg (games.create_coord_4x4_nfg(), P1, [0.25, 0.25, 0.25, 0.25], False), @@ -337,25 +337,25 @@ def test_profile_indexing_by_player_label_reference(game: gbt.Game, player_label (games.create_coord_4x4_nfg(), False, [[1, 0, 0, 0], [0, 1, 0, 0]], P2, 0), (games.create_coord_4x4_nfg(), True, [[1, 0, 0, 0], [0, 1, 0, 0]], P2, 0), ######################################################################### - # myerson 2 card poker efg - (games.create_myerson_2_card_poker_efg(), False, None, P1, -1.25), - (games.create_myerson_2_card_poker_efg(), False, None, P2, 1.25), - (games.create_myerson_2_card_poker_efg(), True, None, P1, "-5/4"), - (games.create_myerson_2_card_poker_efg(), True, None, P2, "5/4"), + # stripped-down poker efg + (games.create_stripped_down_poker_efg(), False, None, "Fred", -0.25), + (games.create_stripped_down_poker_efg(), False, None, "Alice", 0.25), + (games.create_stripped_down_poker_efg(), True, None, "Fred", "-1/4"), + (games.create_stripped_down_poker_efg(), True, None, "Alice", "1/4"), # Raise/Raise for player 1 - (games.create_myerson_2_card_poker_efg(), False, [[1, 0, 0, 0], [1, 0]], P1, -1), - (games.create_myerson_2_card_poker_efg(), False, [[1, 0, 0, 0], [1, 0]], P2, 1), - (games.create_myerson_2_card_poker_efg(), True, [[1, 0, 0, 0], [1, 0]], P1, -1), - (games.create_myerson_2_card_poker_efg(), True, [[1, 0, 0, 0], [1, 0]], P2, 1), + (games.create_stripped_down_poker_efg(), False, [[1, 0, 0, 0], [1, 0]], "Fred", 0), + (games.create_stripped_down_poker_efg(), False, [[1, 0, 0, 0], [1, 0]], "Alice", 0), + (games.create_stripped_down_poker_efg(), True, [[1, 0, 0, 0], [1, 0]], "Fred", 0), + (games.create_stripped_down_poker_efg(), True, [[1, 0, 0, 0], [1, 0]], "Alice", 0), # Fold/Fold for player 1 (player 2's strategy is payoff-irrelevant) - (games.create_myerson_2_card_poker_efg(), False, [[0, 0, 0, 1], [1, 0]], P1, -2), - (games.create_myerson_2_card_poker_efg(), False, [[0, 0, 0, 1], [1, 0]], P2, 2), - (games.create_myerson_2_card_poker_efg(), True, [[0, 0, 0, 1], [1, 0]], P1, -2), - (games.create_myerson_2_card_poker_efg(), True, [[0, 0, 0, 1], [1, 0]], P2, 2), - (games.create_myerson_2_card_poker_efg(), False, [[0, 0, 0, 1], [0.5, 0.5]], P1, -2), - (games.create_myerson_2_card_poker_efg(), False, [[0, 0, 0, 1], [0.5, 0.5]], P2, 2), - (games.create_myerson_2_card_poker_efg(), True, [[0, 0, 0, 1], ["1/2", "1/2"]], P1, -2), - (games.create_myerson_2_card_poker_efg(), True, [[0, 0, 0, 1], ["1/2", "1/2"]], P2, 2), + (games.create_stripped_down_poker_efg(), False, [[0, 0, 0, 1], [1, 0]], "Fred", -1), + (games.create_stripped_down_poker_efg(), False, [[0, 0, 0, 1], [1, 0]], "Alice", 1), + (games.create_stripped_down_poker_efg(), True, [[0, 0, 0, 1], [1, 0]], "Fred", -1), + (games.create_stripped_down_poker_efg(), True, [[0, 0, 0, 1], [1, 0]], "Alice", 1), + (games.create_stripped_down_poker_efg(), False, [[0, 0, 0, 1], [0.5, 0.5]], "Fred", -1), + (games.create_stripped_down_poker_efg(), False, [[0, 0, 0, 1], [0.5, 0.5]], "Alice", 1), + (games.create_stripped_down_poker_efg(), True, [[0, 0, 0, 1], ["1/2", "1/2"]], "Fred", -1), + (games.create_stripped_down_poker_efg(), True, [[0, 0, 0, 1], ["1/2", "1/2"]], "Alice", 1), ######################################################################### (games.create_mixed_behav_game_efg(), False, None, P1, 3.0), (games.create_mixed_behav_game_efg(), False, None, P2, 3.0), @@ -384,15 +384,15 @@ def test_payoff_by_label_reference(game: gbt.Game, rational_flag: bool, profile_ (games.create_coord_4x4_nfg(outcome_version=True), False, "1-1", 0.25), (games.create_coord_4x4_nfg(outcome_version=True), True, "1-1", "1/4"), ############################################################################## - # myerson 2 card poker efg - (games.create_myerson_2_card_poker_efg(), False, "11", -0.5), # Raise/Raise - (games.create_myerson_2_card_poker_efg(), False, "12", -0.75), # Raise Red/Fold Black - (games.create_myerson_2_card_poker_efg(), False, "21", -1.75), # Fold Red/Raise Black - (games.create_myerson_2_card_poker_efg(), False, "22", -2), # Fold/Fold - (games.create_myerson_2_card_poker_efg(), True, "11", "-1/2"), - (games.create_myerson_2_card_poker_efg(), True, "12", "-3/4"), - (games.create_myerson_2_card_poker_efg(), True, "21", "-7/4"), - (games.create_myerson_2_card_poker_efg(), True, "22", -2), + # stripped-down poker efg + (games.create_stripped_down_poker_efg(), False, "11", 0.5), # Bet/Bet + (games.create_stripped_down_poker_efg(), False, "12", 0.25), # Bet King/Fold Queen + (games.create_stripped_down_poker_efg(), False, "21", -0.75), # Fold King/Bet Queen + (games.create_stripped_down_poker_efg(), False, "22", -1), # Fold/Fold + (games.create_stripped_down_poker_efg(), True, "11", "1/2"), + (games.create_stripped_down_poker_efg(), True, "12", "1/4"), + (games.create_stripped_down_poker_efg(), True, "21", "-3/4"), + (games.create_stripped_down_poker_efg(), True, "22", -1), ] ) def test_strategy_value_by_label_reference(game: gbt.Game, rational_flag: bool, label: str, @@ -483,8 +483,8 @@ def test_payoffs_reference(game: gbt.Game, profile_data: list, rational_flag: bo (games.create_2x2x2_nfg(), None, True, (["1/2", "1/2"], [2, 2], ["1/2", "1/2"])), (games.create_2x2x2_nfg(), [[1, 0], [1, 0], [1, 0]], True, ([0, 1], [0, 4], [0, 1])), ############################################################################### - # myerson 2 card poker efg - (games.create_myerson_2_card_poker_efg(), None, False, [(-0.5, -0.75, -1.75, -2), (1.5, 1)]), + # stripped-down poker efg + (games.create_stripped_down_poker_efg(), None, False, [(0.5, 0.25, -0.75, -1), (0.5, 0)]), ] ) def test_strategy_value_reference(game: gbt.Game, profile_data: list, rational_flag: bool, @@ -821,11 +821,11 @@ def _get_and_check_answers(game: gbt.Game, action_probs1: tuple, action_probs2: pytest.param(games.create_2x2x2_nfg(), PROBS_1B_rat, PROBS_2B_rat, True, lambda profile, player: profile.payoff(player), lambda game: game.players, id="payoffs_2x2x2_rat"), - # Myerson 2-card poker efg - pytest.param(games.create_myerson_2_card_poker_efg(), PROBS_1B_doub, PROBS_2B_doub, False, + # stripped-down poker + pytest.param(games.create_stripped_down_poker_efg(), PROBS_1B_doub, PROBS_2B_doub, False, lambda profile, player: profile.payoff(player), lambda game: game.players, id="payoffs_poker_doub"), - pytest.param(games.create_myerson_2_card_poker_efg(), PROBS_1B_rat, PROBS_2B_rat, True, + pytest.param(games.create_stripped_down_poker_efg(), PROBS_1B_rat, PROBS_2B_rat, True, lambda profile, player: profile.payoff(player), lambda game: game.players, id="payoffs_poker_rat"), ################################################################################# @@ -844,11 +844,11 @@ def _get_and_check_answers(game: gbt.Game, action_probs1: tuple, action_probs2: pytest.param(games.create_2x2x2_nfg(), PROBS_1B_rat, PROBS_2B_rat, True, lambda profile, strategy: profile.strategy_regret(strategy), lambda game: game.strategies, id="regret_2x2x2_rat"), - # Myerson 2-card poker efg - pytest.param(games.create_myerson_2_card_poker_efg(), PROBS_1B_doub, PROBS_2B_doub, False, + # stripped-down poker + pytest.param(games.create_stripped_down_poker_efg(), PROBS_1B_doub, PROBS_2B_doub, False, lambda profile, strategy: profile.strategy_regret(strategy), lambda game: game.strategies, id="regret_poker_doub"), - pytest.param(games.create_myerson_2_card_poker_efg(), PROBS_1B_rat, PROBS_2B_rat, True, + pytest.param(games.create_stripped_down_poker_efg(), PROBS_1B_rat, PROBS_2B_rat, True, lambda profile, strategy: profile.strategy_regret(strategy), lambda game: game.strategies, id="regret_poker_rat"), ################################################################################# @@ -867,11 +867,11 @@ def _get_and_check_answers(game: gbt.Game, action_probs1: tuple, action_probs2: pytest.param(games.create_2x2x2_nfg(), PROBS_1B_rat, PROBS_2B_rat, True, lambda profile, strategy: profile.strategy_value(strategy), lambda game: game.strategies, id="strat_value_2x2x2_rat"), - # Myerson 2-card poker efg - pytest.param(games.create_myerson_2_card_poker_efg(), PROBS_1B_doub, PROBS_2B_doub, False, + # stripped-down poker + pytest.param(games.create_stripped_down_poker_efg(), PROBS_1B_doub, PROBS_2B_doub, False, lambda profile, strategy: profile.strategy_value(strategy), lambda game: game.strategies, id="strat_value_poker_doub"), - pytest.param(games.create_myerson_2_card_poker_efg(), PROBS_1B_rat, PROBS_2B_rat, True, + pytest.param(games.create_stripped_down_poker_efg(), PROBS_1B_rat, PROBS_2B_rat, True, lambda profile, strategy: profile.strategy_value(strategy), lambda game: game.strategies, id="strat_value_poker_rat"), ################################################################################# @@ -898,13 +898,13 @@ def _get_and_check_answers(game: gbt.Game, action_probs1: tuple, action_probs2: other=strat_pair[1]), lambda game: list(product(game.strategies, game.strategies)), id="strat_value_deriv_2x2x2_rat"), - # Myerson 2-card poker efg - pytest.param(games.create_myerson_2_card_poker_efg(), PROBS_1B_doub, PROBS_2B_doub, False, + # stripped-down poker + pytest.param(games.create_stripped_down_poker_efg(), PROBS_1B_doub, PROBS_2B_doub, False, lambda profile, strat_pair: profile.strategy_value_deriv(strategy=strat_pair[0], other=strat_pair[1]), lambda game: list(product(game.strategies, game.strategies)), id="strat_value_deriv_poker_doub"), - pytest.param(games.create_myerson_2_card_poker_efg(), PROBS_1B_rat, PROBS_2B_rat, True, + pytest.param(games.create_stripped_down_poker_efg(), PROBS_1B_rat, PROBS_2B_rat, True, lambda profile, strat_pair: profile.strategy_value_deriv(strategy=strat_pair[0], other=strat_pair[1]), lambda game: list(product(game.strategies, game.strategies)), @@ -925,11 +925,11 @@ def _get_and_check_answers(game: gbt.Game, action_probs1: tuple, action_probs2: pytest.param(games.create_2x2x2_nfg(), PROBS_1B_rat, PROBS_2B_rat, True, lambda profile, y: profile.liap_value(), lambda x: [1], id="liap_value_2x2x2_rat"), - # Myerson 2-card poker efg - pytest.param(games.create_myerson_2_card_poker_efg(), PROBS_1B_doub, PROBS_2B_doub, False, + # stripped-down poker + pytest.param(games.create_stripped_down_poker_efg(), PROBS_1B_doub, PROBS_2B_doub, False, lambda profile, y: profile.liap_value(), lambda x: [1], id="liap_value_poker_doub"), - pytest.param(games.create_myerson_2_card_poker_efg(), PROBS_1B_rat, PROBS_2B_rat, True, + pytest.param(games.create_stripped_down_poker_efg(), PROBS_1B_rat, PROBS_2B_rat, True, lambda profile, y: profile.liap_value(), lambda x: [1], id="liap_value_poker_rat"), ] diff --git a/tests/test_nash.py b/tests/test_nash.py index 49a078888..7fbf7c02b 100644 --- a/tests/test_nash.py +++ b/tests/test_nash.py @@ -19,20 +19,20 @@ def test_enumpure_strategy(): """Test calls of enumeration of pure strategies.""" - game = games.read_from_file("myerson_2_card_poker.efg") + game = games.read_from_file("stripped_down_poker.efg") assert len(gbt.nash.enumpure_solve(game, use_strategic=True).equilibria) == 0 def test_enumpure_agent(): """Test calls of enumeration of pure agent strategies.""" - game = games.read_from_file("myerson_2_card_poker.efg") + game = games.read_from_file("stripped_down_poker.efg") assert len(gbt.nash.enumpure_solve(game, use_strategic=False).equilibria) == 0 def test_enummixed_double(): """Test calls of enumeration of mixed strategy equilibria for 2-player games, floating-point. """ - game = games.read_from_file("myerson_2_card_poker.efg") + game = games.read_from_file("stripped_down_poker.efg") result = gbt.nash.enummixed_solve(game, rational=False) assert len(result.equilibria) == 1 # For floating-point results are not exact, so we skip testing exact values for now @@ -44,7 +44,7 @@ def test_enummixed_double(): "game,mixed_strategy_prof_data", [ # Zero-sum games - (games.create_myerson_2_card_poker_efg(), [[["1/3", "2/3", 0, 0], ["2/3", "1/3"]]]), + (games.create_stripped_down_poker_efg(), [[["1/3", "2/3", 0, 0], ["2/3", "1/3"]]]), # Non-zero-sum games (games.create_one_shot_trust_efg(), [[[0, 1], ["1/2", "1/2"]], [[0, 1], [0, 1]]]), @@ -90,7 +90,7 @@ def test_enummixed_rational(game: gbt.Game, mixed_strategy_prof_data: list): [ # 2-player zero-sum games ( - games.create_myerson_2_card_poker_efg(), + games.create_stripped_down_poker_efg(), [[[[1, 0], ["1/3", "2/3"]], [["2/3", "1/3"]]]], None, ), @@ -234,7 +234,7 @@ def are_the_same(game, found, candidate): def test_lcp_strategy_double(): """Test calls of LCP for mixed strategy equilibria, floating-point.""" - game = games.read_from_file("myerson_2_card_poker.efg") + game = games.read_from_file("stripped_down_poker.efg") result = gbt.nash.lcp_solve(game, use_strategic=True, rational=False) assert len(result.equilibria) == 1 # For floating-point results are not exact, so we skip testing exact values for now @@ -246,7 +246,7 @@ def test_lcp_strategy_double(): "game,mixed_strategy_prof_data,stop_after", [ # Zero-sum games - (games.create_myerson_2_card_poker_efg(), [[["1/3", "2/3", 0, 0], ["2/3", "1/3"]]], None), + (games.create_stripped_down_poker_efg(), [[["1/3", "2/3", 0, 0], ["2/3", "1/3"]]], None), (games.create_kuhn_poker_efg(), [games.kuhn_poker_lcp_first_mixed_strategy_prof()], 1), # Non-zero-sum games (games.create_one_shot_trust_efg(), [[[0, 1], ["1/2", "1/2"]]], None), @@ -304,7 +304,7 @@ def test_lcp_strategy_rational(game: gbt.Game, mixed_strategy_prof_data: list, def test_lcp_behavior_double(): """Test calls of LCP for mixed behavior equilibria, floating-point.""" - game = games.read_from_file("myerson_2_card_poker.efg") + game = games.read_from_file("stripped_down_poker.efg") result = gbt.nash.lcp_solve(game, use_strategic=False, rational=False) assert len(result.equilibria) == 1 # For floating-point results are not exact, so we skip testing exact values for now @@ -316,7 +316,7 @@ def test_lcp_behavior_double(): "game,mixed_behav_prof_data", [ # Zero-sum games (also tested with lp solve) - (games.create_myerson_2_card_poker_efg(), [[[1, 0], ["1/3", "2/3"]], [["2/3", "1/3"]]]), + (games.create_stripped_down_poker_efg(), [[[1, 0], ["1/3", "2/3"]], [["2/3", "1/3"]]]), ( games.create_kuhn_poker_efg(), [ @@ -372,7 +372,7 @@ def test_lcp_behavior_rational(game: gbt.Game, mixed_behav_prof_data: list): def test_lp_strategy_double(): """Test calls of LP for mixed strategy equilibria, floating-point.""" - game = games.read_from_file("myerson_2_card_poker.efg") + game = games.read_from_file("stripped_down_poker.efg") result = gbt.nash.lp_solve(game, use_strategic=True, rational=False) assert len(result.equilibria) == 1 # For floating-point results are not exact, so we skip testing exact values for now @@ -382,7 +382,7 @@ def test_lp_strategy_double(): @pytest.mark.nash_lp_strategy def test_lp_strategy_rational(): """Test calls of LP for mixed strategy equilibria, rational precision.""" - game = games.read_from_file("myerson_2_card_poker.efg") + game = games.read_from_file("stripped_down_poker.efg") result = gbt.nash.lp_solve(game, use_strategic=True, rational=True) assert len(result.equilibria) == 1 expected = game.mixed_strategy_profile( @@ -397,7 +397,7 @@ def test_lp_strategy_rational(): def test_lp_behavior_double(): """Test calls of LP for mixed behavior equilibria, floating-point.""" - game = games.read_from_file("myerson_2_card_poker.efg") + game = games.read_from_file("stripped_down_poker.efg") result = gbt.nash.lp_solve(game, use_strategic=False, rational=False) assert len(result.equilibria) == 1 # For floating-point results are not exact, so we skip testing exact values for now @@ -413,7 +413,7 @@ def test_lp_behavior_double(): [[[0, 1], [1, 0]], [[1, 0], [1, 0]]], ), ( - games.create_myerson_2_card_poker_efg(), + games.create_stripped_down_poker_efg(), [[[1, 0], ["1/3", "2/3"]], [["2/3", "1/3"]]], ), ( @@ -447,47 +447,47 @@ def test_lp_behavior_rational(game: gbt.Game, mixed_behav_prof_data: list): def test_liap_strategy(): """Test calls of liap for mixed strategy equilibria.""" - game = games.read_from_file("myerson_2_card_poker.efg") + game = games.read_from_file("stripped_down_poker.efg") _ = gbt.nash.liap_solve(game.mixed_strategy_profile()) def test_liap_behavior(): """Test calls of liap for mixed behavior equilibria.""" - game = games.read_from_file("myerson_2_card_poker.efg") + game = games.read_from_file("stripped_down_poker.efg") _ = gbt.nash.liap_solve(game.mixed_behavior_profile()) def test_simpdiv_strategy(): """Test calls of simplicial subdivision for mixed strategy equilibria.""" - game = games.read_from_file("myerson_2_card_poker.efg") + game = games.read_from_file("stripped_down_poker.efg") result = gbt.nash.simpdiv_solve(game.mixed_strategy_profile(rational=True)) assert len(result.equilibria) == 1 def test_ipa_strategy(): """Test calls of IPA for mixed strategy equilibria.""" - game = games.read_from_file("myerson_2_card_poker.efg") + game = games.read_from_file("stripped_down_poker.efg") result = gbt.nash.ipa_solve(game) assert len(result.equilibria) == 1 def test_gnm_strategy(): """Test calls of GNM for mixed strategy equilibria.""" - game = games.read_from_file("myerson_2_card_poker.efg") + game = games.read_from_file("stripped_down_poker.efg") result = gbt.nash.gnm_solve(game) assert len(result.equilibria) == 1 def test_logit_strategy(): """Test calls of logit for mixed strategy equilibria.""" - game = games.read_from_file("myerson_2_card_poker.efg") + game = games.read_from_file("stripped_down_poker.efg") result = gbt.nash.logit_solve(game, use_strategic=True) assert len(result.equilibria) == 1 def test_logit_behavior(): """Test calls of logit for behavior equilibria.""" - game = games.read_from_file("myerson_2_card_poker.efg") + game = games.read_from_file("stripped_down_poker.efg") result = gbt.nash.logit_solve(game, use_strategic=False) assert len(result.equilibria) == 1 diff --git a/tests/test_node.py b/tests/test_node.py index 3f20da2c7..e11524522 100644 --- a/tests/test_node.py +++ b/tests/test_node.py @@ -791,26 +791,26 @@ def test_node_plays(): def test_node_children_action_label(): - game = games.read_from_file("myerson_2_card_poker.efg") - assert game.root.children["RED"] == game.root.children[0] - assert game.root.children["BLACK"].children["FOLD"] == game.root.children[1].children[1] + game = games.read_from_file("stripped_down_poker.efg") + assert game.root.children["King"] == game.root.children[0] + assert game.root.children["Queen"].children["Fold"] == game.root.children[1].children[1] def test_node_children_action(): - game = games.read_from_file("myerson_2_card_poker.efg") - assert game.root.children[game.root.infoset.actions["RED"]] == game.root.children[0] + game = games.read_from_file("stripped_down_poker.efg") + assert game.root.children[game.root.infoset.actions["King"]] == game.root.children[0] def test_node_children_nonexistent_action(): - game = games.read_from_file("myerson_2_card_poker.efg") + game = games.read_from_file("stripped_down_poker.efg") with pytest.raises(ValueError): - _ = game.root.children["GREEN"] + _ = game.root.children["Jack"] def test_node_children_other_infoset_action(): - game = games.read_from_file("myerson_2_card_poker.efg") + game = games.read_from_file("stripped_down_poker.efg") with pytest.raises(ValueError): - _ = game.root.children[game.root.children[0].infoset.actions["RAISE"]] + _ = game.root.children[game.root.children[0].infoset.actions["Bet"]] @pytest.mark.parametrize( @@ -821,7 +821,7 @@ def test_node_children_other_infoset_action(): pytest.param(games.read_from_file("cent3.efg")), pytest.param(games.read_from_file("e01.efg")), pytest.param(games.read_from_file("e02.efg")), - pytest.param(games.read_from_file("myerson_2_card_poker.efg")), + pytest.param(games.read_from_file("stripped_down_poker.efg")), pytest.param(gbt.Game.new_tree()), ], ) From d79174e3c895da1ad8509db5a88b07b483d6adae Mon Sep 17 00:00:00 2001 From: rahulsavani Date: Thu, 13 Nov 2025 18:41:44 +0000 Subject: [PATCH 03/17] added the file tests/test_games/stripped_down_poker.efg --- tests/test_games/stripped_down_poker.efg | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 tests/test_games/stripped_down_poker.efg diff --git a/tests/test_games/stripped_down_poker.efg b/tests/test_games/stripped_down_poker.efg new file mode 100644 index 000000000..9c7eb66ec --- /dev/null +++ b/tests/test_games/stripped_down_poker.efg @@ -0,0 +1,14 @@ +EFG 2 R "A simple Poker game" { "Fred" "Alice" } +"Stripped-Down Poker: a simple game of one-card poker from Reiley et al (2008)." + +c "" 1 "(0,1)" { "King" 1/2 "Queen" 1/2 } 0 +p "" 1 1 "(1,1)" { "Bet" "Fold" } 0 +p "" 2 1 "(2,1)" { "Call" "Fold" } 0 +t "" 1 "Win Big" { 2, -2 } +t "" 2 "Win" { 1, -1 } +t "" 4 "Lose" { -1, 1 } +p "" 1 2 "(1,2)" { "Bet" "Fold" } 0 +p "" 2 1 "(2,1)" { "Call" "Fold" } 0 +t "" 3 "Lose Big" { -2, 2 } +t "" 2 "Win" { 1, -1 } +t "" 4 "Lose" { -1, 1 } From 4b0a3dc732c2b9f0fa6a78a14192310327d90ab0 Mon Sep 17 00:00:00 2001 From: Rahul Savani Date: Mon, 17 Nov 2025 13:21:59 +0000 Subject: [PATCH 04/17] Fred/Alice -> Alice/Bob; new infoset labels --- tests/test_behav.py | 120 +++++++++++------------ tests/test_games/stripped_down_poker.efg | 12 +-- tests/test_mixed.py | 86 ++++++++-------- 3 files changed, 109 insertions(+), 109 deletions(-) diff --git a/tests/test_behav.py b/tests/test_behav.py index dbf096167..638a8baf8 100644 --- a/tests/test_behav.py +++ b/tests/test_behav.py @@ -49,10 +49,10 @@ def test_payoff_reference(game: gbt.Game, player_idx: int, payoff: typing.Union[ (games.create_mixed_behav_game_efg(), "Player 1", "3", True), (games.create_mixed_behav_game_efg(), "Player 2", "3", True), (games.create_mixed_behav_game_efg(), "Player 3", "13/4", True), - (games.create_stripped_down_poker_efg(), "Fred", -0.25, False), - (games.create_stripped_down_poker_efg(), "Alice", 0.25, False), - (games.create_stripped_down_poker_efg(), "Fred", "-1/4", True), - (games.create_stripped_down_poker_efg(), "Alice", "1/4", True), + (games.create_stripped_down_poker_efg(), "Alice", -0.25, False), + (games.create_stripped_down_poker_efg(), "Bob", 0.25, False), + (games.create_stripped_down_poker_efg(), "Alice", "-1/4", True), + (games.create_stripped_down_poker_efg(), "Bob", "1/4", True), ] ) def test_payoff_by_label_reference(game: gbt.Game, label: str, payoff: typing.Union[str, float], @@ -85,12 +85,12 @@ def test_is_defined_at(game: gbt.Game, rational_flag: bool): (games.create_mixed_behav_game_efg(), "Infoset 1:1", True), (games.create_mixed_behav_game_efg(), "Infoset 2:1", True), (games.create_mixed_behav_game_efg(), "Infoset 3:1", True), - (games.create_stripped_down_poker_efg(), "(1,1)", False), - (games.create_stripped_down_poker_efg(), "(1,2)", False), - (games.create_stripped_down_poker_efg(), "(2,1)", False), - (games.create_stripped_down_poker_efg(), "(1,1)", True), - (games.create_stripped_down_poker_efg(), "(1,2)", True), - (games.create_stripped_down_poker_efg(), "(2,1)", True), + (games.create_stripped_down_poker_efg(), "Alice has King", False), + (games.create_stripped_down_poker_efg(), "Alice has Queen", False), + (games.create_stripped_down_poker_efg(), "Bob's response", False), + (games.create_stripped_down_poker_efg(), "Alice has King", True), + (games.create_stripped_down_poker_efg(), "Alice has Queen", True), + (games.create_stripped_down_poker_efg(), "Bob's response", True), ] ) def test_is_defined_at_by_label(game: gbt.Game, label: str, rational_flag: bool): @@ -212,14 +212,14 @@ def test_profile_indexing_by_invalid_infoset_label(rational_flag: bool): (games.create_mixed_behav_game_efg(), "Infoset 1:1", "D1", 0.5, False), (games.create_mixed_behav_game_efg(), "Infoset 1:1", "U1", "1/2", True), (games.create_mixed_behav_game_efg(), "Infoset 1:1", "D1", "1/2", True), - (games.create_stripped_down_poker_efg(), "(1,1)", "Bet", 0.5, False), - (games.create_stripped_down_poker_efg(), "(1,1)", "Fold", 0.5, False), - (games.create_stripped_down_poker_efg(), "(1,2)", "Bet", 0.5, False), - (games.create_stripped_down_poker_efg(), "(1,2)", "Fold", 0.5, False), - (games.create_stripped_down_poker_efg(), "(2,1)", "Call", 0.5, False), - (games.create_stripped_down_poker_efg(), "(2,1)", "Fold", 0.5, False), - (games.create_stripped_down_poker_efg(), "(2,1)", "Call", "1/2", True), - (games.create_stripped_down_poker_efg(), "(2,1)", "Fold", "1/2", True), + (games.create_stripped_down_poker_efg(), "Alice has King", "Bet", 0.5, False), + (games.create_stripped_down_poker_efg(), "Alice has King", "Fold", 0.5, False), + (games.create_stripped_down_poker_efg(), "Alice has Queen", "Bet", 0.5, False), + (games.create_stripped_down_poker_efg(), "Alice has Queen", "Fold", 0.5, False), + (games.create_stripped_down_poker_efg(), "Bob's response", "Call", 0.5, False), + (games.create_stripped_down_poker_efg(), "Bob's response", "Fold", 0.5, False), + (games.create_stripped_down_poker_efg(), "Bob's response", "Call", "1/2", True), + (games.create_stripped_down_poker_efg(), "Bob's response", "Fold", "1/2", True), ] ) def test_profile_indexing_by_infoset_and_action_labels_reference(game: gbt.Game, @@ -241,14 +241,14 @@ def test_profile_indexing_by_infoset_and_action_labels_reference(game: gbt.Game, (games.create_mixed_behav_game_efg(), "Player 1", "Infoset 1:1", "D1", 0.5, False), (games.create_mixed_behav_game_efg(), "Player 1", "Infoset 1:1", "U1", "1/2", True), (games.create_mixed_behav_game_efg(), "Player 1", "Infoset 1:1", "D1", "1/2", True), - (games.create_stripped_down_poker_efg(), "Fred", "(1,1)", "Bet", 0.5, False), - (games.create_stripped_down_poker_efg(), "Fred", "(1,1)", "Fold", 0.5, False), - (games.create_stripped_down_poker_efg(), "Fred", "(1,2)", "Bet", 0.5, False), - (games.create_stripped_down_poker_efg(), "Fred", "(1,2)", "Fold", 0.5, False), - (games.create_stripped_down_poker_efg(), "Alice", "(2,1)", "Call", 0.5, False), - (games.create_stripped_down_poker_efg(), "Alice", "(2,1)", "Fold", 0.5, False), - (games.create_stripped_down_poker_efg(), "Alice", "(2,1)", "Call", "1/2", True), - (games.create_stripped_down_poker_efg(), "Alice", "(2,1)", "Fold", "1/2", True), + (games.create_stripped_down_poker_efg(), "Alice", "Alice has King", "Bet", 0.5, False), + (games.create_stripped_down_poker_efg(), "Alice", "Alice has King", "Fold", 0.5, False), + (games.create_stripped_down_poker_efg(), "Alice", "Alice has Queen", "Bet", 0.5, False), + (games.create_stripped_down_poker_efg(), "Alice", "Alice has Queen", "Fold", 0.5, False), + (games.create_stripped_down_poker_efg(), "Bob", "Bob's response", "Call", 0.5, False), + (games.create_stripped_down_poker_efg(), "Bob", "Bob's response", "Fold", 0.5, False), + (games.create_stripped_down_poker_efg(), "Bob", "Bob's response", "Call", "1/2", True), + (games.create_stripped_down_poker_efg(), "Bob", "Bob's response", "Fold", "1/2", True), ] ) def test_profile_indexing_by_player_infoset_action_labels_reference(game: gbt.Game, @@ -271,8 +271,8 @@ def test_profile_indexing_by_player_infoset_action_labels_reference(game: gbt.Ga (games.create_mixed_behav_game_efg(), "1:1", "U2", False), (games.create_mixed_behav_game_efg(), "1:1", "U4", True), # U4 isn't in the game (games.create_mixed_behav_game_efg(), "1:1", "U4", False), - (games.create_stripped_down_poker_efg(), "(1,1)", "MEET", True), # MEET at different iset - (games.create_stripped_down_poker_efg(), "(1,1)", "MEET", False), + (games.create_stripped_down_poker_efg(), "Alice has King", "MEET", True), + (games.create_stripped_down_poker_efg(), "Alice has King", "MEET", False), ] ) def test_profile_indexing_by_invalid_infoset_or_action_label(game: gbt.Game, infoset_label: str, @@ -316,12 +316,12 @@ def test_profile_indexing_by_player_and_infoset_idx_reference(game: gbt.Game, (games.create_mixed_behav_game_efg(), 0, "Infoset 1:1", ["1/2", "1/2"], True), (games.create_mixed_behav_game_efg(), 1, "Infoset 2:1", ["1/2", "1/2"], True), (games.create_mixed_behav_game_efg(), 2, "Infoset 3:1", ["1/2", "1/2"], True), - (games.create_stripped_down_poker_efg(), 0, "(1,1)", [0.5, 0.5], False), - (games.create_stripped_down_poker_efg(), 0, "(1,2)", [0.5, 0.5], False), - (games.create_stripped_down_poker_efg(), 1, "(2,1)", [0.5, 0.5], False), - (games.create_stripped_down_poker_efg(), 0, "(1,1)", ["1/2", "1/2"], True), - (games.create_stripped_down_poker_efg(), 0, "(1,2)", ["1/2", "1/2"], True), - (games.create_stripped_down_poker_efg(), 1, "(2,1)", ["1/2", "1/2"], True), + (games.create_stripped_down_poker_efg(), 0, "Alice has King", [0.5, 0.5], False), + (games.create_stripped_down_poker_efg(), 0, "Alice has Queen", [0.5, 0.5], False), + (games.create_stripped_down_poker_efg(), 1, "Bob's response", [0.5, 0.5], False), + (games.create_stripped_down_poker_efg(), 0, "Alice has King", ["1/2", "1/2"], True), + (games.create_stripped_down_poker_efg(), 0, "Alice has Queen", ["1/2", "1/2"], True), + (games.create_stripped_down_poker_efg(), 1, "Bob's response", ["1/2", "1/2"], True), ] ) def test_profile_indexing_by_player_idx_infoset_label_reference(game: gbt.Game, player_idx: int, @@ -400,11 +400,11 @@ def test_profile_indexing_by_player_idx_reference(game: gbt.Game, player_idx: in (games.create_mixed_behav_game_efg(), "Player 1", [["1/2", "1/2"]], True), (games.create_mixed_behav_game_efg(), "Player 2", [["1/2", "1/2"]], True), (games.create_mixed_behav_game_efg(), "Player 3", [["1/2", "1/2"]], True), - (games.create_stripped_down_poker_efg(), "Fred", [[0.5, 0.5], [0.5, 0.5]], False), - (games.create_stripped_down_poker_efg(), "Alice", [[0.5, 0.5]], False), - (games.create_stripped_down_poker_efg(), "Fred", [["1/2", "1/2"], ["1/2", "1/2"]], + (games.create_stripped_down_poker_efg(), "Alice", [[0.5, 0.5], [0.5, 0.5]], False), + (games.create_stripped_down_poker_efg(), "Bob", [[0.5, 0.5]], False), + (games.create_stripped_down_poker_efg(), "Alice", [["1/2", "1/2"], ["1/2", "1/2"]], True), - (games.create_stripped_down_poker_efg(), "Alice", [["1/2", "1/2"]], True), + (games.create_stripped_down_poker_efg(), "Bob", [["1/2", "1/2"]], True), ] ) def test_profile_indexing_by_player_label_reference(game: gbt.Game, player_label: str, @@ -513,12 +513,12 @@ def test_set_probabilities_infoset(game: gbt.Game, player_idx: int, infoset_idx: (games.create_mixed_behav_game_efg(), "Infoset 1:1", ["7/9", "2/9"], True), (games.create_mixed_behav_game_efg(), "Infoset 2:1", ["4/13", "9/13"], True), (games.create_mixed_behav_game_efg(), "Infoset 3:1", ["1/98", "97/98"], True), - (games.create_stripped_down_poker_efg(), "(1,1)", [0.1, 0.9], False), - (games.create_stripped_down_poker_efg(), "(1,2)", [0.2, 0.8], False), - (games.create_stripped_down_poker_efg(), "(2,1)", [0.3, 0.7], False), - (games.create_stripped_down_poker_efg(), "(1,1)", ["1/10", "9/10"], True), - (games.create_stripped_down_poker_efg(), "(1,2)", ["2/10", "8/10"], True), - (games.create_stripped_down_poker_efg(), "(2,1)", ["3/10", "7/10"], True), + (games.create_stripped_down_poker_efg(), "Alice has King", [0.1, 0.9], False), + (games.create_stripped_down_poker_efg(), "Alice has Queen", [0.2, 0.8], False), + (games.create_stripped_down_poker_efg(), "Bob's response", [0.3, 0.7], False), + (games.create_stripped_down_poker_efg(), "Alice has King", ["1/10", "9/10"], True), + (games.create_stripped_down_poker_efg(), "Alice has Queen", ["2/10", "8/10"], True), + (games.create_stripped_down_poker_efg(), "Bob's response", ["3/10", "7/10"], True), ] ) def test_set_probabilities_infoset_by_label(game: gbt.Game, infoset_label: str, probs: list, @@ -562,11 +562,11 @@ def test_set_probabilities_player(game: gbt.Game, player_idx: int, behav_data: l (games.create_mixed_behav_game_efg(), "Player 1", [["7/9", "2/9"]], True), (games.create_mixed_behav_game_efg(), "Player 2", [["4/13", "9/13"]], True), (games.create_mixed_behav_game_efg(), "Player 3", [["1/98", "97/98"]], True), - (games.create_stripped_down_poker_efg(), "Fred", [[0.1, 0.9], [0.5, 0.5]], False), - (games.create_stripped_down_poker_efg(), "Alice", [[0.6, 0.4]], False), - (games.create_stripped_down_poker_efg(), "Fred", [["1/3", "2/3"], ["1/2", "1/2"]], + (games.create_stripped_down_poker_efg(), "Alice", [[0.1, 0.9], [0.5, 0.5]], False), + (games.create_stripped_down_poker_efg(), "Bob", [[0.6, 0.4]], False), + (games.create_stripped_down_poker_efg(), "Alice", [["1/3", "2/3"], ["1/2", "1/2"]], True), - (games.create_stripped_down_poker_efg(), "Alice", [["2/3", "1/3"]], True), + (games.create_stripped_down_poker_efg(), "Bob", [["2/3", "1/3"]], True), ] ) def test_set_probabilities_player_by_label(game: gbt.Game, player_label: str, behav_data: list, @@ -672,12 +672,12 @@ def test_infoset_prob_reference(game: gbt.Game, player_idx: int, infoset_idx: in (games.create_mixed_behav_game_efg(), "Infoset 1:1", "1", True), (games.create_mixed_behav_game_efg(), "Infoset 2:1", "1", True), (games.create_mixed_behav_game_efg(), "Infoset 3:1", "1", True), - (games.create_stripped_down_poker_efg(), "(1,1)", 0.5, False), - (games.create_stripped_down_poker_efg(), "(1,2)", 0.5, False), - (games.create_stripped_down_poker_efg(), "(2,1)", 0.5, False), - (games.create_stripped_down_poker_efg(), "(1,1)", "1/2", True), - (games.create_stripped_down_poker_efg(), "(1,2)", "1/2", True), - (games.create_stripped_down_poker_efg(), "(2,1)", "1/2", True), + (games.create_stripped_down_poker_efg(), "Alice has King", 0.5, False), + (games.create_stripped_down_poker_efg(), "Alice has Queen", 0.5, False), + (games.create_stripped_down_poker_efg(), "Bob's response", 0.5, False), + (games.create_stripped_down_poker_efg(), "Alice has King", "1/2", True), + (games.create_stripped_down_poker_efg(), "Alice has Queen", "1/2", True), + (games.create_stripped_down_poker_efg(), "Bob's response", "1/2", True), ] ) def test_infoset_prob_by_label_reference(game: gbt.Game, label: str, @@ -717,12 +717,12 @@ def test_infoset_payoff_reference(game: gbt.Game, player_idx: int, infoset_idx: (games.create_mixed_behav_game_efg(), "Infoset 1:1", "3", True), (games.create_mixed_behav_game_efg(), "Infoset 2:1", "3", True), (games.create_mixed_behav_game_efg(), "Infoset 3:1", "13/4", True), - (games.create_stripped_down_poker_efg(), "(1,1)", 0.25, False), - (games.create_stripped_down_poker_efg(), "(1,2)", -0.75, False), - (games.create_stripped_down_poker_efg(), "(2,1)", -0.5, False), - (games.create_stripped_down_poker_efg(), "(1,1)", "1/4", True), - (games.create_stripped_down_poker_efg(), "(1,2)", "-3/4", True), - (games.create_stripped_down_poker_efg(), "(2,1)", "-1/2", True), + (games.create_stripped_down_poker_efg(), "Alice has King", 0.25, False), + (games.create_stripped_down_poker_efg(), "Alice has Queen", -0.75, False), + (games.create_stripped_down_poker_efg(), "Bob's response", -0.5, False), + (games.create_stripped_down_poker_efg(), "Alice has King", "1/4", True), + (games.create_stripped_down_poker_efg(), "Alice has Queen", "-3/4", True), + (games.create_stripped_down_poker_efg(), "Bob's response", "-1/2", True), ] ) def test_infoset_payoff_by_label_reference(game: gbt.Game, label: str, diff --git a/tests/test_games/stripped_down_poker.efg b/tests/test_games/stripped_down_poker.efg index 9c7eb66ec..8a21af1ff 100644 --- a/tests/test_games/stripped_down_poker.efg +++ b/tests/test_games/stripped_down_poker.efg @@ -1,14 +1,14 @@ -EFG 2 R "A simple Poker game" { "Fred" "Alice" } +EFG 2 R "A simple Poker game" { "Alice" "Bob" } "Stripped-Down Poker: a simple game of one-card poker from Reiley et al (2008)." -c "" 1 "(0,1)" { "King" 1/2 "Queen" 1/2 } 0 -p "" 1 1 "(1,1)" { "Bet" "Fold" } 0 -p "" 2 1 "(2,1)" { "Call" "Fold" } 0 +c "" 1 "Deal" { "King" 1/2 "Queen" 1/2 } 0 +p "" 1 1 "Alice has King" { "Bet" "Fold" } 0 +p "" 2 1 "Bob's response" { "Call" "Fold" } 0 t "" 1 "Win Big" { 2, -2 } t "" 2 "Win" { 1, -1 } t "" 4 "Lose" { -1, 1 } -p "" 1 2 "(1,2)" { "Bet" "Fold" } 0 -p "" 2 1 "(2,1)" { "Call" "Fold" } 0 +p "" 1 2 "Alice has Queen" { "Bet" "Fold" } 0 +p "" 2 1 "Bob's response" { "Call" "Fold" } 0 t "" 3 "Lose Big" { -2, 2 } t "" 2 "Win" { 1, -1 } t "" 4 "Lose" { -1, 1 } diff --git a/tests/test_mixed.py b/tests/test_mixed.py index b37763d74..82658bfd1 100644 --- a/tests/test_mixed.py +++ b/tests/test_mixed.py @@ -138,10 +138,10 @@ def test_set_and_get_probability_by_strategy_label(game: gbt.Game, strategy_labe (games.create_coord_4x4_nfg(), P1, True, ["1/4", 0, 0, "3/4"]), ############################################################################## # stripped-down poker efg - (games.create_stripped_down_poker_efg(), "Fred", False, [0.25, 0.75, 0, 0]), - (games.create_stripped_down_poker_efg(), "Alice", False, [1, 0]), - (games.create_stripped_down_poker_efg(), "Fred", True, ["1/4", "3/4", 0, 0]), - (games.create_stripped_down_poker_efg(), "Alice", True, [1, 0]), + (games.create_stripped_down_poker_efg(), "Alice", False, [0.25, 0.75, 0, 0]), + (games.create_stripped_down_poker_efg(), "Bob", False, [1, 0]), + (games.create_stripped_down_poker_efg(), "Alice", True, ["1/4", "3/4", 0, 0]), + (games.create_stripped_down_poker_efg(), "Bob", True, [1, 0]), ], ) def test_set_and_get_probabilities_by_player_label(game: gbt.Game, player_label: str, @@ -158,19 +158,19 @@ def test_set_and_get_probabilities_by_player_label(game: gbt.Game, player_label: ############################################################################## # stripped-down poker efg # Player 1 - (games.create_stripped_down_poker_efg(), "Fred", "11", 0.25, False), - (games.create_stripped_down_poker_efg(), "Fred", "12", 0.25, False), - (games.create_stripped_down_poker_efg(), "Fred", "21", 0.25, False), - (games.create_stripped_down_poker_efg(), "Fred", "22", 0.25, False), - (games.create_stripped_down_poker_efg(), "Fred", "11", "1/4", True), - (games.create_stripped_down_poker_efg(), "Fred", "12", "1/4", True), - (games.create_stripped_down_poker_efg(), "Fred", "21", "1/4", True), - (games.create_stripped_down_poker_efg(), "Fred", "22", "1/4", True), + (games.create_stripped_down_poker_efg(), "Alice", "11", 0.25, False), + (games.create_stripped_down_poker_efg(), "Alice", "12", 0.25, False), + (games.create_stripped_down_poker_efg(), "Alice", "21", 0.25, False), + (games.create_stripped_down_poker_efg(), "Alice", "22", 0.25, False), + (games.create_stripped_down_poker_efg(), "Alice", "11", "1/4", True), + (games.create_stripped_down_poker_efg(), "Alice", "12", "1/4", True), + (games.create_stripped_down_poker_efg(), "Alice", "21", "1/4", True), + (games.create_stripped_down_poker_efg(), "Alice", "22", "1/4", True), # Player 2 - (games.create_stripped_down_poker_efg(), "Alice", "1", 0.5, False), - (games.create_stripped_down_poker_efg(), "Alice", "2", 0.5, False), - (games.create_stripped_down_poker_efg(), "Alice", "1", "1/2", True), - (games.create_stripped_down_poker_efg(), "Alice", "2", "1/2", True), + (games.create_stripped_down_poker_efg(), "Bob", "1", 0.5, False), + (games.create_stripped_down_poker_efg(), "Bob", "2", 0.5, False), + (games.create_stripped_down_poker_efg(), "Bob", "1", "1/2", True), + (games.create_stripped_down_poker_efg(), "Bob", "2", "1/2", True), ############################################################################## # coordination 4x4 nfg outcome version with strategy labels (games.create_coord_4x4_nfg(outcome_version=True), P1, "1-1", "1/4", True), @@ -191,12 +191,12 @@ def test_profile_indexing_by_player_and_strategy_label_reference(game: gbt.Game, [ ############################################################################## # stripped-down poker efg - (games.create_stripped_down_poker_efg(), "Alice", "11", True), - (games.create_stripped_down_poker_efg(), "Alice", "11", False), - (games.create_stripped_down_poker_efg(), "Fred", "1", True), - (games.create_stripped_down_poker_efg(), "Fred", "1", False), - (games.create_stripped_down_poker_efg(), "Fred", "2", True), - (games.create_stripped_down_poker_efg(), "Fred", "2", False), + (games.create_stripped_down_poker_efg(), "Bob", "11", True), + (games.create_stripped_down_poker_efg(), "Bob", "11", False), + (games.create_stripped_down_poker_efg(), "Alice", "1", True), + (games.create_stripped_down_poker_efg(), "Alice", "1", False), + (games.create_stripped_down_poker_efg(), "Alice", "2", True), + (games.create_stripped_down_poker_efg(), "Alice", "2", False), ############################################################################## # coordination 4x4 nfg outcome version with strategy labels (games.create_coord_4x4_nfg(outcome_version=True), P1, "2-1", True), @@ -295,10 +295,10 @@ def test_profile_indexing_by_strategy_label_reference(game: gbt.Game, strategy_l (games.create_mixed_behav_game_efg(), P3, ["1/2", "1/2"], True), ############################################################################ # stripped-down poker efg - (games.create_stripped_down_poker_efg(), "Fred", [0.25, 0.25, 0.25, 0.25], False), - (games.create_stripped_down_poker_efg(), "Alice", [0.5, 0.5], False), - (games.create_stripped_down_poker_efg(), "Fred", ["1/4", "1/4", "1/4", "1/4"], True), - (games.create_stripped_down_poker_efg(), "Alice", ["1/2", "1/2"], True), + (games.create_stripped_down_poker_efg(), "Alice", [0.25, 0.25, 0.25, 0.25], False), + (games.create_stripped_down_poker_efg(), "Bob", [0.5, 0.5], False), + (games.create_stripped_down_poker_efg(), "Alice", ["1/4", "1/4", "1/4", "1/4"], True), + (games.create_stripped_down_poker_efg(), "Bob", ["1/2", "1/2"], True), ############################################################################ # coordination 4x4 nfg (games.create_coord_4x4_nfg(), P1, [0.25, 0.25, 0.25, 0.25], False), @@ -338,24 +338,24 @@ def test_profile_indexing_by_player_label_reference(game: gbt.Game, player_label (games.create_coord_4x4_nfg(), True, [[1, 0, 0, 0], [0, 1, 0, 0]], P2, 0), ######################################################################### # stripped-down poker efg - (games.create_stripped_down_poker_efg(), False, None, "Fred", -0.25), - (games.create_stripped_down_poker_efg(), False, None, "Alice", 0.25), - (games.create_stripped_down_poker_efg(), True, None, "Fred", "-1/4"), - (games.create_stripped_down_poker_efg(), True, None, "Alice", "1/4"), - # Raise/Raise for player 1 - (games.create_stripped_down_poker_efg(), False, [[1, 0, 0, 0], [1, 0]], "Fred", 0), - (games.create_stripped_down_poker_efg(), False, [[1, 0, 0, 0], [1, 0]], "Alice", 0), - (games.create_stripped_down_poker_efg(), True, [[1, 0, 0, 0], [1, 0]], "Fred", 0), - (games.create_stripped_down_poker_efg(), True, [[1, 0, 0, 0], [1, 0]], "Alice", 0), + (games.create_stripped_down_poker_efg(), False, None, "Alice", -0.25), + (games.create_stripped_down_poker_efg(), False, None, "Bob", 0.25), + (games.create_stripped_down_poker_efg(), True, None, "Alice", "-1/4"), + (games.create_stripped_down_poker_efg(), True, None, "Bob", "1/4"), + # Bet/Call + (games.create_stripped_down_poker_efg(), False, [[1, 0, 0, 0], [1, 0]], "Alice", 0), + (games.create_stripped_down_poker_efg(), False, [[1, 0, 0, 0], [1, 0]], "Bob", 0), + (games.create_stripped_down_poker_efg(), True, [[1, 0, 0, 0], [1, 0]], "Alice", 0), + (games.create_stripped_down_poker_efg(), True, [[1, 0, 0, 0], [1, 0]], "Bob", 0), # Fold/Fold for player 1 (player 2's strategy is payoff-irrelevant) - (games.create_stripped_down_poker_efg(), False, [[0, 0, 0, 1], [1, 0]], "Fred", -1), - (games.create_stripped_down_poker_efg(), False, [[0, 0, 0, 1], [1, 0]], "Alice", 1), - (games.create_stripped_down_poker_efg(), True, [[0, 0, 0, 1], [1, 0]], "Fred", -1), - (games.create_stripped_down_poker_efg(), True, [[0, 0, 0, 1], [1, 0]], "Alice", 1), - (games.create_stripped_down_poker_efg(), False, [[0, 0, 0, 1], [0.5, 0.5]], "Fred", -1), - (games.create_stripped_down_poker_efg(), False, [[0, 0, 0, 1], [0.5, 0.5]], "Alice", 1), - (games.create_stripped_down_poker_efg(), True, [[0, 0, 0, 1], ["1/2", "1/2"]], "Fred", -1), - (games.create_stripped_down_poker_efg(), True, [[0, 0, 0, 1], ["1/2", "1/2"]], "Alice", 1), + (games.create_stripped_down_poker_efg(), False, [[0, 0, 0, 1], [1, 0]], "Alice", -1), + (games.create_stripped_down_poker_efg(), False, [[0, 0, 0, 1], [1, 0]], "Bob", 1), + (games.create_stripped_down_poker_efg(), True, [[0, 0, 0, 1], [1, 0]], "Alice", -1), + (games.create_stripped_down_poker_efg(), True, [[0, 0, 0, 1], [1, 0]], "Bob", 1), + (games.create_stripped_down_poker_efg(), False, [[0, 0, 0, 1], [0.5, 0.5]], "Alice", -1), + (games.create_stripped_down_poker_efg(), False, [[0, 0, 0, 1], [0.5, 0.5]], "Bob", 1), + (games.create_stripped_down_poker_efg(), True, [[0, 0, 0, 1], ["1/2", "1/2"]], "Alice", -1), + (games.create_stripped_down_poker_efg(), True, [[0, 0, 0, 1], ["1/2", "1/2"]], "Bob", 1), ######################################################################### (games.create_mixed_behav_game_efg(), False, None, P1, 3.0), (games.create_mixed_behav_game_efg(), False, None, P2, 3.0), From 346ce45185a61c7f31665c449b86e09030359013 Mon Sep 17 00:00:00 2001 From: Ed Chalstrey Date: Mon, 17 Nov 2025 15:16:43 +0000 Subject: [PATCH 05/17] update game title in tutorial 3 --- doc/tutorials/03_poker.ipynb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/tutorials/03_poker.ipynb b/doc/tutorials/03_poker.ipynb index 14292df75..8389dbc49 100644 --- a/doc/tutorials/03_poker.ipynb +++ b/doc/tutorials/03_poker.ipynb @@ -53,14 +53,14 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "ad6a1119", "metadata": {}, "outputs": [], "source": [ "g = gbt.Game.new_tree(\n", " players=[\"Alice\", \"Bob\"],\n", - " title=\"One card poker\"\n", + " title=\"Stripped-Down Poker: a simple game of one-card poker from Reiley et al (2008).\"\n", ")" ] }, From a96b03f18fc92bdfc576b96c82e92567175c4162 Mon Sep 17 00:00:00 2001 From: Ed Chalstrey Date: Mon, 17 Nov 2025 15:22:59 +0000 Subject: [PATCH 06/17] change action labels to Bet/Call and Fold --- doc/tutorials/03_poker.ipynb | 272 +++++++++++++++++------------------ 1 file changed, 136 insertions(+), 136 deletions(-) diff --git a/doc/tutorials/03_poker.ipynb b/doc/tutorials/03_poker.ipynb index 8389dbc49..ec401eccc 100644 --- a/doc/tutorials/03_poker.ipynb +++ b/doc/tutorials/03_poker.ipynb @@ -22,12 +22,12 @@ " - A card is dealt at random to Alice\n", " - Alice observes her card\n", " - Bob does not observe the card\n", - "- Alice then chooses either to **Raise** or to **Fold**.\n", + "- Alice then chooses either to **Bet** or to **Fold**.\n", " - If she chooses to Fold, Bob wins the pot and the game ends.\n", - " - If she chooses to Raise, she adds another \\$1 to the pot.\n", - "- Bob then chooses either to **Meet** or **Pass**.\n", - " - If he chooses to Pass, Alice wins the pot and the game ends.\n", - " - If he chooses to Meet, he adds another $1 to the pot.\n", + " - If she chooses to Bet, she adds another \\$1 to the pot.\n", + "- Bob then chooses either to **Call** or **Fold**.\n", + " - If he chooses to Fold, Alice wins the pot and the game ends.\n", + " - If he chooses to Call, he adds another $1 to the pot.\n", "- There is then a showdown, in which Alice reveals her card.\n", " - If she has a King, then she wins the pot;\n", " - If she has a Queen, then Bob wins the pot." @@ -35,7 +35,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 20, "id": "69cbfe81", "metadata": {}, "outputs": [], @@ -53,7 +53,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 21, "id": "ad6a1119", "metadata": {}, "outputs": [], @@ -74,7 +74,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 22, "id": "841f9f74", "metadata": {}, "outputs": [ @@ -82,9 +82,9 @@ "name": "stdout", "output_type": "stream", "text": [ - "Player(game=Game(title='One card poker'), label='Alice')\n", - "Player(game=Game(title='One card poker'), label='Bob')\n", - "ChancePlayer(game=Game(title='One card poker'))\n" + "Player(game=Game(title='Stripped-Down Poker: a simple game of one-card poker from Reiley et al (2008).'), label='Alice')\n", + "Player(game=Game(title='Stripped-Down Poker: a simple game of one-card poker from Reiley et al (2008).'), label='Bob')\n", + "ChancePlayer(game=Game(title='Stripped-Down Poker: a simple game of one-card poker from Reiley et al (2008).'))\n" ] } ], @@ -110,7 +110,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 23, "id": "fe80c64c", "metadata": {}, "outputs": [], @@ -138,7 +138,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 24, "id": "0e3bb5ef", "metadata": {}, "outputs": [], @@ -147,7 +147,7 @@ " g.append_move(\n", " node,\n", " player=\"Alice\",\n", - " actions=[\"Raise\", \"Fold\"]\n", + " actions=[\"Bet\", \"Fold\"]\n", " )" ] }, @@ -160,27 +160,27 @@ "\n", "In contrast, Bob does not know Alice’s card, and therefore cannot distinguish between the two nodes at which he has to make his decision:\n", "\n", - " - Chance player chooses King, then Alice Raises: `g.root.children[\"King\"].children[\"Raise\"]`\n", - " - Chance player chooses Queen, then Alice Raises: `g.root.children[\"Queen\"].children[\"Raise\"]`\n", + " - Chance player chooses King, then Alice Bets: `g.root.children[\"King\"].children[\"Bet\"]`\n", + " - Chance player chooses Queen, then Alice Bets: `g.root.children[\"Queen\"].children[\"Bet\"]`\n", "\n", - "In other words, Bob's decision when Alice raises with a Queen should be part of the same information set as Bob's decision when Alice raises with a King.\n", + "In other words, Bob's decision when Alice Bets with a Queen should be part of the same information set as Bob's decision when Alice Bets with a King.\n", "\n", "To set this scenario up in Gambit, we'll need to use `Game.append_infoset` to add a move as part of an existing information set (represented in Gambit as an `Infoset`).\n", "\n", - "First, let's add Bob's move to the node where Alice has raised with a King." + "First, let's add Bob's move to the node where Alice has Betd with a King." ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 25, "id": "dbfa7035", "metadata": {}, "outputs": [], "source": [ "g.append_move(\n", - " g.root.children[\"King\"].children[\"Raise\"],\n", + " g.root.children[\"King\"].children[\"Bet\"],\n", " player=\"Bob\",\n", - " actions=[\"Meet\", \"Pass\"]\n", + " actions=[\"Call\", \"Fold\"]\n", ")" ] }, @@ -189,19 +189,19 @@ "id": "689ce12c", "metadata": {}, "source": [ - "Now let's add the information set we created at the node where Alice raised with a King, to the node where Alice raised with a Queen." + "Now let's add the information set we created at the node where Alice Betd with a King, to the node where Alice Betd with a Queen." ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 26, "id": "655cdae3", "metadata": {}, "outputs": [], "source": [ "g.append_infoset(\n", - " g.root.children[\"Queen\"].children[\"Raise\"],\n", - " infoset=g.root.children[\"King\"].children[\"Raise\"].infoset\n", + " g.root.children[\"Queen\"].children[\"Bet\"],\n", + " infoset=g.root.children[\"King\"].children[\"Bet\"].infoset\n", ")" ] }, @@ -211,7 +211,7 @@ "metadata": {}, "source": [ "In game theory terms, this creates \"imperfect information\".\n", - "Bob cannot distinguish between these two nodes in the game tree, so he must use the same strategy (same probabilities for Meet vs. Pass) in both situations.\n", + "Bob cannot distinguish between these two nodes in the game tree, so he must use the same strategy (same probabilities for Call vs. Fold) in both situations.\n", "\n", "This is crucial in games where players must make decisions without complete knowledge of their opponents' private information.\n", "\n", @@ -220,7 +220,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 27, "id": "87c988be", "metadata": {}, "outputs": [], @@ -241,7 +241,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 28, "id": "29aa60a0", "metadata": {}, "outputs": [], @@ -250,15 +250,15 @@ "g.set_outcome(g.root.children[\"King\"].children[\"Fold\"], bob_wins)\n", "g.set_outcome(g.root.children[\"Queen\"].children[\"Fold\"], bob_wins)\n", "\n", - "# Bob sees Alice raise and calls, correctly believing she is bluffing, Bob wins big\n", - "g.set_outcome(g.root.children[\"Queen\"].children[\"Raise\"].children[\"Meet\"], bob_winsbig)\n", + "# Bob sees Alice Bet and calls, correctly believing she is bluffing, Bob wins big\n", + "g.set_outcome(g.root.children[\"Queen\"].children[\"Bet\"].children[\"Call\"], bob_winsbig)\n", "\n", - "# Bob sees Alice raise and calls, incorrectly believing she is bluffing, Alice wins big\n", - "g.set_outcome(g.root.children[\"King\"].children[\"Raise\"].children[\"Meet\"], alice_winsbig)\n", + "# Bob sees Alice Bet and calls, incorrectly believing she is bluffing, Alice wins big\n", + "g.set_outcome(g.root.children[\"King\"].children[\"Bet\"].children[\"Call\"], alice_winsbig)\n", "\n", - "# Bob does not call Alice's raise, Alice wins small\n", - "g.set_outcome(g.root.children[\"King\"].children[\"Raise\"].children[\"Pass\"], alice_wins)\n", - "g.set_outcome(g.root.children[\"Queen\"].children[\"Raise\"].children[\"Pass\"], alice_wins)" + "# Bob does not call Alice's Bet, Alice wins small\n", + "g.set_outcome(g.root.children[\"King\"].children[\"Bet\"].children[\"Fold\"], alice_wins)\n", + "g.set_outcome(g.root.children[\"Queen\"].children[\"Bet\"].children[\"Fold\"], alice_wins)" ] }, { @@ -274,7 +274,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 29, "id": "4d92c8d9", "metadata": {}, "outputs": [ @@ -284,7 +284,7 @@ "NashComputationResult(method='lcp', rational=True, use_strategic=False, equilibria=[[[[Rational(1, 1), Rational(0, 1)], [Rational(1, 3), Rational(2, 3)]], [[Rational(2, 3), Rational(1, 3)]]]], parameters={'stop_after': 0, 'max_depth': 0})" ] }, - "execution_count": 10, + "execution_count": 29, "metadata": {}, "output_type": "execute_result" } @@ -308,7 +308,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 30, "id": "9967d6f7", "metadata": {}, "outputs": [ @@ -327,7 +327,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 31, "id": "3293e818", "metadata": {}, "outputs": [ @@ -337,7 +337,7 @@ "pygambit.gambit.MixedBehaviorProfileRational" ] }, - "execution_count": 12, + "execution_count": 31, "metadata": {}, "output_type": "execute_result" } @@ -360,7 +360,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 32, "id": "4cf38264", "metadata": {}, "outputs": [ @@ -370,7 +370,7 @@ "pygambit.gambit.MixedBehavior" ] }, - "execution_count": 13, + "execution_count": 32, "metadata": {}, "output_type": "execute_result" } @@ -381,7 +381,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 33, "id": "85e7fdda", "metadata": {}, "outputs": [ @@ -394,7 +394,7 @@ "[[Rational(1, 1), Rational(0, 1)], [Rational(1, 3), Rational(2, 3)]]" ] }, - "execution_count": 14, + "execution_count": 33, "metadata": {}, "output_type": "execute_result" } @@ -408,7 +408,7 @@ "id": "6615115d", "metadata": {}, "source": [ - "In this case, at Alice's first information set, the one at which she has the King, she always raises.\n", + "In this case, at Alice's first information set, the one at which she has the King, she always Bets.\n", "\n", "At her second information set, where she has the Queen, she sometimes bluffs, raising with probability one-third.\n", "\n", @@ -419,7 +419,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 34, "id": "f45a82b6", "metadata": {}, "outputs": [ @@ -427,8 +427,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "At information set 0, Alice plays Raise with probability: 1 and Fold with probability: 0\n", - "At information set 1, Alice plays Raise with probability: 1/3 and Fold with probability: 2/3\n" + "At information set 0, Alice plays Bet with probability: 1 and Fold with probability: 0\n", + "At information set 1, Alice plays Bet with probability: 1/3 and Fold with probability: 2/3\n" ] } ], @@ -436,7 +436,7 @@ "for infoset, mixed_action in eqm[\"Alice\"].mixed_actions():\n", " print(\n", " f\"At information set {infoset.number}, \"\n", - " f\"Alice plays Raise with probability: {mixed_action['Raise']}\"\n", + " f\"Alice plays Bet with probability: {mixed_action['Bet']}\"\n", " f\" and Fold with probability: {mixed_action['Fold']}\"\n", " )" ] @@ -451,7 +451,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 35, "id": "83bbd3e5", "metadata": {}, "outputs": [ @@ -459,9 +459,9 @@ "name": "stdout", "output_type": "stream", "text": [ - "At information set 0, Alice plays Raise with probability: 1\n", + "At information set 0, Alice plays Bet with probability: 1\n", "At information set 0, Alice plays Fold with probability: 0\n", - "At information set 1, Alice plays Raise with probability: 1/3\n", + "At information set 1, Alice plays Bet with probability: 1/3\n", "At information set 1, Alice plays Fold with probability: 2/3\n" ] } @@ -484,7 +484,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 36, "id": "6bf51b38", "metadata": {}, "outputs": [ @@ -497,7 +497,7 @@ "[[Rational(2, 3), Rational(1, 3)]]" ] }, - "execution_count": 17, + "execution_count": 36, "metadata": {}, "output_type": "execute_result" } @@ -511,16 +511,16 @@ "id": "e906c4c4", "metadata": {}, "source": [ - "Bob meets Alice’s raise two-thirds of the time.\n", - "The label “Raise” is used in more than one information set for Alice, so in the above we had to specify information sets when indexing.\n", + "Bob Calls Alice’s Bet two-thirds of the time.\n", + "The label “Bet” is used in more than one information set for Alice, so in the above we had to specify information sets when indexing.\n", "\n", "When there is no ambiguity, we can specify action labels directly.\n", - "So for example, because Bob has only one action named “Meet” in the game, we can extract the probability that Bob plays “Meet” by:" + "So for example, because Bob has only one action named “Call” in the game, we can extract the probability that Bob plays “Call” by:" ] }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 37, "id": "2966e700", "metadata": {}, "outputs": [ @@ -533,13 +533,13 @@ "Rational(2, 3)" ] }, - "execution_count": 18, + "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "eqm[\"Bob\"][\"Meet\"]" + "eqm[\"Bob\"][\"Call\"]" ] }, { @@ -552,7 +552,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 38, "id": "f5a7f110", "metadata": {}, "outputs": [ @@ -565,13 +565,13 @@ "Rational(2, 3)" ] }, - "execution_count": 19, + "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "eqm[\"Meet\"]" + "eqm[\"Call\"]" ] }, { @@ -586,7 +586,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 39, "id": "a7d3816d", "metadata": {}, "outputs": [ @@ -594,8 +594,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "When Bob plays Meet his expected payoff is -1\n", - "When Bob plays Pass his expected payoff is -1\n" + "When Bob plays Call his expected payoff is -1\n", + "When Bob plays Fold his expected payoff is -1\n" ] } ], @@ -616,12 +616,12 @@ "\n", "`MixedBehaviorProfile.belief` returns the probability of reaching a node, conditional on its information set being reached.\n", "\n", - "Recall that the two nodes in Bob's only information set are `g.root.children[\"King\"].children[\"Raise\"]` and `g.root.children[\"Queen\"].children[\"Raise\"]`):" + "Recall that the two nodes in Bob's only information set are `g.root.children[\"King\"].children[\"Bet\"]` and `g.root.children[\"Queen\"].children[\"Bet\"]`):" ] }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 40, "id": "4a54b20c", "metadata": {}, "outputs": [ @@ -629,8 +629,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "Bob's belief in reaching the King -> Raise node is: 3/4\n", - "Bob's belief in reaching the Queen -> Raise node is: 1/4\n" + "Bob's belief in reaching the King -> Bet node is: 3/4\n", + "Bob's belief in reaching the Queen -> Bet node is: 1/4\n" ] } ], @@ -647,14 +647,14 @@ "id": "351bb3ce", "metadata": {}, "source": [ - "Bob believes that, conditional on Alice raising, there's a 3/4 chance that she has the King; therefore, the expected payoff to meeting is in fact -1 as computed.\n", + "Bob believes that, conditional on Alice raising, there's a 3/4 chance that she has the King; therefore, the expected payoff to Calling is in fact -1 as computed.\n", "\n", "`MixedBehaviorProfile.infoset_prob` returns the probability that an information set is reached:" ] }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 41, "id": "b250c1cd", "metadata": {}, "outputs": [ @@ -667,7 +667,7 @@ "Rational(2, 3)" ] }, - "execution_count": 22, + "execution_count": 41, "metadata": {}, "output_type": "execute_result" } @@ -686,7 +686,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 42, "id": "6f01846b", "metadata": {}, "outputs": [ @@ -694,8 +694,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "The probability that the node King -> Raise is reached is: 1/2. Bob's expected payoff conditional on reaching this node is -5/3\n", - "The probability that the node Queen -> Raise is reached is: 1/6. Bob's expected payoff conditional on reaching this node is 1\n" + "The probability that the node King -> Bet is reached is: 1/2. Bob's expected payoff conditional on reaching this node is -5/3\n", + "The probability that the node Queen -> Bet is reached is: 1/6. Bob's expected payoff conditional on reaching this node is 1\n" ] } ], @@ -718,7 +718,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 43, "id": "5079d231", "metadata": {}, "outputs": [ @@ -731,7 +731,7 @@ "Rational(1, 3)" ] }, - "execution_count": 24, + "execution_count": 43, "metadata": {}, "output_type": "execute_result" } @@ -742,7 +742,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 44, "id": "c55f2c7a", "metadata": {}, "outputs": [ @@ -755,7 +755,7 @@ "Rational(-1, 3)" ] }, - "execution_count": 25, + "execution_count": 44, "metadata": {}, "output_type": "execute_result" } @@ -782,7 +782,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 45, "id": "d4ecff88", "metadata": {}, "outputs": [ @@ -792,7 +792,7 @@ "['11', '12', '21', '22']" ] }, - "execution_count": 26, + "execution_count": 45, "metadata": {}, "output_type": "execute_result" } @@ -809,14 +809,14 @@ "In the strategic form of this game, Alice has four strategies.\n", "\n", "The generated strategy labels list the action numbers taken at each information set.\n", - "For example, label '11' refers to the strategy gets dealt the King, then raises.\n", + "For example, label '11' refers to the strategy gets dealt the King, then Bets.\n", "\n", "We can therefore apply a method which operates on a strategic game to any game with an extensive representation." ] }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 46, "id": "24e4b6e8", "metadata": {}, "outputs": [ @@ -826,7 +826,7 @@ "NashComputationResult(method='gnm', rational=False, use_strategic=True, equilibria=[[[0.33333333333866677, 0.6666666666613335, 0.0, 0.0], [0.6666666666559997, 0.3333333333440004]]], parameters={'perturbation': [[1.0, 0.0, 0.0, 0.0], [1.0, 0.0]], 'end_lambda': -10.0, 'steps': 100, 'local_newton_interval': 3, 'local_newton_maxits': 10})" ] }, - "execution_count": 27, + "execution_count": 46, "metadata": {}, "output_type": "execute_result" } @@ -848,7 +848,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 47, "id": "d9ffb4b8", "metadata": {}, "outputs": [ @@ -858,7 +858,7 @@ "pygambit.gambit.MixedStrategyProfileDouble" ] }, - "execution_count": 28, + "execution_count": 47, "metadata": {}, "output_type": "execute_result" } @@ -880,7 +880,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 48, "id": "56e2f847", "metadata": {}, "outputs": [ @@ -933,7 +933,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 49, "id": "d18a91f0", "metadata": {}, "outputs": [ @@ -942,14 +942,14 @@ "output_type": "stream", "text": [ "Alice's expected payoffs:\n", - "At information set 0, when playing Raise - gnm: 1.6667, lcp: 1.6667\n", + "At information set 0, when playing Bet - gnm: 1.6667, lcp: 1.6667\n", "At information set 0, when playing Fold - gnm: -1.0000, lcp: -1.0000\n", - "At information set 1, when playing Raise - gnm: -1.0000, lcp: -1.0000\n", + "At information set 1, when playing Bet - gnm: -1.0000, lcp: -1.0000\n", "At information set 1, when playing Fold - gnm: -1.0000, lcp: -1.0000\n", "\n", "Bob's expected payoffs:\n", - "At information set 0, when playing Meet - gnm: -1.0000, lcp: -1.0000\n", - "At information set 0, when playing Pass - gnm: -1.0000, lcp: -1.0000\n", + "At information set 0, when playing Call - gnm: -1.0000, lcp: -1.0000\n", + "At information set 0, when playing Fold - gnm: -1.0000, lcp: -1.0000\n", "\n" ] } @@ -999,7 +999,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 50, "id": "0c55f745", "metadata": {}, "outputs": [ @@ -1009,7 +1009,7 @@ "(Rational(2, 1), Rational(-2, 1))" ] }, - "execution_count": 31, + "execution_count": 50, "metadata": {}, "output_type": "execute_result" } @@ -1031,7 +1031,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 51, "id": "101598c6", "metadata": {}, "outputs": [ @@ -1041,7 +1041,7 @@ "1" ] }, - "execution_count": 32, + "execution_count": 51, "metadata": {}, "output_type": "execute_result" } @@ -1053,7 +1053,7 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 52, "id": "9b142728", "metadata": {}, "outputs": [ @@ -1063,7 +1063,7 @@ "3.987411578698641e-08" ] }, - "execution_count": 33, + "execution_count": 52, "metadata": {}, "output_type": "execute_result" } @@ -1084,7 +1084,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 53, "id": "ff405409", "metadata": {}, "outputs": [ @@ -1094,7 +1094,7 @@ "9.968528946746602e-09" ] }, - "execution_count": 34, + "execution_count": 53, "metadata": {}, "output_type": "execute_result" } @@ -1115,7 +1115,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 54, "id": "31b0143c", "metadata": {}, "outputs": [ @@ -1125,7 +1125,7 @@ "9.395259956013202e-05" ] }, - "execution_count": 35, + "execution_count": 54, "metadata": {}, "output_type": "execute_result" } @@ -1144,7 +1144,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 55, "id": "7cfba34a", "metadata": {}, "outputs": [ @@ -1152,8 +1152,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "CPU times: user 2.84 ms, sys: 19 μs, total: 2.86 ms\n", - "Wall time: 2.86 ms\n" + "CPU times: user 10 ms, sys: 113 μs, total: 10.1 ms\n", + "Wall time: 10.2 ms\n" ] }, { @@ -1162,7 +1162,7 @@ "NashComputationResult(method='logit', rational=False, use_strategic=False, equilibria=[[[[1.0, 0.0], [0.3338351656285655, 0.666164834417892]], [[0.6670407651644307, 0.3329592348608147]]]], parameters={'first_step': 0.03, 'max_accel': 1.1})" ] }, - "execution_count": 36, + "execution_count": 55, "metadata": {}, "output_type": "execute_result" } @@ -1174,7 +1174,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 56, "id": "6f1809a7", "metadata": {}, "outputs": [ @@ -1182,8 +1182,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "CPU times: user 5.51 ms, sys: 72 μs, total: 5.58 ms\n", - "Wall time: 5.59 ms\n" + "CPU times: user 20.2 ms, sys: 430 μs, total: 20.6 ms\n", + "Wall time: 21.7 ms\n" ] }, { @@ -1192,7 +1192,7 @@ "NashComputationResult(method='logit', rational=False, use_strategic=False, equilibria=[[[[1.0, 0.0], [0.33333338649882943, 0.6666666135011706]], [[0.6666667065407631, 0.3333332934592369]]]], parameters={'first_step': 0.03, 'max_accel': 1.1})" ] }, - "execution_count": 37, + "execution_count": 56, "metadata": {}, "output_type": "execute_result" } @@ -1214,17 +1214,17 @@ }, { "cell_type": "code", - "execution_count": 38, + "execution_count": 57, "id": "414b6f65", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "5.5099518433632255e-05" + "5.509533871672634e-05" ] }, - "execution_count": 38, + "execution_count": 57, "metadata": {}, "output_type": "execute_result" } @@ -1246,17 +1246,17 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 58, "id": "a892dc2b", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "5.5099518433632255e-05" + "5.509533871672634e-05" ] }, - "execution_count": 39, + "execution_count": 58, "metadata": {}, "output_type": "execute_result" } @@ -1287,7 +1287,7 @@ }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 59, "id": "2f79695a", "metadata": {}, "outputs": [ @@ -1297,7 +1297,7 @@ "[Rational(1, 3), Rational(1, 3), Rational(1, 3)]" ] }, - "execution_count": 40, + "execution_count": 59, "metadata": {}, "output_type": "execute_result" } @@ -1321,7 +1321,7 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 60, "id": "5de6acb2", "metadata": {}, "outputs": [ @@ -1331,7 +1331,7 @@ "[Rational(1, 4), Rational(1, 2), Rational(1, 4)]" ] }, - "execution_count": 41, + "execution_count": 60, "metadata": {}, "output_type": "execute_result" } @@ -1354,7 +1354,7 @@ }, { "cell_type": "code", - "execution_count": 42, + "execution_count": 61, "id": "c47d2ab6", "metadata": {}, "outputs": [ @@ -1364,7 +1364,7 @@ "[Decimal('0.25'), Decimal('0.50'), Decimal('0.25')]" ] }, - "execution_count": 42, + "execution_count": 61, "metadata": {}, "output_type": "execute_result" } @@ -1391,7 +1391,7 @@ }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 62, "id": "04329084", "metadata": {}, "outputs": [ @@ -1401,7 +1401,7 @@ "[Rational(1, 4), Rational(1, 2), Rational(1, 4)]" ] }, - "execution_count": 43, + "execution_count": 62, "metadata": {}, "output_type": "execute_result" } @@ -1413,7 +1413,7 @@ }, { "cell_type": "code", - "execution_count": 44, + "execution_count": 63, "id": "9015e129", "metadata": {}, "outputs": [ @@ -1423,7 +1423,7 @@ "[Decimal('0.25'), Decimal('0.50'), Decimal('0.25')]" ] }, - "execution_count": 44, + "execution_count": 63, "metadata": {}, "output_type": "execute_result" } @@ -1448,7 +1448,7 @@ }, { "cell_type": "code", - "execution_count": 45, + "execution_count": 64, "id": "0a019aa5", "metadata": {}, "outputs": [ @@ -1458,7 +1458,7 @@ "[Decimal('0.25'), Decimal('0.5'), Decimal('0.25')]" ] }, - "execution_count": 45, + "execution_count": 64, "metadata": {}, "output_type": "execute_result" } @@ -1478,7 +1478,7 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 65, "id": "1991d288", "metadata": {}, "outputs": [ @@ -1508,7 +1508,7 @@ }, { "cell_type": "code", - "execution_count": 47, + "execution_count": 66, "id": "b1dc37fd", "metadata": {}, "outputs": [ @@ -1518,7 +1518,7 @@ "1.0" ] }, - "execution_count": 47, + "execution_count": 66, "metadata": {}, "output_type": "execute_result" } @@ -1537,7 +1537,7 @@ }, { "cell_type": "code", - "execution_count": 48, + "execution_count": 67, "id": "dc1edea2", "metadata": {}, "outputs": [ @@ -1547,7 +1547,7 @@ "Decimal('0.3333333333333333')" ] }, - "execution_count": 48, + "execution_count": 67, "metadata": {}, "output_type": "execute_result" } @@ -1566,7 +1566,7 @@ }, { "cell_type": "code", - "execution_count": 49, + "execution_count": 68, "id": "1edd90d6", "metadata": {}, "outputs": [ @@ -1576,7 +1576,7 @@ "Decimal('0.9999999999999999')" ] }, - "execution_count": 49, + "execution_count": 68, "metadata": {}, "output_type": "execute_result" } From ecfb153a41f6a8469dc79b3a0a94f8f47c3d5265 Mon Sep 17 00:00:00 2001 From: Ed Chalstrey Date: Tue, 18 Nov 2025 15:41:31 +0000 Subject: [PATCH 07/17] rename to stripped-down poker --- doc/tutorials/{03_poker.ipynb => 03_stripped_down_poker.ipynb} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename doc/tutorials/{03_poker.ipynb => 03_stripped_down_poker.ipynb} (99%) diff --git a/doc/tutorials/03_poker.ipynb b/doc/tutorials/03_stripped_down_poker.ipynb similarity index 99% rename from doc/tutorials/03_poker.ipynb rename to doc/tutorials/03_stripped_down_poker.ipynb index ec401eccc..d7b8d4c70 100644 --- a/doc/tutorials/03_poker.ipynb +++ b/doc/tutorials/03_stripped_down_poker.ipynb @@ -5,7 +5,7 @@ "id": "98eb65d8", "metadata": {}, "source": [ - "# 3) A one-card poker game with private information\n", + "# 3) Stripped-down poker\n", "\n", "In this tutorial, we'll create an extensive form representation of a one-card poker game [[Mye91](#references)] and use it to demonstrate and explain the following with Gambit:\n", "\n", From 5aa3450e7c490b47a123a5fdd967a83812767af1 Mon Sep 17 00:00:00 2001 From: Ed Chalstrey Date: Tue, 18 Nov 2025 15:46:59 +0000 Subject: [PATCH 08/17] update references --- doc/tutorials/03_stripped_down_poker.ipynb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/tutorials/03_stripped_down_poker.ipynb b/doc/tutorials/03_stripped_down_poker.ipynb index d7b8d4c70..0de9a0e7a 100644 --- a/doc/tutorials/03_stripped_down_poker.ipynb +++ b/doc/tutorials/03_stripped_down_poker.ipynb @@ -7,14 +7,16 @@ "source": [ "# 3) Stripped-down poker\n", "\n", - "In this tutorial, we'll create an extensive form representation of a one-card poker game [[Mye91](#references)] and use it to demonstrate and explain the following with Gambit:\n", + "In this tutorial, we'll create an extensive form representation of a one-card poker game from [Reiley et al (2008)](#references), a classroom game under the name \"stripped-down poker\".\n", + "This is perhaps the simplest interesting game with imperfect information.\n", + "\n", + "We'll use \"stripped-down poker\" to demonstrate and explain the following with Gambit:\n", "\n", "1. Setting up an extensive form game with imperfect information using [information sets](#information-sets)\n", "2. [Computing and interpreting Nash equilibria](#computing-and-interpreting-nash-equilibria) and understanding mixed behaviour and mixed strategy profiles\n", "3. [Acceptance criteria for Nash equilibria](#acceptance-criteria-for-nash-equilibria)\n", "\n", - "A version of this game also appears in [[RUW08](#references)], as a classroom game under the name \"stripped-down poker\".\n", - "This is perhaps the simplest interesting game with imperfect information.\n", + "A version of this game \n", "\n", "In our version of the game, there are two players, **Alice** and **Bob**, and a deck of cards, with equal numbers of **King** and **Queen** cards.\n", "\n", @@ -1604,8 +1606,6 @@ "source": [ "#### References\n", "\n", - "Myerson, Roger B. (1991) *Game Theory: Analysis of Conflict*. Cambridge: Harvard University Press.\n", - "\n", "Reiley, David H., Michael B. Urbancic and Mark Walker. (2008) \"Stripped-down poker: A classroom game with signaling and bluffing.\" *The Journal of Economic Education* 39(4): 323-341." ] } From d040af98a8e02bafda85b2a7488210991f6dec28 Mon Sep 17 00:00:00 2001 From: Ed Chalstrey Date: Tue, 18 Nov 2025 15:54:41 +0000 Subject: [PATCH 09/17] match outcome labels to test game --- doc/tutorials/03_stripped_down_poker.ipynb | 192 ++++++++++----------- 1 file changed, 96 insertions(+), 96 deletions(-) diff --git a/doc/tutorials/03_stripped_down_poker.ipynb b/doc/tutorials/03_stripped_down_poker.ipynb index 0de9a0e7a..674fb8b95 100644 --- a/doc/tutorials/03_stripped_down_poker.ipynb +++ b/doc/tutorials/03_stripped_down_poker.ipynb @@ -37,7 +37,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 1, "id": "69cbfe81", "metadata": {}, "outputs": [], @@ -55,7 +55,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 2, "id": "ad6a1119", "metadata": {}, "outputs": [], @@ -76,7 +76,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 3, "id": "841f9f74", "metadata": {}, "outputs": [ @@ -112,7 +112,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 4, "id": "fe80c64c", "metadata": {}, "outputs": [], @@ -140,7 +140,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 5, "id": "0e3bb5ef", "metadata": {}, "outputs": [], @@ -174,7 +174,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 6, "id": "dbfa7035", "metadata": {}, "outputs": [], @@ -196,7 +196,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 7, "id": "655cdae3", "metadata": {}, "outputs": [], @@ -217,20 +217,20 @@ "\n", "This is crucial in games where players must make decisions without complete knowledge of their opponents' private information.\n", "\n", - "Let's now set up the four possible payoff outcomes for the game." + "Let's now set up the four possible payoff outcomes for the game. We'll label them according to player 1 (Alice)." ] }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 8, "id": "87c988be", "metadata": {}, "outputs": [], "source": [ - "alice_winsbig = g.add_outcome([2, -2], label=\"Alice wins big\")\n", - "alice_wins = g.add_outcome([1, -1], label=\"Alice wins\")\n", - "bob_winsbig = g.add_outcome([-2, 2], label=\"Bob wins big\")\n", - "bob_wins = g.add_outcome([-1, 1], label=\"Bob wins\")" + "win_big = g.add_outcome([2, -2], label=\"Win Big\")\n", + "win = g.add_outcome([1, -1], label=\"Win\")\n", + "lose_big = g.add_outcome([-2, 2], label=\"Lose Big\")\n", + "lose = g.add_outcome([-1, 1], label=\"Lose\")" ] }, { @@ -243,24 +243,24 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 9, "id": "29aa60a0", "metadata": {}, "outputs": [], "source": [ "# Alice folds, Bob wins small\n", - "g.set_outcome(g.root.children[\"King\"].children[\"Fold\"], bob_wins)\n", - "g.set_outcome(g.root.children[\"Queen\"].children[\"Fold\"], bob_wins)\n", + "g.set_outcome(g.root.children[\"King\"].children[\"Fold\"], lose)\n", + "g.set_outcome(g.root.children[\"Queen\"].children[\"Fold\"], lose)\n", "\n", "# Bob sees Alice Bet and calls, correctly believing she is bluffing, Bob wins big\n", - "g.set_outcome(g.root.children[\"Queen\"].children[\"Bet\"].children[\"Call\"], bob_winsbig)\n", + "g.set_outcome(g.root.children[\"Queen\"].children[\"Bet\"].children[\"Call\"], lose_big)\n", "\n", "# Bob sees Alice Bet and calls, incorrectly believing she is bluffing, Alice wins big\n", - "g.set_outcome(g.root.children[\"King\"].children[\"Bet\"].children[\"Call\"], alice_winsbig)\n", + "g.set_outcome(g.root.children[\"King\"].children[\"Bet\"].children[\"Call\"], win_big)\n", "\n", "# Bob does not call Alice's Bet, Alice wins small\n", - "g.set_outcome(g.root.children[\"King\"].children[\"Bet\"].children[\"Fold\"], alice_wins)\n", - "g.set_outcome(g.root.children[\"Queen\"].children[\"Bet\"].children[\"Fold\"], alice_wins)" + "g.set_outcome(g.root.children[\"King\"].children[\"Bet\"].children[\"Fold\"], win)\n", + "g.set_outcome(g.root.children[\"Queen\"].children[\"Bet\"].children[\"Fold\"], win)" ] }, { @@ -276,7 +276,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 10, "id": "4d92c8d9", "metadata": {}, "outputs": [ @@ -286,7 +286,7 @@ "NashComputationResult(method='lcp', rational=True, use_strategic=False, equilibria=[[[[Rational(1, 1), Rational(0, 1)], [Rational(1, 3), Rational(2, 3)]], [[Rational(2, 3), Rational(1, 3)]]]], parameters={'stop_after': 0, 'max_depth': 0})" ] }, - "execution_count": 29, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -310,7 +310,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 11, "id": "9967d6f7", "metadata": {}, "outputs": [ @@ -329,7 +329,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 12, "id": "3293e818", "metadata": {}, "outputs": [ @@ -339,7 +339,7 @@ "pygambit.gambit.MixedBehaviorProfileRational" ] }, - "execution_count": 31, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -362,7 +362,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 13, "id": "4cf38264", "metadata": {}, "outputs": [ @@ -372,7 +372,7 @@ "pygambit.gambit.MixedBehavior" ] }, - "execution_count": 32, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } @@ -383,7 +383,7 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 14, "id": "85e7fdda", "metadata": {}, "outputs": [ @@ -396,7 +396,7 @@ "[[Rational(1, 1), Rational(0, 1)], [Rational(1, 3), Rational(2, 3)]]" ] }, - "execution_count": 33, + "execution_count": 14, "metadata": {}, "output_type": "execute_result" } @@ -421,7 +421,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 15, "id": "f45a82b6", "metadata": {}, "outputs": [ @@ -453,7 +453,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 16, "id": "83bbd3e5", "metadata": {}, "outputs": [ @@ -486,7 +486,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 17, "id": "6bf51b38", "metadata": {}, "outputs": [ @@ -499,7 +499,7 @@ "[[Rational(2, 3), Rational(1, 3)]]" ] }, - "execution_count": 36, + "execution_count": 17, "metadata": {}, "output_type": "execute_result" } @@ -522,7 +522,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 18, "id": "2966e700", "metadata": {}, "outputs": [ @@ -535,7 +535,7 @@ "Rational(2, 3)" ] }, - "execution_count": 37, + "execution_count": 18, "metadata": {}, "output_type": "execute_result" } @@ -554,7 +554,7 @@ }, { "cell_type": "code", - "execution_count": 38, + "execution_count": 19, "id": "f5a7f110", "metadata": {}, "outputs": [ @@ -567,7 +567,7 @@ "Rational(2, 3)" ] }, - "execution_count": 38, + "execution_count": 19, "metadata": {}, "output_type": "execute_result" } @@ -588,7 +588,7 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 20, "id": "a7d3816d", "metadata": {}, "outputs": [ @@ -623,7 +623,7 @@ }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 21, "id": "4a54b20c", "metadata": {}, "outputs": [ @@ -656,7 +656,7 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 22, "id": "b250c1cd", "metadata": {}, "outputs": [ @@ -669,7 +669,7 @@ "Rational(2, 3)" ] }, - "execution_count": 41, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" } @@ -688,7 +688,7 @@ }, { "cell_type": "code", - "execution_count": 42, + "execution_count": 23, "id": "6f01846b", "metadata": {}, "outputs": [ @@ -720,7 +720,7 @@ }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 24, "id": "5079d231", "metadata": {}, "outputs": [ @@ -733,7 +733,7 @@ "Rational(1, 3)" ] }, - "execution_count": 43, + "execution_count": 24, "metadata": {}, "output_type": "execute_result" } @@ -744,7 +744,7 @@ }, { "cell_type": "code", - "execution_count": 44, + "execution_count": 25, "id": "c55f2c7a", "metadata": {}, "outputs": [ @@ -757,7 +757,7 @@ "Rational(-1, 3)" ] }, - "execution_count": 44, + "execution_count": 25, "metadata": {}, "output_type": "execute_result" } @@ -784,7 +784,7 @@ }, { "cell_type": "code", - "execution_count": 45, + "execution_count": 26, "id": "d4ecff88", "metadata": {}, "outputs": [ @@ -794,7 +794,7 @@ "['11', '12', '21', '22']" ] }, - "execution_count": 45, + "execution_count": 26, "metadata": {}, "output_type": "execute_result" } @@ -818,7 +818,7 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 27, "id": "24e4b6e8", "metadata": {}, "outputs": [ @@ -828,7 +828,7 @@ "NashComputationResult(method='gnm', rational=False, use_strategic=True, equilibria=[[[0.33333333333866677, 0.6666666666613335, 0.0, 0.0], [0.6666666666559997, 0.3333333333440004]]], parameters={'perturbation': [[1.0, 0.0, 0.0, 0.0], [1.0, 0.0]], 'end_lambda': -10.0, 'steps': 100, 'local_newton_interval': 3, 'local_newton_maxits': 10})" ] }, - "execution_count": 46, + "execution_count": 27, "metadata": {}, "output_type": "execute_result" } @@ -850,7 +850,7 @@ }, { "cell_type": "code", - "execution_count": 47, + "execution_count": 28, "id": "d9ffb4b8", "metadata": {}, "outputs": [ @@ -860,7 +860,7 @@ "pygambit.gambit.MixedStrategyProfileDouble" ] }, - "execution_count": 47, + "execution_count": 28, "metadata": {}, "output_type": "execute_result" } @@ -882,7 +882,7 @@ }, { "cell_type": "code", - "execution_count": 48, + "execution_count": 29, "id": "56e2f847", "metadata": {}, "outputs": [ @@ -935,7 +935,7 @@ }, { "cell_type": "code", - "execution_count": 49, + "execution_count": 30, "id": "d18a91f0", "metadata": {}, "outputs": [ @@ -1001,7 +1001,7 @@ }, { "cell_type": "code", - "execution_count": 50, + "execution_count": 31, "id": "0c55f745", "metadata": {}, "outputs": [ @@ -1011,7 +1011,7 @@ "(Rational(2, 1), Rational(-2, 1))" ] }, - "execution_count": 50, + "execution_count": 31, "metadata": {}, "output_type": "execute_result" } @@ -1033,7 +1033,7 @@ }, { "cell_type": "code", - "execution_count": 51, + "execution_count": 32, "id": "101598c6", "metadata": {}, "outputs": [ @@ -1043,7 +1043,7 @@ "1" ] }, - "execution_count": 51, + "execution_count": 32, "metadata": {}, "output_type": "execute_result" } @@ -1055,7 +1055,7 @@ }, { "cell_type": "code", - "execution_count": 52, + "execution_count": 33, "id": "9b142728", "metadata": {}, "outputs": [ @@ -1065,7 +1065,7 @@ "3.987411578698641e-08" ] }, - "execution_count": 52, + "execution_count": 33, "metadata": {}, "output_type": "execute_result" } @@ -1086,7 +1086,7 @@ }, { "cell_type": "code", - "execution_count": 53, + "execution_count": 34, "id": "ff405409", "metadata": {}, "outputs": [ @@ -1096,7 +1096,7 @@ "9.968528946746602e-09" ] }, - "execution_count": 53, + "execution_count": 34, "metadata": {}, "output_type": "execute_result" } @@ -1117,7 +1117,7 @@ }, { "cell_type": "code", - "execution_count": 54, + "execution_count": 35, "id": "31b0143c", "metadata": {}, "outputs": [ @@ -1127,7 +1127,7 @@ "9.395259956013202e-05" ] }, - "execution_count": 54, + "execution_count": 35, "metadata": {}, "output_type": "execute_result" } @@ -1146,7 +1146,7 @@ }, { "cell_type": "code", - "execution_count": 55, + "execution_count": 36, "id": "7cfba34a", "metadata": {}, "outputs": [ @@ -1154,8 +1154,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "CPU times: user 10 ms, sys: 113 μs, total: 10.1 ms\n", - "Wall time: 10.2 ms\n" + "CPU times: user 9.81 ms, sys: 49 μs, total: 9.86 ms\n", + "Wall time: 9.89 ms\n" ] }, { @@ -1164,7 +1164,7 @@ "NashComputationResult(method='logit', rational=False, use_strategic=False, equilibria=[[[[1.0, 0.0], [0.3338351656285655, 0.666164834417892]], [[0.6670407651644307, 0.3329592348608147]]]], parameters={'first_step': 0.03, 'max_accel': 1.1})" ] }, - "execution_count": 55, + "execution_count": 36, "metadata": {}, "output_type": "execute_result" } @@ -1176,7 +1176,7 @@ }, { "cell_type": "code", - "execution_count": 56, + "execution_count": 37, "id": "6f1809a7", "metadata": {}, "outputs": [ @@ -1184,8 +1184,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "CPU times: user 20.2 ms, sys: 430 μs, total: 20.6 ms\n", - "Wall time: 21.7 ms\n" + "CPU times: user 18.9 ms, sys: 205 μs, total: 19.1 ms\n", + "Wall time: 19.2 ms\n" ] }, { @@ -1194,7 +1194,7 @@ "NashComputationResult(method='logit', rational=False, use_strategic=False, equilibria=[[[[1.0, 0.0], [0.33333338649882943, 0.6666666135011706]], [[0.6666667065407631, 0.3333332934592369]]]], parameters={'first_step': 0.03, 'max_accel': 1.1})" ] }, - "execution_count": 56, + "execution_count": 37, "metadata": {}, "output_type": "execute_result" } @@ -1216,7 +1216,7 @@ }, { "cell_type": "code", - "execution_count": 57, + "execution_count": 38, "id": "414b6f65", "metadata": {}, "outputs": [ @@ -1226,7 +1226,7 @@ "5.509533871672634e-05" ] }, - "execution_count": 57, + "execution_count": 38, "metadata": {}, "output_type": "execute_result" } @@ -1248,7 +1248,7 @@ }, { "cell_type": "code", - "execution_count": 58, + "execution_count": 39, "id": "a892dc2b", "metadata": {}, "outputs": [ @@ -1258,7 +1258,7 @@ "5.509533871672634e-05" ] }, - "execution_count": 58, + "execution_count": 39, "metadata": {}, "output_type": "execute_result" } @@ -1289,7 +1289,7 @@ }, { "cell_type": "code", - "execution_count": 59, + "execution_count": 40, "id": "2f79695a", "metadata": {}, "outputs": [ @@ -1299,7 +1299,7 @@ "[Rational(1, 3), Rational(1, 3), Rational(1, 3)]" ] }, - "execution_count": 59, + "execution_count": 40, "metadata": {}, "output_type": "execute_result" } @@ -1323,7 +1323,7 @@ }, { "cell_type": "code", - "execution_count": 60, + "execution_count": 41, "id": "5de6acb2", "metadata": {}, "outputs": [ @@ -1333,7 +1333,7 @@ "[Rational(1, 4), Rational(1, 2), Rational(1, 4)]" ] }, - "execution_count": 60, + "execution_count": 41, "metadata": {}, "output_type": "execute_result" } @@ -1356,7 +1356,7 @@ }, { "cell_type": "code", - "execution_count": 61, + "execution_count": 42, "id": "c47d2ab6", "metadata": {}, "outputs": [ @@ -1366,7 +1366,7 @@ "[Decimal('0.25'), Decimal('0.50'), Decimal('0.25')]" ] }, - "execution_count": 61, + "execution_count": 42, "metadata": {}, "output_type": "execute_result" } @@ -1393,7 +1393,7 @@ }, { "cell_type": "code", - "execution_count": 62, + "execution_count": 43, "id": "04329084", "metadata": {}, "outputs": [ @@ -1403,7 +1403,7 @@ "[Rational(1, 4), Rational(1, 2), Rational(1, 4)]" ] }, - "execution_count": 62, + "execution_count": 43, "metadata": {}, "output_type": "execute_result" } @@ -1415,7 +1415,7 @@ }, { "cell_type": "code", - "execution_count": 63, + "execution_count": 44, "id": "9015e129", "metadata": {}, "outputs": [ @@ -1425,7 +1425,7 @@ "[Decimal('0.25'), Decimal('0.50'), Decimal('0.25')]" ] }, - "execution_count": 63, + "execution_count": 44, "metadata": {}, "output_type": "execute_result" } @@ -1450,7 +1450,7 @@ }, { "cell_type": "code", - "execution_count": 64, + "execution_count": 45, "id": "0a019aa5", "metadata": {}, "outputs": [ @@ -1460,7 +1460,7 @@ "[Decimal('0.25'), Decimal('0.5'), Decimal('0.25')]" ] }, - "execution_count": 64, + "execution_count": 45, "metadata": {}, "output_type": "execute_result" } @@ -1480,7 +1480,7 @@ }, { "cell_type": "code", - "execution_count": 65, + "execution_count": 46, "id": "1991d288", "metadata": {}, "outputs": [ @@ -1510,7 +1510,7 @@ }, { "cell_type": "code", - "execution_count": 66, + "execution_count": 47, "id": "b1dc37fd", "metadata": {}, "outputs": [ @@ -1520,7 +1520,7 @@ "1.0" ] }, - "execution_count": 66, + "execution_count": 47, "metadata": {}, "output_type": "execute_result" } @@ -1539,7 +1539,7 @@ }, { "cell_type": "code", - "execution_count": 67, + "execution_count": 48, "id": "dc1edea2", "metadata": {}, "outputs": [ @@ -1549,7 +1549,7 @@ "Decimal('0.3333333333333333')" ] }, - "execution_count": 67, + "execution_count": 48, "metadata": {}, "output_type": "execute_result" } @@ -1568,7 +1568,7 @@ }, { "cell_type": "code", - "execution_count": 68, + "execution_count": 49, "id": "1edd90d6", "metadata": {}, "outputs": [ @@ -1578,7 +1578,7 @@ "Decimal('0.9999999999999999')" ] }, - "execution_count": 68, + "execution_count": 49, "metadata": {}, "output_type": "execute_result" } @@ -1612,7 +1612,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "gambitvenv313", "language": "python", "name": "python3" }, From 3999934d4f6279c05a84d01dfa9a179ec120d2b8 Mon Sep 17 00:00:00 2001 From: Ed Chalstrey Date: Tue, 18 Nov 2025 15:56:20 +0000 Subject: [PATCH 10/17] add full stops --- doc/tutorials/03_stripped_down_poker.ipynb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/tutorials/03_stripped_down_poker.ipynb b/doc/tutorials/03_stripped_down_poker.ipynb index 674fb8b95..3eb70fe32 100644 --- a/doc/tutorials/03_stripped_down_poker.ipynb +++ b/doc/tutorials/03_stripped_down_poker.ipynb @@ -22,8 +22,8 @@ "\n", "- The game begins with each player putting \\$1 in the pot.\n", " - A card is dealt at random to Alice\n", - " - Alice observes her card\n", - " - Bob does not observe the card\n", + " - Alice observes her card.\n", + " - Bob does not observe the card.\n", "- Alice then chooses either to **Bet** or to **Fold**.\n", " - If she chooses to Fold, Bob wins the pot and the game ends.\n", " - If she chooses to Bet, she adds another \\$1 to the pot.\n", From 10f25bcd2a2677cc1443e7f6a9d2083be7cfb5c8 Mon Sep 17 00:00:00 2001 From: Ed Chalstrey Date: Tue, 18 Nov 2025 15:58:03 +0000 Subject: [PATCH 11/17] remove "Betd" typo --- doc/tutorials/03_stripped_down_poker.ipynb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/tutorials/03_stripped_down_poker.ipynb b/doc/tutorials/03_stripped_down_poker.ipynb index 3eb70fe32..c85df9028 100644 --- a/doc/tutorials/03_stripped_down_poker.ipynb +++ b/doc/tutorials/03_stripped_down_poker.ipynb @@ -169,7 +169,7 @@ "\n", "To set this scenario up in Gambit, we'll need to use `Game.append_infoset` to add a move as part of an existing information set (represented in Gambit as an `Infoset`).\n", "\n", - "First, let's add Bob's move to the node where Alice has Betd with a King." + "First, let's add Bob's move to the node where Alice has bet with a King." ] }, { @@ -191,7 +191,7 @@ "id": "689ce12c", "metadata": {}, "source": [ - "Now let's add the information set we created at the node where Alice Betd with a King, to the node where Alice Betd with a Queen." + "Now let's add the information set we created at the node where Alice bet with a King, to the node where Alice bet with a Queen." ] }, { From 1d9de388d6cbc732b6333a78ea9fcb7c4fddfdc4 Mon Sep 17 00:00:00 2001 From: Ed Chalstrey Date: Tue, 18 Nov 2025 16:05:49 +0000 Subject: [PATCH 12/17] add nodes to same infoset with passing a list of nodes to append_move --- doc/tutorials/03_stripped_down_poker.ipynb | 182 +++++++++------------ 1 file changed, 80 insertions(+), 102 deletions(-) diff --git a/doc/tutorials/03_stripped_down_poker.ipynb b/doc/tutorials/03_stripped_down_poker.ipynb index c85df9028..450d13fdf 100644 --- a/doc/tutorials/03_stripped_down_poker.ipynb +++ b/doc/tutorials/03_stripped_down_poker.ipynb @@ -167,9 +167,8 @@ "\n", "In other words, Bob's decision when Alice Bets with a Queen should be part of the same information set as Bob's decision when Alice Bets with a King.\n", "\n", - "To set this scenario up in Gambit, we'll need to use `Game.append_infoset` to add a move as part of an existing information set (represented in Gambit as an `Infoset`).\n", - "\n", - "First, let's add Bob's move to the node where Alice has bet with a King." + "To set this scenario up in Gambit, we'll need to use add both possible moves as part of the same information set (represented in Gambit as an `Infoset`).\n", + "This can be done by passing a list of nodes to the `append_move` method." ] }, { @@ -180,33 +179,12 @@ "outputs": [], "source": [ "g.append_move(\n", - " g.root.children[\"King\"].children[\"Bet\"],\n", + " [g.root.children[\"King\"].children[\"Bet\"], g.root.children[\"Queen\"].children[\"Bet\"]],\n", " player=\"Bob\",\n", " actions=[\"Call\", \"Fold\"]\n", ")" ] }, - { - "cell_type": "markdown", - "id": "689ce12c", - "metadata": {}, - "source": [ - "Now let's add the information set we created at the node where Alice bet with a King, to the node where Alice bet with a Queen." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "655cdae3", - "metadata": {}, - "outputs": [], - "source": [ - "g.append_infoset(\n", - " g.root.children[\"Queen\"].children[\"Bet\"],\n", - " infoset=g.root.children[\"King\"].children[\"Bet\"].infoset\n", - ")" - ] - }, { "cell_type": "markdown", "id": "c4eeb65f", @@ -222,7 +200,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 7, "id": "87c988be", "metadata": {}, "outputs": [], @@ -243,7 +221,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 8, "id": "29aa60a0", "metadata": {}, "outputs": [], @@ -276,7 +254,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 9, "id": "4d92c8d9", "metadata": {}, "outputs": [ @@ -286,7 +264,7 @@ "NashComputationResult(method='lcp', rational=True, use_strategic=False, equilibria=[[[[Rational(1, 1), Rational(0, 1)], [Rational(1, 3), Rational(2, 3)]], [[Rational(2, 3), Rational(1, 3)]]]], parameters={'stop_after': 0, 'max_depth': 0})" ] }, - "execution_count": 10, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -310,7 +288,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 10, "id": "9967d6f7", "metadata": {}, "outputs": [ @@ -329,7 +307,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 11, "id": "3293e818", "metadata": {}, "outputs": [ @@ -339,7 +317,7 @@ "pygambit.gambit.MixedBehaviorProfileRational" ] }, - "execution_count": 12, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -362,7 +340,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 12, "id": "4cf38264", "metadata": {}, "outputs": [ @@ -372,7 +350,7 @@ "pygambit.gambit.MixedBehavior" ] }, - "execution_count": 13, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -383,7 +361,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 13, "id": "85e7fdda", "metadata": {}, "outputs": [ @@ -396,7 +374,7 @@ "[[Rational(1, 1), Rational(0, 1)], [Rational(1, 3), Rational(2, 3)]]" ] }, - "execution_count": 14, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } @@ -421,7 +399,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 14, "id": "f45a82b6", "metadata": {}, "outputs": [ @@ -453,7 +431,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 15, "id": "83bbd3e5", "metadata": {}, "outputs": [ @@ -486,7 +464,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 16, "id": "6bf51b38", "metadata": {}, "outputs": [ @@ -499,7 +477,7 @@ "[[Rational(2, 3), Rational(1, 3)]]" ] }, - "execution_count": 17, + "execution_count": 16, "metadata": {}, "output_type": "execute_result" } @@ -522,7 +500,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 17, "id": "2966e700", "metadata": {}, "outputs": [ @@ -535,7 +513,7 @@ "Rational(2, 3)" ] }, - "execution_count": 18, + "execution_count": 17, "metadata": {}, "output_type": "execute_result" } @@ -554,7 +532,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 18, "id": "f5a7f110", "metadata": {}, "outputs": [ @@ -567,7 +545,7 @@ "Rational(2, 3)" ] }, - "execution_count": 19, + "execution_count": 18, "metadata": {}, "output_type": "execute_result" } @@ -588,7 +566,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 19, "id": "a7d3816d", "metadata": {}, "outputs": [ @@ -623,7 +601,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 20, "id": "4a54b20c", "metadata": {}, "outputs": [ @@ -656,7 +634,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 21, "id": "b250c1cd", "metadata": {}, "outputs": [ @@ -669,7 +647,7 @@ "Rational(2, 3)" ] }, - "execution_count": 22, + "execution_count": 21, "metadata": {}, "output_type": "execute_result" } @@ -688,7 +666,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 22, "id": "6f01846b", "metadata": {}, "outputs": [ @@ -720,7 +698,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 23, "id": "5079d231", "metadata": {}, "outputs": [ @@ -733,7 +711,7 @@ "Rational(1, 3)" ] }, - "execution_count": 24, + "execution_count": 23, "metadata": {}, "output_type": "execute_result" } @@ -744,7 +722,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 24, "id": "c55f2c7a", "metadata": {}, "outputs": [ @@ -757,7 +735,7 @@ "Rational(-1, 3)" ] }, - "execution_count": 25, + "execution_count": 24, "metadata": {}, "output_type": "execute_result" } @@ -784,7 +762,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 25, "id": "d4ecff88", "metadata": {}, "outputs": [ @@ -794,7 +772,7 @@ "['11', '12', '21', '22']" ] }, - "execution_count": 26, + "execution_count": 25, "metadata": {}, "output_type": "execute_result" } @@ -818,7 +796,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 26, "id": "24e4b6e8", "metadata": {}, "outputs": [ @@ -828,7 +806,7 @@ "NashComputationResult(method='gnm', rational=False, use_strategic=True, equilibria=[[[0.33333333333866677, 0.6666666666613335, 0.0, 0.0], [0.6666666666559997, 0.3333333333440004]]], parameters={'perturbation': [[1.0, 0.0, 0.0, 0.0], [1.0, 0.0]], 'end_lambda': -10.0, 'steps': 100, 'local_newton_interval': 3, 'local_newton_maxits': 10})" ] }, - "execution_count": 27, + "execution_count": 26, "metadata": {}, "output_type": "execute_result" } @@ -850,7 +828,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 27, "id": "d9ffb4b8", "metadata": {}, "outputs": [ @@ -860,7 +838,7 @@ "pygambit.gambit.MixedStrategyProfileDouble" ] }, - "execution_count": 28, + "execution_count": 27, "metadata": {}, "output_type": "execute_result" } @@ -882,7 +860,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 28, "id": "56e2f847", "metadata": {}, "outputs": [ @@ -935,7 +913,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 29, "id": "d18a91f0", "metadata": {}, "outputs": [ @@ -1001,7 +979,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 30, "id": "0c55f745", "metadata": {}, "outputs": [ @@ -1011,7 +989,7 @@ "(Rational(2, 1), Rational(-2, 1))" ] }, - "execution_count": 31, + "execution_count": 30, "metadata": {}, "output_type": "execute_result" } @@ -1033,7 +1011,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 31, "id": "101598c6", "metadata": {}, "outputs": [ @@ -1043,7 +1021,7 @@ "1" ] }, - "execution_count": 32, + "execution_count": 31, "metadata": {}, "output_type": "execute_result" } @@ -1055,7 +1033,7 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 32, "id": "9b142728", "metadata": {}, "outputs": [ @@ -1065,7 +1043,7 @@ "3.987411578698641e-08" ] }, - "execution_count": 33, + "execution_count": 32, "metadata": {}, "output_type": "execute_result" } @@ -1086,7 +1064,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 33, "id": "ff405409", "metadata": {}, "outputs": [ @@ -1096,7 +1074,7 @@ "9.968528946746602e-09" ] }, - "execution_count": 34, + "execution_count": 33, "metadata": {}, "output_type": "execute_result" } @@ -1117,7 +1095,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 34, "id": "31b0143c", "metadata": {}, "outputs": [ @@ -1127,7 +1105,7 @@ "9.395259956013202e-05" ] }, - "execution_count": 35, + "execution_count": 34, "metadata": {}, "output_type": "execute_result" } @@ -1146,7 +1124,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 35, "id": "7cfba34a", "metadata": {}, "outputs": [ @@ -1154,8 +1132,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "CPU times: user 9.81 ms, sys: 49 μs, total: 9.86 ms\n", - "Wall time: 9.89 ms\n" + "CPU times: user 9.9 ms, sys: 230 μs, total: 10.1 ms\n", + "Wall time: 10.1 ms\n" ] }, { @@ -1164,7 +1142,7 @@ "NashComputationResult(method='logit', rational=False, use_strategic=False, equilibria=[[[[1.0, 0.0], [0.3338351656285655, 0.666164834417892]], [[0.6670407651644307, 0.3329592348608147]]]], parameters={'first_step': 0.03, 'max_accel': 1.1})" ] }, - "execution_count": 36, + "execution_count": 35, "metadata": {}, "output_type": "execute_result" } @@ -1176,7 +1154,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 36, "id": "6f1809a7", "metadata": {}, "outputs": [ @@ -1184,8 +1162,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "CPU times: user 18.9 ms, sys: 205 μs, total: 19.1 ms\n", - "Wall time: 19.2 ms\n" + "CPU times: user 18.4 ms, sys: 210 μs, total: 18.6 ms\n", + "Wall time: 18.6 ms\n" ] }, { @@ -1194,7 +1172,7 @@ "NashComputationResult(method='logit', rational=False, use_strategic=False, equilibria=[[[[1.0, 0.0], [0.33333338649882943, 0.6666666135011706]], [[0.6666667065407631, 0.3333332934592369]]]], parameters={'first_step': 0.03, 'max_accel': 1.1})" ] }, - "execution_count": 37, + "execution_count": 36, "metadata": {}, "output_type": "execute_result" } @@ -1216,7 +1194,7 @@ }, { "cell_type": "code", - "execution_count": 38, + "execution_count": 37, "id": "414b6f65", "metadata": {}, "outputs": [ @@ -1226,7 +1204,7 @@ "5.509533871672634e-05" ] }, - "execution_count": 38, + "execution_count": 37, "metadata": {}, "output_type": "execute_result" } @@ -1248,7 +1226,7 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 38, "id": "a892dc2b", "metadata": {}, "outputs": [ @@ -1258,7 +1236,7 @@ "5.509533871672634e-05" ] }, - "execution_count": 39, + "execution_count": 38, "metadata": {}, "output_type": "execute_result" } @@ -1289,7 +1267,7 @@ }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 39, "id": "2f79695a", "metadata": {}, "outputs": [ @@ -1299,7 +1277,7 @@ "[Rational(1, 3), Rational(1, 3), Rational(1, 3)]" ] }, - "execution_count": 40, + "execution_count": 39, "metadata": {}, "output_type": "execute_result" } @@ -1323,7 +1301,7 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 40, "id": "5de6acb2", "metadata": {}, "outputs": [ @@ -1333,7 +1311,7 @@ "[Rational(1, 4), Rational(1, 2), Rational(1, 4)]" ] }, - "execution_count": 41, + "execution_count": 40, "metadata": {}, "output_type": "execute_result" } @@ -1356,7 +1334,7 @@ }, { "cell_type": "code", - "execution_count": 42, + "execution_count": 41, "id": "c47d2ab6", "metadata": {}, "outputs": [ @@ -1366,7 +1344,7 @@ "[Decimal('0.25'), Decimal('0.50'), Decimal('0.25')]" ] }, - "execution_count": 42, + "execution_count": 41, "metadata": {}, "output_type": "execute_result" } @@ -1393,7 +1371,7 @@ }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 42, "id": "04329084", "metadata": {}, "outputs": [ @@ -1403,7 +1381,7 @@ "[Rational(1, 4), Rational(1, 2), Rational(1, 4)]" ] }, - "execution_count": 43, + "execution_count": 42, "metadata": {}, "output_type": "execute_result" } @@ -1415,7 +1393,7 @@ }, { "cell_type": "code", - "execution_count": 44, + "execution_count": 43, "id": "9015e129", "metadata": {}, "outputs": [ @@ -1425,7 +1403,7 @@ "[Decimal('0.25'), Decimal('0.50'), Decimal('0.25')]" ] }, - "execution_count": 44, + "execution_count": 43, "metadata": {}, "output_type": "execute_result" } @@ -1450,7 +1428,7 @@ }, { "cell_type": "code", - "execution_count": 45, + "execution_count": 44, "id": "0a019aa5", "metadata": {}, "outputs": [ @@ -1460,7 +1438,7 @@ "[Decimal('0.25'), Decimal('0.5'), Decimal('0.25')]" ] }, - "execution_count": 45, + "execution_count": 44, "metadata": {}, "output_type": "execute_result" } @@ -1480,7 +1458,7 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 45, "id": "1991d288", "metadata": {}, "outputs": [ @@ -1510,7 +1488,7 @@ }, { "cell_type": "code", - "execution_count": 47, + "execution_count": 46, "id": "b1dc37fd", "metadata": {}, "outputs": [ @@ -1520,7 +1498,7 @@ "1.0" ] }, - "execution_count": 47, + "execution_count": 46, "metadata": {}, "output_type": "execute_result" } @@ -1539,7 +1517,7 @@ }, { "cell_type": "code", - "execution_count": 48, + "execution_count": 47, "id": "dc1edea2", "metadata": {}, "outputs": [ @@ -1549,7 +1527,7 @@ "Decimal('0.3333333333333333')" ] }, - "execution_count": 48, + "execution_count": 47, "metadata": {}, "output_type": "execute_result" } @@ -1568,7 +1546,7 @@ }, { "cell_type": "code", - "execution_count": 49, + "execution_count": 48, "id": "1edd90d6", "metadata": {}, "outputs": [ @@ -1578,7 +1556,7 @@ "Decimal('0.9999999999999999')" ] }, - "execution_count": 49, + "execution_count": 48, "metadata": {}, "output_type": "execute_result" } From 8e87be2f43f6fb7905c9f8418ce9a0e70104cead Mon Sep 17 00:00:00 2001 From: Ed Chalstrey Date: Tue, 18 Nov 2025 16:20:19 +0000 Subject: [PATCH 13/17] consistent colons --- doc/tutorials/03_stripped_down_poker.ipynb | 56 ++++++++++++---------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/doc/tutorials/03_stripped_down_poker.ipynb b/doc/tutorials/03_stripped_down_poker.ipynb index 450d13fdf..ac9df7792 100644 --- a/doc/tutorials/03_stripped_down_poker.ipynb +++ b/doc/tutorials/03_stripped_down_poker.ipynb @@ -16,12 +16,10 @@ "2. [Computing and interpreting Nash equilibria](#computing-and-interpreting-nash-equilibria) and understanding mixed behaviour and mixed strategy profiles\n", "3. [Acceptance criteria for Nash equilibria](#acceptance-criteria-for-nash-equilibria)\n", "\n", - "A version of this game \n", - "\n", "In our version of the game, there are two players, **Alice** and **Bob**, and a deck of cards, with equal numbers of **King** and **Queen** cards.\n", "\n", "- The game begins with each player putting \\$1 in the pot.\n", - " - A card is dealt at random to Alice\n", + " - A card is dealt at random to Alice.\n", " - Alice observes her card.\n", " - Bob does not observe the card.\n", "- Alice then chooses either to **Bet** or to **Fold**.\n", @@ -31,7 +29,7 @@ " - If he chooses to Fold, Alice wins the pot and the game ends.\n", " - If he chooses to Call, he adds another $1 to the pot.\n", "- There is then a showdown, in which Alice reveals her card.\n", - " - If she has a King, then she wins the pot;\n", + " - If she has a King, then she wins the pot.\n", " - If she has a Queen, then Bob wins the pot." ] }, @@ -50,7 +48,7 @@ "id": "70819881", "metadata": {}, "source": [ - "Create the game with two players." + "Create the game with two players:" ] }, { @@ -107,7 +105,7 @@ "\n", "The first step in this game is that Alice is dealt a card which could be a King or Queen, each with probability 1/2.\n", "\n", - "To simulate this in Gambit, we create a chance player move at the root node of the game." + "To simulate this in Gambit, we create a chance player move at the root node of the game:" ] }, { @@ -135,7 +133,7 @@ "Alice knows her card, so the two nodes at which she has the move are part of different **information sets**.\n", "\n", "We'll therefore need to append Alice's move separately for each of the root node's children, i.e. the scenarios where she has a King or a Queen.\n", - "Let's now add both of these possible moves." + "Let's now add both of these possible moves:" ] }, { @@ -168,7 +166,7 @@ "In other words, Bob's decision when Alice Bets with a Queen should be part of the same information set as Bob's decision when Alice Bets with a King.\n", "\n", "To set this scenario up in Gambit, we'll need to use add both possible moves as part of the same information set (represented in Gambit as an `Infoset`).\n", - "This can be done by passing a list of nodes to the `append_move` method." + "This can be done by passing a list of nodes to the `append_move` method:" ] }, { @@ -195,7 +193,7 @@ "\n", "This is crucial in games where players must make decisions without complete knowledge of their opponents' private information.\n", "\n", - "Let's now set up the four possible payoff outcomes for the game. We'll label them according to player 1 (Alice)." + "Let's now set up the four possible payoff outcomes for the game. We'll label them according to player 1 (Alice):" ] }, { @@ -216,7 +214,7 @@ "id": "467a2c39", "metadata": {}, "source": [ - "Finally, we should assign an outcome to each of the terminal nodes in the game tree." + "Finally, we should assign an outcome to each of the terminal nodes in the game tree:" ] }, { @@ -249,7 +247,7 @@ "## Computing and interpreting Nash equilibria\n", "\n", "\n", - "Since our one-card poker game is extensive form and has two players, we can use the `lcp_solve` algorithm in Gambit to compute the Nash equilibria." + "Since our one-card poker game is extensive form and has two players, we can use the `lcp_solve` algorithm in Gambit to compute the Nash equilibria:" ] }, { @@ -305,9 +303,17 @@ "eqm = result.equilibria[0]" ] }, + { + "cell_type": "markdown", + "id": "1b1cd21e", + "metadata": {}, + "source": [ + "If we inspect the object type, we can see it's a `MixedBehaviorProfileRational` which is a subclass of `MixedBehaviorProfile` that uses rational numbers for probabilities:" + ] + }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "id": "3293e818", "metadata": {}, "outputs": [ @@ -323,8 +329,6 @@ } ], "source": [ - "# MixedBehaviorProfileRational is a subclass of MixedBehaviorProfile that uses\n", - "# rational numbers for probabilities.\n", "type(eqm)" ] }, @@ -661,7 +665,7 @@ "id": "9216ea34", "metadata": {}, "source": [ - "The corresponding probability that a node is reached in the play of the game is given by `MixedBehaviorProfile.realiz_prob`, and the expected payoff to a player conditional on reaching a node is given by `MixedBehaviorProfile.node_value`." + "The corresponding probability that a node is reached in the play of the game is given by `MixedBehaviorProfile.realiz_prob`, and the expected payoff to a player conditional on reaching a node is given by `MixedBehaviorProfile.node_value`:" ] }, { @@ -757,7 +761,7 @@ "\n", "When a game has an extensive representation, equilibrium finding methods default to computing on that representation.\n", "It is also possible to compute using the strategic representation.\n", - "`pygambit` transparently computes the reduced strategic form representation of an extensive game." + "`pygambit` transparently computes the reduced strategic form representation of an extensive game:" ] }, { @@ -823,7 +827,7 @@ "source": [ "`gnm_solve` can be applied to any game with any number of players, and uses a path-following process in floating-point arithmetic, so it returns profiles with probabilities expressed as floating-point numbers.\n", "\n", - "This method operates on the strategic representation of the game, so the returned results are of type `MixedStrategyProfile` (specifically `MixedStrategyProfileDouble`)." + "This method operates on the strategic representation of the game, so the returned results are of type `MixedStrategyProfile` (specifically `MixedStrategyProfileDouble`):" ] }, { @@ -974,7 +978,7 @@ "Any profile returned as an equilibrium is guaranteed to be an $\\varepsilon$-equilibrium, for $\\varepsilon$ no more than `maxregret`\n", "times the difference of the game's maximum and minimum payoffs.\n", "\n", - "As an example, consider solving our one-card poker game using `logit_solve`. The range of the payoffs in this game is 4 (from +2 to -2).\n" + "As an example, consider solving our one-card poker game using `logit_solve`. The range of the payoffs in this game is 4 (from +2 to -2):\n" ] }, { @@ -1119,7 +1123,7 @@ "id": "dc8c8509", "metadata": {}, "source": [ - "The tradeoff comes from some methods being slow to converge on some games, making it useful instead to get a more coarse approximation to an equilibrium (higher `maxregret` value) which is faster to calculate. " + "The tradeoff comes from some methods being slow to converge on some games, making it useful instead to get a more coarse approximation to an equilibrium (higher `maxregret` value) which is faster to calculate:" ] }, { @@ -1189,7 +1193,7 @@ "source": [ "The convention of expressing `maxregret` scaled by the game's payoffs standardises the behavior of methods across games.\n", "\n", - "For example, consider solving the poker game instead using `liap_solve()`." + "For example, consider solving the poker game instead using `liap_solve()`:" ] }, { @@ -1221,7 +1225,7 @@ "id": "c6853432", "metadata": {}, "source": [ - "If, instead, we double all payoffs, the output of the method is unchanged." + "If, instead, we double all payoffs, the output of the method is unchanged:" ] }, { @@ -1423,7 +1427,7 @@ "\n", "`pygambit` attempts to render `float` values in an appropriate `Decimal` equivalent.\n", "In the majority of cases, this creates no problems.\n", - "For example," + "For example:" ] }, { @@ -1453,7 +1457,7 @@ "id": "d53adcd4", "metadata": {}, "source": [ - "However, rounding can cause difficulties when attempting to use `float` values to represent values which do not have an exact decimal representation" + "However, rounding can cause difficulties when attempting to use `float` values to represent values which do not have an exact decimal representation:" ] }, { @@ -1483,7 +1487,7 @@ "metadata": {}, "source": [ "This behavior can be slightly surprising, especially in light of the fact that\n", - "in Python," + "in Python:" ] }, { @@ -1512,7 +1516,7 @@ "id": "a06699af", "metadata": {}, "source": [ - "In checking whether these probabilities sum to one, `pygambit` first converts each of the probabilities to a `Decimal` representation, via the following method" + "In checking whether these probabilities sum to one, `pygambit` first converts each of the probabilities to a `Decimal` representation, via the following method:" ] }, { @@ -1541,7 +1545,7 @@ "id": "4bfff415", "metadata": {}, "source": [ - "and the sum-to-one check then fails because" + "...and the sum-to-one check then fails because:" ] }, { From 708db39944cee1d28b26e681cd9eca174927a80a Mon Sep 17 00:00:00 2001 From: Ed Chalstrey Date: Tue, 18 Nov 2025 16:26:35 +0000 Subject: [PATCH 14/17] new name for turorial 03 --- doc/pygambit.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/pygambit.rst b/doc/pygambit.rst index b77da9f84..ceec241ec 100644 --- a/doc/pygambit.rst +++ b/doc/pygambit.rst @@ -23,7 +23,7 @@ They are numbered in the order they should be read. tutorials/running_locally tutorials/01_quickstart tutorials/02_extensive_form - tutorials/03_poker + tutorials/03_stripped_down_poker Advanced user tutorials ----------------------- From fb84f71ec53d815774c37cd6bf9a12d41de350b1 Mon Sep 17 00:00:00 2001 From: Ed Chalstrey Date: Thu, 27 Nov 2025 12:48:35 +0000 Subject: [PATCH 15/17] minor edits --- doc/tutorials/03_stripped_down_poker.ipynb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/tutorials/03_stripped_down_poker.ipynb b/doc/tutorials/03_stripped_down_poker.ipynb index ac9df7792..87b1fcd56 100644 --- a/doc/tutorials/03_stripped_down_poker.ipynb +++ b/doc/tutorials/03_stripped_down_poker.ipynb @@ -191,7 +191,7 @@ "In game theory terms, this creates \"imperfect information\".\n", "Bob cannot distinguish between these two nodes in the game tree, so he must use the same strategy (same probabilities for Call vs. Fold) in both situations.\n", "\n", - "This is crucial in games where players must make decisions without complete knowledge of their opponents' private information.\n", + "This is crucial in games where players must make decisions without full knowledge of the state of the game.\n", "\n", "Let's now set up the four possible payoff outcomes for the game. We'll label them according to player 1 (Alice):" ] @@ -247,7 +247,7 @@ "## Computing and interpreting Nash equilibria\n", "\n", "\n", - "Since our one-card poker game is extensive form and has two players, we can use the `lcp_solve` algorithm in Gambit to compute the Nash equilibria:" + "Since our one-card poker game has two players, we can use the `lcp_solve` algorithm in Gambit to compute a Nash equilibrium:" ] }, { @@ -563,7 +563,7 @@ "id": "db19411b", "metadata": {}, "source": [ - "Because this is an equilibrium, Bob is indifferent between the two actions at his information set, meaning he has no reason to prefer one action over the other, given Alice's expected strategy.\n", + "Because this is an equilibrium, Bob is indifferent between the two actions at his information set, meaning he has no reason to prefer one action over the other, in expectation, given Alice's expected strategy.\n", "\n", "`MixedBehaviorProfile.action_value` returns the expected payoff of taking an action, conditional on reaching that action's information set:" ] @@ -968,7 +968,7 @@ "\n", "> In game theory, an epsilon-equilibrium, or near-Nash equilibrium, is a strategy profile that approximately satisfies the condition of Nash equilibrium. In a Nash equilibrium, no player has an incentive to change his behavior. In an approximate Nash equilibrium, this requirement is weakened to allow the possibility that a player may have a small incentive to do something different.\n", "\n", - "> Given a game and a real non-negative parameter $\\varepsilon$, a strategy profile is said to be an $\\varepsilon$-equilibrium if it is not possible for any player to gain more than $\\varepsilon$ in expected payoff by unilaterally deviating from his strategy. Every Nash Equilibrium is equivalent to an $\\varepsilon$-equilibrium where $\\varepsilon = 0$.\n", + "> Given a game and a real non-negative parameter $\\varepsilon$, a strategy profile is said to be an $\\varepsilon$-equilibrium if it is not possible for any player to gain more than $\\varepsilon$ in expected payoff by unilaterally deviating from his strategy. Every Nash Equilibrium is an $\\varepsilon$-equilibrium where $\\varepsilon = 0$.\n", "\n", "\n", "To provide a uniform interface across methods, where relevant Gambit provides a parameter\n", From 58bc9a011cf0be36d2728cd09ef42c7f6164ba4a Mon Sep 17 00:00:00 2001 From: Ed Chalstrey Date: Thu, 27 Nov 2025 12:49:14 +0000 Subject: [PATCH 16/17] typo --- doc/tutorials/03_stripped_down_poker.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tutorials/03_stripped_down_poker.ipynb b/doc/tutorials/03_stripped_down_poker.ipynb index 87b1fcd56..4f1c27fb3 100644 --- a/doc/tutorials/03_stripped_down_poker.ipynb +++ b/doc/tutorials/03_stripped_down_poker.ipynb @@ -165,7 +165,7 @@ "\n", "In other words, Bob's decision when Alice Bets with a Queen should be part of the same information set as Bob's decision when Alice Bets with a King.\n", "\n", - "To set this scenario up in Gambit, we'll need to use add both possible moves as part of the same information set (represented in Gambit as an `Infoset`).\n", + "To set this scenario up in Gambit, we'll need to add both possible moves as part of the same information set (represented in Gambit as an `Infoset`).\n", "This can be done by passing a list of nodes to the `append_move` method:" ] }, From 1c11e03bba2ef285ec8aa225819c938ded627429 Mon Sep 17 00:00:00 2001 From: Ed Chalstrey Date: Thu, 27 Nov 2025 12:50:45 +0000 Subject: [PATCH 17/17] more minor edits --- doc/tutorials/03_stripped_down_poker.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tutorials/03_stripped_down_poker.ipynb b/doc/tutorials/03_stripped_down_poker.ipynb index 4f1c27fb3..624a1b624 100644 --- a/doc/tutorials/03_stripped_down_poker.ipynb +++ b/doc/tutorials/03_stripped_down_poker.ipynb @@ -189,7 +189,7 @@ "metadata": {}, "source": [ "In game theory terms, this creates \"imperfect information\".\n", - "Bob cannot distinguish between these two nodes in the game tree, so he must use the same strategy (same probabilities for Call vs. Fold) in both situations.\n", + "Bob cannot distinguish between these two nodes in the game tree, so he must use the same same probabilities for Call vs. Fold in both situations.\n", "\n", "This is crucial in games where players must make decisions without full knowledge of the state of the game.\n", "\n",