Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## [17.0.0-beta.1] - unreleased

### Changed
- In `pygambit` actions are referred to by their labels, with node or information set context
only when required.


## [17.0.0-alpha.2] - 2026-08-21

### Added
Expand Down
33 changes: 18 additions & 15 deletions doc/pygambit.api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ Representation of games
Outcome
Node
Infoset
Action
Strategy
Subgame

Expand Down Expand Up @@ -110,7 +109,6 @@ Information about the game
Game.max_payoff
Game.strategies
Game.root
Game.actions
Game.infosets
Game.nodes
Game.contingencies
Expand All @@ -125,7 +123,6 @@ Information about the game
Player.game
Player.strategies
Player.infosets
Player.actions
Player.is_chance
Player.min_payoff
Player.max_payoff
Expand Down Expand Up @@ -158,6 +155,8 @@ Information about the game
Node.plays
Node.own_prior_action

Branch

.. autosummary::
:toctree: api/

Expand All @@ -176,20 +175,10 @@ Information about the game
Infoset.is_absent_minded
Infoset.player
Infoset.actions
Infoset.action_probs
Infoset.members
Infoset.precedes
Infoset.plays
Infoset.own_prior_actions

.. autosummary::

:toctree: api/

Action.label
Action.infoset
Action.precedes
Action.prob
Action.plays

.. autosummary::

Expand All @@ -199,7 +188,6 @@ Information about the game
Strategy.game
Strategy.player
Strategy.number
Strategy.action

.. autosummary::

Expand All @@ -209,6 +197,8 @@ Information about the game
Sequence.parent
Sequence.actions

Action

Player behavior
...............

Expand All @@ -220,6 +210,19 @@ Player behavior
Game.mixed_behavior_profile
Game.random_behavior_profile
Game.strategy_support_profile
Game.get_behavior

StrategyBehavior
StrategyBehavior.player
StrategyBehavior.strategy
StrategyBehavior.__getitem__
StrategyBehavior.get
StrategyBehavior.__contains__
StrategyBehavior.__iter__
StrategyBehavior.__len__
StrategyBehavior.keys
StrategyBehavior.values
StrategyBehavior.items


