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
3 changes: 1 addition & 2 deletions doc/pygambit.api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,10 @@ Information about the game
Game.max_payoff
Game.get_min_payoff
Game.get_max_payoff
Game.root
Game.get_infosets
Game.get_events
Game.get_strategies
Game.get_sequences
Game.nodes
Game.contingencies
Game.get_outcome
Game.get_payoffs
Expand Down Expand Up @@ -150,6 +148,7 @@ Information about the game
Node.is_successor_of
Node.plays
Node.own_prior_action
Node.history

.. autosummary::
:toctree: api/
Expand Down
28 changes: 23 additions & 5 deletions doc/tutorials/02_extensive_form.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@
"outputs": [],
"source": [
"g.append_move(\n",
" g.root, # This is the node to append the move to\n",
" gbt.H.path(), # This is the node to append the move to\n",
" player=\"Buyer\",\n",
" actions=[\"Trust\", \"Not trust\"]\n",
")"
Expand Down Expand Up @@ -138,7 +138,7 @@
"outputs": [],
"source": [
"g.append_move(\n",
" g.root.children[\"Trust\"],\n",
" gbt.H.path(\"Trust\"),\n",
" player=\"Seller\",\n",
" actions=[\"Honor\", \"Abuse\"]\n",
")"
Expand Down Expand Up @@ -172,7 +172,13 @@
"id": "716e9b9a",
"metadata": {},
"outputs": [],
"source": "g.make_outcome(\n g.root.children[\"Trust\"].children[\"Honor\"],\n {\"Buyer\": 1, \"Seller\": 1},\n \"Trustworthy\"\n)"
"source": [
"g.make_outcome(\n",
" gbt.H.path(\"Trust\", \"Honor\"),\n",
" {\"Buyer\": 1, \"Seller\": 1},\n",
" \"Trustworthy\"\n",
")"
]
},
{
"cell_type": "code",
Expand All @@ -198,7 +204,13 @@
"id": "695b1aad",
"metadata": {},
"outputs": [],
"source": "g.make_outcome(\n g.root.children[\"Trust\"].children[\"Abuse\"],\n {\"Buyer\": -1, \"Seller\": 2},\n \"Untrustworthy\"\n)"
"source": [
"g.make_outcome(\n",
" gbt.H.path(\"Trust\", \"Abuse\"),\n",
" {\"Buyer\": -1, \"Seller\": 2},\n",
" \"Untrustworthy\"\n",
")"
]
},
{
"cell_type": "code",
Expand All @@ -224,7 +236,13 @@
"id": "0704ef86",
"metadata": {},
"outputs": [],
"source": "g.make_outcome(\n g.root.children[\"Not trust\"],\n {\"Buyer\": 0, \"Seller\": 0},\n \"Opt-out\"\n)"
"source": [
"g.make_outcome(\n",
" gbt.H.path(\"Not trust\"),\n",
" {\"Buyer\": 0, \"Seller\": 0},\n",
" \"Opt-out\"\n",
")"
]
},
{
"cell_type": "code",
Expand Down
96 changes: 70 additions & 26 deletions doc/tutorials/03_stripped_down_poker.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,13 @@
"id": "fe80c64c",
"metadata": {},
"outputs": [],
"source": "g.append_event(\n g.root,\n actions=[\"King\", \"Queen\"],\n probs=[gbt.Rational(1, 2), gbt.Rational(1, 2)]\n)"
"source": [
"g.append_event(\n",
" gbt.H.path(),\n",
" actions=[\"King\", \"Queen\"],\n",
" probs=[gbt.Rational(1, 2), gbt.Rational(1, 2)]\n",
")"
]
},
{
"cell_type": "code",
Expand Down Expand Up @@ -137,7 +143,7 @@
"metadata": {},
"outputs": [],
"source": [
"for node in g.root.children:\n",
"for node in g.get_nodes(gbt.H.path(...)):\n",
" g.append_move(\n",
" node,\n",
" player=\"Alice\",\n",
Expand All @@ -162,15 +168,15 @@
"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’s 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\u2019s 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",
" - Chance player chooses King, then Alice Bets: `gbt.H.path(\"King\", \"Bet\")`\n",
" - Chance player chooses Queen, then Alice Bets: `gbt.H.path(\"Queen\", \"Bet\")`\n",
"\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 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 selector matching both nodes to the `append_move` method:"
]
},
{
Expand All @@ -181,7 +187,7 @@
"outputs": [],
"source": [
"g.append_move(\n",
" [g.root.children[\"King\"].children[\"Bet\"], g.root.children[\"Queen\"].children[\"Bet\"]],\n",
" gbt.H.path(..., \"Bet\"),\n",
" player=\"Bob\",\n",
" actions=[\"Call\", \"Fold\"]\n",
")"
Expand Down Expand Up @@ -209,7 +215,35 @@
"id": "29aa60a0",
"metadata": {},
"outputs": [],
"source": "# Alice folds, Bob wins small\ng.make_outcome(\n [g.root.children[\"King\"].children[\"Fold\"], g.root.children[\"Queen\"].children[\"Fold\"]],\n {\"Alice\": -1, \"Bob\": 1},\n \"Lose\"\n)\n\n# Bob sees Alice Bet and calls, correctly believing she is bluffing, Bob wins big\ng.make_outcome(\n g.root.children[\"Queen\"].children[\"Bet\"].children[\"Call\"],\n {\"Alice\": -2, \"Bob\": 2},\n \"Lose Big\"\n)\n\n# Bob sees Alice Bet and calls, incorrectly believing she is bluffing, Alice wins big\ng.make_outcome(\n g.root.children[\"King\"].children[\"Bet\"].children[\"Call\"],\n {\"Alice\": 2, \"Bob\": -2},\n \"Win Big\"\n)\n\n# Bob does not call Alice's Bet, Alice wins small\ng.make_outcome(\n [g.root.children[\"King\"].children[\"Bet\"].children[\"Fold\"],\n g.root.children[\"Queen\"].children[\"Bet\"].children[\"Fold\"]],\n {\"Alice\": 1, \"Bob\": -1},\n \"Win\"\n)"
"source": [
"# Alice folds, Bob wins small\n",
"g.make_outcome(\n",
" gbt.H.path(..., \"Fold\"),\n",
" {\"Alice\": -1, \"Bob\": 1},\n",
" \"Lose\"\n",
")\n",
"\n",
"# Bob sees Alice Bet and calls, correctly believing she is bluffing, Bob wins big\n",
"g.make_outcome(\n",
" gbt.H.path(\"Queen\", \"Bet\", \"Call\"),\n",
" {\"Alice\": -2, \"Bob\": 2},\n",
" \"Lose Big\"\n",
")\n",
"\n",
"# Bob sees Alice Bet and calls, incorrectly believing she is bluffing, Alice wins big\n",
"g.make_outcome(\n",
" gbt.H.path(\"King\", \"Bet\", \"Call\"),\n",
" {\"Alice\": 2, \"Bob\": -2},\n",
" \"Win Big\"\n",
")\n",
"\n",
"# Bob does not call Alice's Bet, Alice wins small\n",
"g.make_outcome(\n",
" gbt.H.path(..., \"Bet\", \"Fold\"),\n",
" {\"Alice\": 1, \"Bob\": -1},\n",
" \"Win\"\n",
")"
]
},
{
"cell_type": "code",
Expand Down Expand Up @@ -347,7 +381,7 @@
" for action in node.actions:\n",
" print(\n",
" f\"At information set {node.infoset.number}, \"\n",
" f\"Alice plays {action} with probability: {eqm[node][action]}\"\n",
" f\"Alice plays {action} with probability: {eqm[node.history][action]}\"\n",
" )"
]
},
Expand All @@ -356,7 +390,7 @@
"id": "1f121d48",
"metadata": {},
"source": [
"Now let's look at Bob’s strategy:"
"Now let's look at Bob\u2019s strategy:"
]
},
{
Expand All @@ -374,7 +408,7 @@
"id": "e906c4c4",
"metadata": {},
"source": [
"Bob Calls Alice’s Bet two-thirds of the time.\n",
"Bob Calls Alice\u2019s 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 All @@ -386,7 +420,11 @@
"id": "2966e700",
"metadata": {},
"outputs": [],
"source": "(bob_node,) = g.get_infosets(\"Bob\")\nbob_infoset = bob_node.infoset\neqm[bob_node][\"Call\"]"
"source": [
"(bob_node,) = g.get_infosets(\"Bob\")\n",
"bob_infoset = bob_node.infoset\n",
"eqm[bob_node.history][\"Call\"]"
]
},
{
"cell_type": "markdown",
Expand Down Expand Up @@ -421,7 +459,7 @@
"\n",
"`MixedBehaviorProfile.beliefs` returns the probability of reaching each 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[\"Bet\"]` and `g.root.children[\"Queen\"].children[\"Bet\"]`):"
"Recall that the two nodes in Bob's only information set are `gbt.H.path(\"King\", \"Bet\")` and `gbt.H.path(\"Queen\", \"Bet\")`):"
]
},
{
Expand Down Expand Up @@ -819,8 +857,9 @@
"outputs": [],
"source": [
"small_game = gbt.Game.new_tree()\n",
"small_game.append_event(small_game.root, [\"a\", \"b\", \"c\"], [gbt.Rational(1, 3)] * 3)\n",
"list(small_game.root.action_probs.values())"
"root = small_game.get_nodes(gbt.H.path())[0]\n",
"small_game.append_event(root, [\"a\", \"b\", \"c\"], [gbt.Rational(1, 3)] * 3)\n",
"list(root.action_probs.values())"
]
},
{
Expand All @@ -837,10 +876,10 @@
"outputs": [],
"source": [
"small_game.make_event(\n",
" [small_game.root],\n",
" [root],\n",
" [gbt.Rational(1, 4), gbt.Rational(1, 2), gbt.Rational(1, 4)]\n",
")\n",
"list(small_game.root.action_probs.values())"
"list(root.action_probs.values())"
]
},
{
Expand All @@ -859,10 +898,10 @@
"outputs": [],
"source": [
"small_game.make_event(\n",
" [small_game.root],\n",
" [root],\n",
" [gbt.Decimal(\".25\"), gbt.Decimal(\".50\"), gbt.Decimal(\".25\")]\n",
")\n",
"list(small_game.root.action_probs.values())"
"list(root.action_probs.values())"
]
},
{
Expand All @@ -884,8 +923,8 @@
"metadata": {},
"outputs": [],
"source": [
"small_game.make_event([small_game.root], [\"1/4\", \"1/2\", \"1/4\"])\n",
"list(small_game.root.action_probs.values())"
"small_game.make_event([root], [\"1/4\", \"1/2\", \"1/4\"])\n",
"list(root.action_probs.values())"
]
},
{
Expand All @@ -895,8 +934,8 @@
"metadata": {},
"outputs": [],
"source": [
"small_game.make_event([small_game.root], [\".25\", \".50\", \".25\"])\n",
"list(small_game.root.action_probs.values())"
"small_game.make_event([root], [\".25\", \".50\", \".25\"])\n",
"list(root.action_probs.values())"
]
},
{
Expand All @@ -919,8 +958,8 @@
"metadata": {},
"outputs": [],
"source": [
"small_game.make_event([small_game.root], [.25, .50, .25])\n",
"list(small_game.root.action_probs.values())"
"small_game.make_event([root], [.25, .50, .25])\n",
"list(root.action_probs.values())"
]
},
{
Expand All @@ -937,7 +976,12 @@
"id": "1991d288",
"metadata": {},
"outputs": [],
"source": "try:\n small_game.make_event([small_game.root], [1/3, 1/3, 1/3])\nexcept ValueError as e:\n print(\"ValueError:\", e)\n"
"source": [
"try:\n",
" small_game.make_event([root], [1/3, 1/3, 1/3])\n",
"except ValueError as e:\n",
" print(\"ValueError:\", e)\n"
]
},
{
"cell_type": "markdown",
Expand Down
Loading
Loading