Representation of strategic behavior
Expand Down
71 changes: 14 additions & 57 deletions doc/tutorials/03_stripped_down_poker.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@
"source": [
"The loop above causes each of the newly-appended moves to be in new information sets, reflecting the fact that Alice's decision depends on the knowledge of which card she holds.\n",
"\n",
"In contrast, Bob does not know Alice\u2019s card, and therefore cannot distinguish between the two nodes at which he has to make his decision:\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 Bets: `g.root.children[\"King\"].children[\"Bet\"]`\n",
" - Chance player chooses Queen, then Alice Bets: `g.root.children[\"Queen\"].children[\"Bet\"]`\n",
Expand Down Expand Up @@ -382,21 +382,14 @@
"id": "83bbd3e5",
"metadata": {},
"outputs": [],
"source": [
"for action in g.players[\"Alice\"].actions:\n",
" node = next(iter(action.infoset.members))\n",
" print(\n",
" f\"At information set {action.infoset.number}, \"\n",
" f\"Alice plays {action.label} with probability: {eqm[node][action.label]}\"\n",
" )"
]
"source": "for infoset in g.players[\"Alice\"].infosets:\n for label in infoset.actions:\n node = next(iter(infoset.members))\n print(\n f\"At information set {infoset.number}, \"\n f\"Alice plays {label} with probability: {eqm[node][label]}\"\n )"
},
{
"cell_type": "markdown",
"id": "1f121d48",
"metadata": {},
"source": [
"Now let's look at Bob\u2019s strategy:"
"Now let's look at Bob’s strategy:"
]
},
{
Expand All @@ -414,7 +407,7 @@
"id": "e906c4c4",
"metadata": {},
"source": [
"Bob Calls Alice\u2019s Bet two-thirds of the time.\n",
"Bob Calls Alice’s Bet two-thirds of the time.\n",
"\n",
"Since Bob has just one information set, we can get its representative node and index\n",
"the profile directly by it to read off a single action's probability:"
Expand Down Expand Up @@ -448,13 +441,7 @@
"id": "a7d3816d",
"metadata": {},
"outputs": [],
"source": [
"bob_action_values = eqm.action_values[bob_node]\n",
"for action in bob_infoset.actions:\n",
" print(\n",
" f\"When Bob plays {action.label} his expected payoff is {bob_action_values[action.label]}\"\n",
" )"
]
"source": "bob_action_values = eqm.action_values[bob_node]\nfor label in bob_infoset.actions:\n print(\n f\"When Bob plays {label} his expected payoff is {bob_action_values[label]}\"\n )"
},
{
"cell_type": "markdown",
Expand All @@ -474,13 +461,7 @@
"id": "4a54b20c",
"metadata": {},
"outputs": [],
"source": [
"for node in bob_infoset.members:\n",
" print(\n",
" f\"Bob's belief in reaching the {node.parent.prior_action.label} -> \"\n",
" f\"{node.prior_action.label} node is: {eqm.beliefs[node]}\"\n",
" )"
]
"source": "for node in bob_infoset.members:\n print(\n f\"Bob's belief in reaching the {node.parent.prior_action[1]} -> \"\n f\"{node.prior_action[1]} node is: {eqm.beliefs[node]}\"\n )"
},
{
"cell_type": "markdown",
Expand Down Expand Up @@ -516,15 +497,7 @@
"id": "6f01846b",
"metadata": {},
"outputs": [],
"source": [
"bob_node_values = eqm.node_values[\"Bob\"]\n",
"for node in bob_infoset.members:\n",
" print(\n",
" f\"The probability that the node {node.parent.prior_action.label} -> \"\n",
" f\"{node.prior_action.label} is reached is: {eqm.realiz_probs[node]}. \",\n",
" f\"Bob's expected payoff conditional on reaching this node is {bob_node_values[node]}\"\n",
" )"
]
"source": "bob_node_values = eqm.node_values[\"Bob\"]\nfor node in bob_infoset.members:\n print(\n f\"The probability that the node {node.parent.prior_action[1]} -> \"\n f\"{node.prior_action[1]} is reached is: {eqm.realiz_probs[node]}. \",\n f\"Bob's expected payoff conditional on reaching this node is {bob_node_values[node]}\"\n )"
},
{
"cell_type": "markdown",
Expand Down Expand Up @@ -658,23 +631,7 @@
"id": "d18a91f0",
"metadata": {},
"outputs": [],
"source": [
"for player in g.players:\n",
" print(\n",
" f\"{player.label}'s expected payoffs:\"\n",
" )\n",
" gnm_action_values = gnm_eqm.as_behavior().action_values\n",
" lcp_action_values = eqm.action_values\n",
" for action in player.actions:\n",
" node = next(iter(action.infoset.members))\n",
" print(\n",
" f\"At information set {action.infoset.number}, \"\n",
" f\"when playing {action.label} - \"\n",
" f\"gnm: {gnm_action_values[node][action.label]:.4f}\"\n",
" f\", lcp: {str(lcp_action_values[node][action.label])}\"\n",
" )\n",
" print()"
]
"source": "for player in g.players:\n print(\n f\"{player.label}'s expected payoffs:\"\n )\n gnm_action_values = gnm_eqm.as_behavior().action_values\n lcp_action_values = eqm.action_values\n for infoset in player.infosets:\n for label in infoset.actions:\n node = next(iter(infoset.members))\n print(\n f\"At information set {infoset.number}, \"\n f\"when playing {label} - \"\n f\"gnm: {gnm_action_values[node][label]:.4f}\"\n f\", lcp: {str(lcp_action_values[node][label])}\"\n )\n print()"
},
{
"cell_type": "markdown",
Expand Down Expand Up @@ -879,7 +836,7 @@
"id": "2f79695a",
"metadata": {},
"outputs": [],
"source": "small_game = gbt.Game.new_tree()\nsmall_game.append_event(small_game.root, [\"a\", \"b\", \"c\"], [gbt.Rational(1, 3)] * 3)\n[act.prob for act in small_game.root.infoset.actions]"
"source": "small_game = gbt.Game.new_tree()\nsmall_game.append_event(small_game.root, [\"a\", \"b\", \"c\"], [gbt.Rational(1, 3)] * 3)\nlist(small_game.root.infoset.action_probs.values())"
},
{
"cell_type": "markdown",
Expand All @@ -893,7 +850,7 @@
"id": "5de6acb2",
"metadata": {},
"outputs": [],
"source": "small_game.make_event(\n [small_game.root],\n [gbt.Rational(1, 4), gbt.Rational(1, 2), gbt.Rational(1, 4)]\n)\n[act.prob for act in small_game.root.infoset.actions]"
"source": "small_game.make_event(\n [small_game.root],\n [gbt.Rational(1, 4), gbt.Rational(1, 2), gbt.Rational(1, 4)]\n)\nlist(small_game.root.infoset.action_probs.values())"
},
{
"cell_type": "markdown",
Expand All @@ -909,7 +866,7 @@
"id": "c47d2ab6",
"metadata": {},
"outputs": [],
"source": "small_game.make_event(\n [small_game.root],\n [gbt.Decimal(\".25\"), gbt.Decimal(\".50\"), gbt.Decimal(\".25\")]\n)\n[act.prob for act in small_game.root.infoset.actions]"
"source": "small_game.make_event(\n [small_game.root],\n [gbt.Decimal(\".25\"), gbt.Decimal(\".50\"), gbt.Decimal(\".25\")]\n)\nlist(small_game.root.infoset.action_probs.values())"
},
{
"cell_type": "markdown",
Expand All @@ -929,15 +886,15 @@
"id": "04329084",
"metadata": {},
"outputs": [],
"source": "small_game.make_event([small_game.root], [\"1/4\", \"1/2\", \"1/4\"])\n[act.prob for act in small_game.root.infoset.actions]"
"source": "small_game.make_event([small_game.root], [\"1/4\", \"1/2\", \"1/4\"])\nlist(small_game.root.infoset.action_probs.values())"
},
{
"cell_type": "code",
"execution_count": null,
"id": "9015e129",
"metadata": {},
"outputs": [],
"source": "small_game.make_event([small_game.root], [\".25\", \".50\", \".25\"])\n[act.prob for act in small_game.root.infoset.actions]"
"source": "small_game.make_event([small_game.root], [\".25\", \".50\", \".25\"])\nlist(small_game.root.infoset.action_probs.values())"
},
{
"cell_type": "markdown",
Expand All @@ -958,7 +915,7 @@
"id": "0a019aa5",
"metadata": {},
"outputs": [],
"source": "small_game.make_event([small_game.root], [.25, .50, .25])\n[act.prob for act in small_game.root.infoset.actions]"
"source": "small_game.make_event([small_game.root], [.25, .50, .25])\nlist(small_game.root.infoset.action_probs.values())"
},
{
"cell_type": "markdown",
Expand Down
123 changes: 0 additions & 123 deletions src/pygambit/action.pxi

This file was deleted.

Loading
Loading