diff --git a/.gitignore b/.gitignore
index d2f3fe579..9d37e0d3b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -48,3 +48,5 @@ doc/tutorials/*.png
Gambit.app/*
*.ipynb_checkpoints
*.ef
+build_support/msw/gambit.wxs
+build_support/osx/Info.plist
diff --git a/Makefile.am b/Makefile.am
index fe3fc232f..b0680a7d7 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -100,147 +100,152 @@ EXTRA_DIST = \
src/gui/bitmaps/zoomout.xpm \
src/gui/bitmaps/zoom1.xpm \
src/gui/bitmaps/gambitrc.rc \
- contrib/games/2s2x2x2.efg \
- contrib/games/2smp.efg \
- contrib/games/2x2x2.efg \
- contrib/games/4cards.efg \
- contrib/games/artist1.efg \
- contrib/games/artist2.efg \
- contrib/games/badgame1.efg \
- contrib/games/badgame2.efg \
- contrib/games/bayes1a.efg \
- contrib/games/bayes2a.efg \
- contrib/games/bcp2.efg \
- contrib/games/bcp3.efg \
- contrib/games/bcp4.efg \
- contrib/games/bhg1.efg \
- contrib/games/bhg2.efg \
- contrib/games/bhg3.efg \
- contrib/games/bhg4.efg \
- contrib/games/bhg5.efg \
- contrib/games/caro2.efg \
- contrib/games/cent2.efg \
- contrib/games/cent3.efg \
- contrib/games/cent4.efg \
- contrib/games/cent6.efg \
- contrib/games/centcs10.efg \
- contrib/games/centcs6.efg \
- contrib/games/condjury.efg \
- contrib/games/coord2.efg \
- contrib/games/coord2ts.efg \
- contrib/games/coord3.efg \
- contrib/games/coord4.efg \
- contrib/games/cross.efg \
- contrib/games/cs.efg \
- contrib/games/e01.efg \
- contrib/games/e02.efg \
- contrib/games/e03.efg \
- contrib/games/e04.efg \
- contrib/games/e05.efg \
- contrib/games/e06.efg \
- contrib/games/e07.efg \
- contrib/games/e08.efg \
- contrib/games/e09.efg \
- contrib/games/e10a.efg \
- contrib/games/e10.efg \
- contrib/games/e13.efg \
- contrib/games/e16.efg \
- contrib/games/e17.efg \
- contrib/games/e18.efg \
- contrib/games/g1.efg \
- contrib/games/g2.efg \
- contrib/games/g3.efg \
- contrib/games/holdout7.efg \
- contrib/games/holdout.efg \
- contrib/games/hs1.efg \
- contrib/games/jury_mr.efg \
- contrib/games/jury_un.efg \
- contrib/games/km1.efg \
- contrib/games/km2.efg \
- contrib/games/km3.efg \
- contrib/games/km6.efg \
- contrib/games/montyhal.efg \
- contrib/games/my_2-1.efg \
- contrib/games/my_2-4.efg \
- contrib/games/my_2-8.efg \
- contrib/games/my_3-3a.efg \
- contrib/games/my_3-3b.efg \
- contrib/games/my_3-3c.efg \
- contrib/games/my_3-3d.efg \
- contrib/games/my_3-3e.efg \
- contrib/games/my_3-4.efg \
- contrib/games/myerson.efg \
- contrib/games/nim7.efg \
- contrib/games/nim.efg \
- contrib/games/palf2.efg \
- contrib/games/palf3.efg \
- contrib/games/palf.efg \
- contrib/games/poker2.efg \
- contrib/games/poker.efg \
- contrib/games/pvw2.efg \
- contrib/games/pvw.efg \
- contrib/games/sh3.efg \
- contrib/games/sww1.efg \
- contrib/games/sww2.efg \
- contrib/games/sww3.efg \
- contrib/games/tim.efg \
- contrib/games/ttt.efg \
- contrib/games/vd.efg \
- contrib/games/w_ex1.efg \
- contrib/games/w_ex2.efg \
- contrib/games/wilson1.efg \
- contrib/games/work1.efg \
- contrib/games/work2.efg \
- contrib/games/work3.efg \
- contrib/games/2x2a.nfg \
- contrib/games/2x2const.nfg \
- contrib/games/2x2.nfg \
- contrib/games/2x2x2.nfg \
- contrib/games/2x2x2x2.nfg \
- contrib/games/2x2x2x2x2.nfg \
- contrib/games/3x3x3.nfg \
- contrib/games/5x4x3.nfg \
- contrib/games/8x2x2.nfg \
- contrib/games/8x8.nfg \
- contrib/games/cent2.nfg \
- contrib/games/coord2.nfg \
- contrib/games/coord333.nfg \
- contrib/games/coord3.nfg \
- contrib/games/coord4.nfg \
- contrib/games/csg1.nfg \
- contrib/games/csg2.nfg \
- contrib/games/csg3.nfg \
- contrib/games/csg4.nfg \
- contrib/games/deg1.nfg \
- contrib/games/deg2.nfg \
- contrib/games/e01.nfg \
- contrib/games/e02.nfg \
- contrib/games/e04.nfg \
- contrib/games/e07.nfg \
- contrib/games/g1.nfg \
- contrib/games/g2.nfg \
- contrib/games/g3.nfg \
- contrib/games/loopback.nfg \
- contrib/games/mixdom2.nfg \
- contrib/games/mixdom.nfg \
- contrib/games/oneill.nfg \
- contrib/games/pd.nfg \
- contrib/games/perfect1.nfg \
- contrib/games/perfect2.nfg \
- contrib/games/perfect3.nfg \
- contrib/games/poker.nfg \
- contrib/games/sh3.nfg \
- contrib/games/stengel.nfg \
- contrib/games/sww1.nfg \
- contrib/games/todd1.nfg \
- contrib/games/todd2.nfg \
- contrib/games/todd3.nfg \
- contrib/games/vd.nfg \
- contrib/games/wink3.nfg \
- contrib/games/winkels.nfg \
- contrib/games/yamamoto.nfg \
- contrib/games/zero.nfg \
- src/README.rst
+ src/README.rst \
+ src/pygambit/catalog_game_files/2s2x2x2.efg \
+ src/pygambit/catalog_game_files/2smp.efg \
+ src/pygambit/catalog_game_files/2x2.nfg \
+ src/pygambit/catalog_game_files/2x2a.nfg \
+ src/pygambit/catalog_game_files/2x2const.nfg \
+ src/pygambit/catalog_game_files/2x2x2-nau.nfg \
+ src/pygambit/catalog_game_files/2x2x2.efg \
+ src/pygambit/catalog_game_files/2x2x2.nfg \
+ src/pygambit/catalog_game_files/2x2x2x2.nfg \
+ src/pygambit/catalog_game_files/2x2x2x2x2.nfg \
+ src/pygambit/catalog_game_files/3x3x3.nfg \
+ src/pygambit/catalog_game_files/4cards.efg \
+ src/pygambit/catalog_game_files/5x4x3.nfg \
+ src/pygambit/catalog_game_files/8x2x2.nfg \
+ src/pygambit/catalog_game_files/8x8.nfg \
+ src/pygambit/catalog_game_files/artist1.efg \
+ src/pygambit/catalog_game_files/artist2.efg \
+ src/pygambit/catalog_game_files/badgame1.efg \
+ src/pygambit/catalog_game_files/badgame2.efg \
+ src/pygambit/catalog_game_files/bagwell.efg \
+ src/pygambit/catalog_game_files/bayes1a.efg \
+ src/pygambit/catalog_game_files/bayes2a.efg \
+ src/pygambit/catalog_game_files/bcp2.efg \
+ src/pygambit/catalog_game_files/bcp3.efg \
+ src/pygambit/catalog_game_files/bcp4.efg \
+ src/pygambit/catalog_game_files/bhg1.efg \
+ src/pygambit/catalog_game_files/bhg2.efg \
+ src/pygambit/catalog_game_files/bhg3.efg \
+ src/pygambit/catalog_game_files/bhg4.efg \
+ src/pygambit/catalog_game_files/bhg5.efg \
+ src/pygambit/catalog_game_files/caro2.efg \
+ src/pygambit/catalog_game_files/cent2.efg \
+ src/pygambit/catalog_game_files/cent2.nfg \
+ src/pygambit/catalog_game_files/cent3.efg \
+ src/pygambit/catalog_game_files/cent4.efg \
+ src/pygambit/catalog_game_files/cent6.efg \
+ src/pygambit/catalog_game_files/centcs10.efg \
+ src/pygambit/catalog_game_files/centcs6.efg \
+ src/pygambit/catalog_game_files/condjury.efg \
+ src/pygambit/catalog_game_files/coord2.efg \
+ src/pygambit/catalog_game_files/coord2.nfg \
+ src/pygambit/catalog_game_files/coord2ts.efg \
+ src/pygambit/catalog_game_files/coord3.efg \
+ src/pygambit/catalog_game_files/coord3.nfg \
+ src/pygambit/catalog_game_files/coord333.nfg \
+ src/pygambit/catalog_game_files/coord4.efg \
+ src/pygambit/catalog_game_files/coord4.nfg \
+ src/pygambit/catalog_game_files/cross.efg \
+ src/pygambit/catalog_game_files/cs.efg \
+ src/pygambit/catalog_game_files/csg1.nfg \
+ src/pygambit/catalog_game_files/csg2.nfg \
+ src/pygambit/catalog_game_files/csg3.nfg \
+ src/pygambit/catalog_game_files/csg4.nfg \
+ src/pygambit/catalog_game_files/deg1.nfg \
+ src/pygambit/catalog_game_files/deg2.nfg \
+ src/pygambit/catalog_game_files/e01.efg \
+ src/pygambit/catalog_game_files/e01.nfg \
+ src/pygambit/catalog_game_files/e02.efg \
+ src/pygambit/catalog_game_files/e02.nfg \
+ src/pygambit/catalog_game_files/e03.efg \
+ src/pygambit/catalog_game_files/e04.efg \
+ src/pygambit/catalog_game_files/e04.nfg \
+ src/pygambit/catalog_game_files/e05.efg \
+ src/pygambit/catalog_game_files/e06.efg \
+ src/pygambit/catalog_game_files/e07.efg \
+ src/pygambit/catalog_game_files/e07.nfg \
+ src/pygambit/catalog_game_files/e08.efg \
+ src/pygambit/catalog_game_files/e09.efg \
+ src/pygambit/catalog_game_files/e10.efg \
+ src/pygambit/catalog_game_files/e10a.efg \
+ src/pygambit/catalog_game_files/e13.efg \
+ src/pygambit/catalog_game_files/e16.efg \
+ src/pygambit/catalog_game_files/e17.efg \
+ src/pygambit/catalog_game_files/e18.efg \
+ src/pygambit/catalog_game_files/g1.efg \
+ src/pygambit/catalog_game_files/g1.nfg \
+ src/pygambit/catalog_game_files/g2.efg \
+ src/pygambit/catalog_game_files/g2.nfg \
+ src/pygambit/catalog_game_files/g3.efg \
+ src/pygambit/catalog_game_files/g3.nfg \
+ src/pygambit/catalog_game_files/holdout.efg \
+ src/pygambit/catalog_game_files/holdout7.efg \
+ src/pygambit/catalog_game_files/hs1.efg \
+ src/pygambit/catalog_game_files/jury_mr.efg \
+ src/pygambit/catalog_game_files/jury_un.efg \
+ src/pygambit/catalog_game_files/km1.efg \
+ src/pygambit/catalog_game_files/km2.efg \
+ src/pygambit/catalog_game_files/km3.efg \
+ src/pygambit/catalog_game_files/km6.efg \
+ src/pygambit/catalog_game_files/loopback.nfg \
+ src/pygambit/catalog_game_files/mixdom.nfg \
+ src/pygambit/catalog_game_files/mixdom2.nfg \
+ src/pygambit/catalog_game_files/montyhal.efg \
+ src/pygambit/catalog_game_files/my_2-1.efg \
+ src/pygambit/catalog_game_files/my_2-4.efg \
+ src/pygambit/catalog_game_files/my_2-8.efg \
+ src/pygambit/catalog_game_files/my_3-3a.efg \
+ src/pygambit/catalog_game_files/my_3-3b.efg \
+ src/pygambit/catalog_game_files/my_3-3c.efg \
+ src/pygambit/catalog_game_files/my_3-3d.efg \
+ src/pygambit/catalog_game_files/my_3-3e.efg \
+ src/pygambit/catalog_game_files/my_3-4.efg \
+ src/pygambit/catalog_game_files/myerson.efg \
+ src/pygambit/catalog_game_files/myerson_fig_4_2.efg \
+ src/pygambit/catalog_game_files/nim.efg \
+ src/pygambit/catalog_game_files/nim7.efg \
+ src/pygambit/catalog_game_files/oneill.nfg \
+ src/pygambit/catalog_game_files/palf.efg \
+ src/pygambit/catalog_game_files/palf2.efg \
+ src/pygambit/catalog_game_files/palf3.efg \
+ src/pygambit/catalog_game_files/pbride.efg \
+ src/pygambit/catalog_game_files/pd.nfg \
+ src/pygambit/catalog_game_files/perfect1.nfg \
+ src/pygambit/catalog_game_files/perfect2.nfg \
+ src/pygambit/catalog_game_files/perfect3.nfg \
+ src/pygambit/catalog_game_files/poker.efg \
+ src/pygambit/catalog_game_files/poker.nfg \
+ src/pygambit/catalog_game_files/poker2.efg \
+ src/pygambit/catalog_game_files/pvw.efg \
+ src/pygambit/catalog_game_files/pvw2.efg \
+ src/pygambit/catalog_game_files/sh3.efg \
+ src/pygambit/catalog_game_files/sh3.nfg \
+ src/pygambit/catalog_game_files/spence.efg \
+ src/pygambit/catalog_game_files/stengel.nfg \
+ src/pygambit/catalog_game_files/sww1.efg \
+ src/pygambit/catalog_game_files/sww1.nfg \
+ src/pygambit/catalog_game_files/sww2.efg \
+ src/pygambit/catalog_game_files/sww3.efg \
+ src/pygambit/catalog_game_files/tim.efg \
+ src/pygambit/catalog_game_files/todd1.nfg \
+ src/pygambit/catalog_game_files/todd2.nfg \
+ src/pygambit/catalog_game_files/todd3.nfg \
+ src/pygambit/catalog_game_files/ttt.efg \
+ src/pygambit/catalog_game_files/vd.efg \
+ src/pygambit/catalog_game_files/vd.nfg \
+ src/pygambit/catalog_game_files/w_ex1.efg \
+ src/pygambit/catalog_game_files/w_ex2.efg \
+ src/pygambit/catalog_game_files/wilson1.efg \
+ src/pygambit/catalog_game_files/wink3.nfg \
+ src/pygambit/catalog_game_files/winkels.nfg \
+ src/pygambit/catalog_game_files/work1.efg \
+ src/pygambit/catalog_game_files/work2.efg \
+ src/pygambit/catalog_game_files/work3.efg \
+ src/pygambit/catalog_game_files/yamamoto.nfg \
+ src/pygambit/catalog_game_files/zero.nfg
core_SOURCES = \
src/core/core.h \
diff --git a/doc/catalog.rst b/doc/catalog.rst
new file mode 100644
index 000000000..c9e73ea3b
--- /dev/null
+++ b/doc/catalog.rst
@@ -0,0 +1,12 @@
+Catalog of games
+================
+
+.. raw:: html
+
+
+
+.. note::
+ If you are not redirected automatically, see
+ `Games Catalog `.
diff --git a/doc/developer.catalog.rst b/doc/developer.catalog.rst
new file mode 100644
index 000000000..264e3d37b
--- /dev/null
+++ b/doc/developer.catalog.rst
@@ -0,0 +1,184 @@
+.. _update-the-catlog:
+
+Updating the Games Catalog
+==========================
+
+This page covers the process for contributing to and updating Gambit's :ref:`Games Catalog `.
+To do so, you will need to have the `gambit` GitHub repo cloned and be able to submit pull request via GitHub;
+you may wish to first review the :ref:`contributor guidelines `.
+
+You can add games to the catalog saved in a valid representation :ref:`format `, e.g. for `.efg` for extensive form games.
+Alternatively, you can define games for the catalog in *pygambit* code.
+You may wish to first review the :ref:`pygambit ` docs pages.
+
+Both options for adding to the catalog below include an optional step for adding metadata to the catalog for your game(s).
+Adding metadata to games will create a new filter for the :func:`pygambit.catalog.games` that users can search the catalog with.
+
+.. dropdown:: Add game files to the catalog
+ :class-container: sd-border-0
+
+ 1. **Create the game file:**
+
+ Use either :ref:`pygambit `, the Gambit :ref:`CLI ` or :ref:`GUI ` to create and save game in a valid representation :ref:`format `.
+
+ 2. **Add the game file:**
+
+ Create a new branch in the `gambit` repo and commit the new game to `src/pygambit/catalog_game_files`
+
+ 3. **Update the catalog:**
+
+ Use the `catalog_update.py` script to update the catalog and associated documatation & build files.
+
+ .. code-block:: bash
+
+ pip install ruamel.yaml
+ cd src/pygambit
+ python catalog_update.py
+
+ .. note::
+ Run this script in a Python environment where `pygambit` itself is also :ref:`installed `
+
+ 4. **[Optional] Edit the catalog entry:**
+
+ Open `src/pygambit/catalog.yml` and find the new entry that was created in the previous step.
+ The entry will be named after the game file, but in camel case, with "Game" prefixed if the file started with a number.
+
+ If the game file doesn't already include a description ("comments" in older versions of Gambit) you should add a description field:
+
+ .. code-block:: yaml
+
+ MyGame:
+ file: my_game.nfg
+ description: "A game that... originally created by Author (2000)."
+
+ 5. **[Optional] Add custom metadata to catalog games:**
+
+ Open `src/pygambit/catalog.py` and add update the `CatalogGame` base class with the new metadata field.
+ Include a type hint, a default value and a docstring.
+
+ .. code-block:: python
+
+ # Metadata fields
+ my_metadata: int | None = None
+ """Explanation of my_metadata field."""
+
+ Open `src/pygambit/catalog.yml` and add the field under the `metadata` for the game you added, and any others that shouldn't have the default.
+
+ .. code-block:: yaml
+
+ MyGame:
+ file: my_game.efg
+ metadata:
+ my_metadata: 17
+
+ 6. **Submit a pull request to GitHub with all changes:**
+
+ .. warning::
+ If you made changes in step 4 or 5 above, re-run the update script from step 3.
+
+ .. warning::
+ Make sure you commit all changed files e.g. run `git add --all` before committing and pushing.
+
+.. dropdown:: Code games for the catalog
+ :class-container: sd-border-0
+
+ 1. **Write the pygambit code:**
+
+ Write code for your game with :ref:`pygambit `.
+ Your code should create a ``Game`` object with a title and description.
+
+ .. note::
+ Test your game by visualising it in `draw_tree` and running Gambit's solvers.
+
+ 2. **Create a new Python class for your game:**
+
+ Create a new branch in the `gambit` repo and open `src/pygambit/catalog_games.py`.
+ Add a subclass of `CatalogGame` with your code implemented as the `_game` function,
+ which should be defined as a `staticmethod` returning a ``Game`` object.
+ You can optionally include paramaters to generate game variants.
+
+ .. code-block:: python
+
+ class MyGame(gbt.catalog.CatalogGame):
+
+ @staticmethod
+ def _game(some_param: bool = False) -> gbt.Game:
+ """
+ Docstring for _game function.
+
+ Parameters
+ ----------
+ some_param : bool, optional
+ Description of optional paramater.
+ Defaults to False.
+
+ Returns
+ -------
+ gbt.Game
+ The constructed game.
+
+ Examples
+ --------
+ >>> MyGame(some_param=False) # Constructs the standard game
+ >>> MyGame(some_param=True) # Constructs the alternate game
+ """
+ g = gbt.Game.new_tree(
+ players=["Buyer", "Seller"], title="My game"
+ )
+ g.description = "Longer description of My game, originally by Author (2000)."
+ g.append_move(g.root, "Buyer", ["Trust", "Not trust"])
+ g.append_move(g.root.children[0], "Seller", ["Honor", "Abuse"])
+ g.set_outcome(g.root.children[0].children[0], g.add_outcome([1, 1], label="Trustworthy"))
+ if some_param:
+ g.set_outcome(
+ g.root.children[0].children[1], g.add_outcome(["1/2", 2], label="Untrustworthy")
+ )
+ else:
+ g.set_outcome(
+ g.root.children[0].children[1], g.add_outcome([-1, 2], label="Untrustworthy")
+ )
+ g.set_outcome(g.root.children[1], g.add_outcome([0, 0], label="Opt-out"))
+ return g
+
+ .. note::
+ If you add a docstring to the class itself, this will be used in the API reference docs as the game description instead of `g.description`
+
+ 3. **Update the catalog:**
+
+ Use the `catalog_update.py` script to update the catalog and associated documatation & build files.
+
+ .. code-block:: bash
+
+ pip install ruamel.yaml
+ cd src/pygambit
+ python catalog_update.py
+
+ .. note::
+ Run this script in a Python environment where `pygambit` itself is also :ref:`installed `
+
+ 4. **[Optional] Add custom metadata to catalog games:**
+
+ Open `src/pygambit/catalog.py` and add update the `CatalogGame` base class with the new metadata field.
+ Include a type hint, a default value and a docstring.
+
+ .. code-block:: python
+
+ # Metadata fields
+ my_metadata: int | None = None
+ """Explanation of my_metadata field."""
+
+ Open `src/pygambit/catalog_games.py` and add a value for the field as a class attribute for the game(s) you added.
+
+ .. code-block:: python
+
+ class MyGame(gbt.catalog.CatalogGame):
+ my_metadata = 17
+ ...
+
+ 6. **Submit a pull request to GitHub with all changes:**
+
+ .. warning::
+ If you made changes in step 4 above, re-run the update script from step 3.
+
+ .. warning::
+ Make sure you commit all changed files e.g. run `git add --all` before committing and pushing.
diff --git a/doc/developer.contributing.rst b/doc/developer.contributing.rst
index f86939850..02ca37747 100644
--- a/doc/developer.contributing.rst
+++ b/doc/developer.contributing.rst
@@ -1,3 +1,5 @@
+.. _contributing:
+
Contributing to Gambit
======================
diff --git a/doc/developer.rst b/doc/developer.rst
index 0a1512659..b954f0850 100644
--- a/doc/developer.rst
+++ b/doc/developer.rst
@@ -11,3 +11,4 @@ This section contains information for developers who want to contribute to the G
developer.build
developer.contributing
+ developer.catalog
diff --git a/doc/index.rst b/doc/index.rst
index 79076153a..50aa0bc7a 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -64,7 +64,7 @@ We recommended most new users install the PyGambit Python package and read the a
pygambit
tools
gui
- samples
+ catalog
developer
formats
biblio
diff --git a/doc/pygambit.api.rst b/doc/pygambit.api.rst
index ae029bae7..fc36aac62 100644
--- a/doc/pygambit.api.rst
+++ b/doc/pygambit.api.rst
@@ -95,7 +95,7 @@ Information about the game
:toctree: api/
Game.title
- Game.comment
+ Game.description
Game.is_const_sum
Game.is_tree
Game.is_perfect_recall
@@ -325,3 +325,161 @@ Computation of quantal response equilibria
logit_estimate
LogitQREMixedStrategyFitResult
LogitQREMixedBehaviorFitResult
+
+
+.. _pygambit-catalog:
+
+Catalog of games
+~~~~~~~~~~~~~~~~
+
+.. currentmodule:: pygambit.catalog
+
+.. autosummary::
+ :toctree: api/
+
+ games
+ Artist1
+ Artist2
+ Badgame1
+ Badgame2
+ Bagwell
+ Bayes1a
+ Bayes2a
+ Bcp2
+ Bcp3
+ Bcp4
+ Bhg1
+ Bhg2
+ Bhg3
+ Bhg4
+ Bhg5
+ Caro2
+ Cent2
+ Cent2NFG
+ Cent3
+ Cent4
+ Cent6
+ Centcs10
+ Centcs6
+ Condjury
+ Coord2
+ Coord2NFG
+ Coord2ts
+ Coord3
+ Coord333
+ Coord3NFG
+ Coord4
+ Coord4NFG
+ Cross
+ Cs
+ Csg1
+ Csg2
+ Csg3
+ Csg4
+ Deg1
+ Deg2
+ E01
+ E01NFG
+ E02
+ E02NFG
+ E03
+ E04
+ E04NFG
+ E05
+ E06
+ E07
+ E07NFG
+ E08
+ E09
+ E10
+ E10a
+ E13
+ E16
+ E17
+ E18
+ G1
+ G1NFG
+ G2
+ G2NFG
+ G3
+ G3NFG
+ Game2s2x2x2
+ Game2smp
+ Game2x2
+ Game2x2a
+ Game2x2const
+ Game2x2x2
+ Game2x2x2NFG
+ Game2x2x2_nau
+ Game2x2x2x2
+ Game2x2x2x2x2
+ Game3x3x3
+ Game4cards
+ Game5x4x3
+ Game8x2x2
+ Game8x8
+ Holdout
+ Hs1
+ Jury_mr
+ Jury_un
+ Km1
+ Km2
+ Km3
+ Km6
+ Loopback
+ Mixdom
+ Mixdom2
+ Montyhal
+ My_2_1
+ My_2_4
+ My_2_8
+ My_3_3a
+ My_3_3b
+ My_3_3c
+ My_3_3d
+ My_3_3e
+ My_3_4
+ Myerson
+ Myerson_fig_4_2
+ Nim
+ Nim7
+ OneShotTrust
+ Oneill
+ Palf
+ Palf2
+ Palf3
+ Pbride
+ Perfect1
+ Perfect2
+ Perfect3
+ Poker
+ Poker2
+ PokerNFG
+ PrisonersDilemma
+ Pvw
+ Pvw2
+ Sh3
+ Sh3NFG
+ Spence
+ Stengel
+ Sww1
+ Sww1NFG
+ Sww2
+ Sww3
+ Tim
+ Todd1
+ Todd2
+ Todd3
+ Ttt
+ Vd
+ VdNFG
+ W_ex1
+ W_ex2
+ Wilson1
+ Wink3
+ Winkels
+ Work1
+ Work2
+ Work3
+ Yamamoto
+ Zero
diff --git a/doc/tools.enummixed.rst b/doc/tools.enummixed.rst
index c3ad6df12..f57ffbbc8 100644
--- a/doc/tools.enummixed.rst
+++ b/doc/tools.enummixed.rst
@@ -64,7 +64,7 @@ points.
feature that has not been widely tested.
Computing the equilibria, in mixed strategies, of :download:`e02.nfg
-<../contrib/games/e02.nfg>`, the reduced strategic form of the example
+<../src/pygambit/catalog_game_files/e02.nfg>`, the reduced strategic form of the example
in Figure 2 of Selten (International Journal of Game Theory,
1975)
diff --git a/doc/tools.enumpoly.rst b/doc/tools.enumpoly.rst
index a04362e98..23875d684 100644
--- a/doc/tools.enumpoly.rst
+++ b/doc/tools.enumpoly.rst
@@ -92,7 +92,7 @@ support of some set of equilibria.
default, no information about supports is printed.
Computing equilibria of the strategic game :download:`e01.nfg
-<../contrib/games/e01.efg>`, the example in Figure 1 of Selten
+<../src/pygambit/catalog_game_files/e01.efg>`, the example in Figure 1 of Selten
(International Journal of Game Theory, 1975) sometimes called
"Selten's horse"
diff --git a/doc/tools.enumpure.rst b/doc/tools.enumpure.rst
index c653bc7bd..1a03109fe 100644
--- a/doc/tools.enumpure.rst
+++ b/doc/tools.enumpure.rst
@@ -53,7 +53,7 @@ pure-strategy Nash equilibria.
Computing the pure-strategy equilibria of extensive game :download:`e02.efg
-<../contrib/games/e02.efg>`, the example in Figure 2 of Selten
+<../src/pygambit/catalog_game_files/e02.efg>`, the example in Figure 2 of Selten
(International Journal of Game Theory, 1975)
$ gambit-enumpure e02.efg
diff --git a/doc/tools.gnm.rst b/doc/tools.gnm.rst
index 7bd63c3cc..b70c3beee 100644
--- a/doc/tools.gnm.rst
+++ b/doc/tools.gnm.rst
@@ -81,7 +81,7 @@ subsets of equilibria being found.
Show intermediate output of the algorithm. If this option is
not specified, only the equilibria found are reported.
-Computing an equilibrium of :download:`e02.nfg <../contrib/games/e02.nfg>`,
+Computing an equilibrium of :download:`e02.nfg <../src/pygambit/catalog_game_files/e02.nfg>`,
the reduced strategic form of the example in Figure 2 of Selten
(International Journal of Game Theory, 1975)
diff --git a/doc/tools.ipa.rst b/doc/tools.ipa.rst
index adac09b2f..2790a6a3f 100644
--- a/doc/tools.ipa.rst
+++ b/doc/tools.ipa.rst
@@ -48,7 +48,7 @@ equilibria being found.
output of equilibria (excluding the initial NE tag).
-Computing an equilibrium of :download:`e02.nfg <../contrib/games/e02.nfg>`,
+Computing an equilibrium of :download:`e02.nfg <../src/pygambit/catalog_game_files/e02.nfg>`,
the reduced strategic form of the example in Figure 2 of Selten
(International Journal of Game Theory, 1975)
diff --git a/doc/tools.lcp.rst b/doc/tools.lcp.rst
index 19b62d812..55e161f23 100644
--- a/doc/tools.lcp.rst
+++ b/doc/tools.lcp.rst
@@ -76,7 +76,7 @@ game.
Computing an equilibrium of extensive game :download:`e02.efg
-<../contrib/games/e02.efg>`, the example in Figure 2 of Selten
+<../src/pygambit/catalog_game_files/e02.efg>`, the example in Figure 2 of Selten
(International Journal of Game Theory, 1975)
$ gambit-lcp e02.efg
diff --git a/doc/tools.liap.rst b/doc/tools.liap.rst
index fdac11f51..10cab5043 100644
--- a/doc/tools.liap.rst
+++ b/doc/tools.liap.rst
@@ -96,7 +96,7 @@ not guaranteed to find all, or even any, Nash equilibria.
equilibria found.
Computing an equilibrium in mixed strategies of :download:`e02.efg
-<../contrib/games/e02.efg>`, the example in Figure 2 of Selten
+<../src/pygambit/catalog_game_files/e02.efg>`, the example in Figure 2 of Selten
(International Journal of Game Theory, 1975)
$ gambit-liap e02.nfg
diff --git a/doc/tools.logit.rst b/doc/tools.logit.rst
index 908cb201c..2f19a71b1 100644
--- a/doc/tools.logit.rst
+++ b/doc/tools.logit.rst
@@ -102,7 +102,7 @@ the beliefs at such information sets as being uniform across all member nodes.
equilibrium at the end of the branch is output.
Computing the principal branch, in mixed strategies, of :download:`e02.nfg
-<../contrib/games/e02.nfg>`, the reduced strategic form of the example
+<../src/pygambit/catalog_game_files/e02.nfg>`, the reduced strategic form of the example
in Figure 2 of Selten (International Journal of Game Theory,
1975)
diff --git a/doc/tools.lp.rst b/doc/tools.lp.rst
index f09e97663..e637cbaa9 100644
--- a/doc/tools.lp.rst
+++ b/doc/tools.lp.rst
@@ -53,7 +53,7 @@ points of that set.
Suppresses printing of the banner at program launch.
Computing an equilibrium of the game :download:`2x2const.nfg
-<../contrib/games/2x2const.nfg>`, a game with two players with two
+<../src/pygambit/catalog_game_files/2x2const.nfg>`, a game with two players with two
strategies each, with a unique equilibrium in mixed strategies
$ gambit-lp 2x2const.nfg
diff --git a/doc/tools.simpdiv.rst b/doc/tools.simpdiv.rst
index ccebe633c..8c65c6810 100644
--- a/doc/tools.simpdiv.rst
+++ b/doc/tools.simpdiv.rst
@@ -87,7 +87,7 @@ options to specify additional starting points for the algorithm.
Computing an equilibrium in mixed strategies of :download:`e02.efg
-<../contrib/games/e02.efg>`, the example in Figure 2 of Selten
+<../src/pygambit/catalog_game_files/e02.efg>`, the example in Figure 2 of Selten
(International Journal of Game Theory, 1975)
$ gambit-simpdiv e02.nfg
diff --git a/doc/tutorials/01_quickstart.ipynb b/doc/tutorials/01_quickstart.ipynb
index 06ec6f91e..23e07731c 100644
--- a/doc/tutorials/01_quickstart.ipynb
+++ b/doc/tutorials/01_quickstart.ipynb
@@ -38,7 +38,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 1,
"id": "c58d382d",
"metadata": {},
"outputs": [],
@@ -50,7 +50,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 2,
"id": "2060c1ed",
"metadata": {},
"outputs": [
@@ -60,7 +60,7 @@
"pygambit.gambit.Game"
]
},
- "execution_count": 1,
+ "execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
@@ -83,7 +83,7 @@
},
{
"cell_type": "code",
- "execution_count": 2,
+ "execution_count": 3,
"id": "9d8203e8",
"metadata": {},
"outputs": [],
@@ -111,7 +111,7 @@
},
{
"cell_type": "code",
- "execution_count": 3,
+ "execution_count": 4,
"id": "61030607",
"metadata": {},
"outputs": [],
@@ -135,7 +135,7 @@
},
{
"cell_type": "code",
- "execution_count": 4,
+ "execution_count": 5,
"id": "caecc334",
"metadata": {},
"outputs": [
@@ -149,7 +149,7 @@
"Game(title='Prisoner's Dilemma')"
]
},
- "execution_count": 4,
+ "execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
@@ -189,7 +189,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 6,
"id": "843ba7f3",
"metadata": {},
"outputs": [
@@ -203,7 +203,7 @@
"Game(title='Another Prisoner's Dilemma')"
]
},
- "execution_count": 5,
+ "execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
@@ -233,7 +233,7 @@
},
{
"cell_type": "code",
- "execution_count": 6,
+ "execution_count": 7,
"id": "5ee752c4",
"metadata": {},
"outputs": [
@@ -270,7 +270,7 @@
},
{
"cell_type": "code",
- "execution_count": 7,
+ "execution_count": 8,
"id": "a81c06c7",
"metadata": {},
"outputs": [
@@ -280,7 +280,7 @@
"pygambit.nash.NashComputationResult"
]
},
- "execution_count": 7,
+ "execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
@@ -300,7 +300,7 @@
},
{
"cell_type": "code",
- "execution_count": 8,
+ "execution_count": 9,
"id": "bd395180",
"metadata": {},
"outputs": [
@@ -310,7 +310,7 @@
"1"
]
},
- "execution_count": 8,
+ "execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
@@ -329,7 +329,7 @@
},
{
"cell_type": "code",
- "execution_count": 9,
+ "execution_count": 10,
"id": "76570ebc",
"metadata": {},
"outputs": [
@@ -342,7 +342,7 @@
"[[Rational(0, 1), Rational(1, 1)], [Rational(0, 1), Rational(1, 1)]]"
]
},
- "execution_count": 9,
+ "execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
@@ -354,7 +354,7 @@
},
{
"cell_type": "code",
- "execution_count": 10,
+ "execution_count": 11,
"id": "6e8cfcde",
"metadata": {},
"outputs": [
@@ -364,7 +364,7 @@
"pygambit.gambit.MixedStrategyProfileRational"
]
},
- "execution_count": 10,
+ "execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
@@ -385,7 +385,7 @@
},
{
"cell_type": "code",
- "execution_count": 11,
+ "execution_count": 12,
"id": "980bf6b1",
"metadata": {},
"outputs": [
@@ -417,11 +417,89 @@
},
{
"cell_type": "markdown",
- "id": "24f36b0d",
+ "id": "15ab8d84",
"metadata": {},
"source": [
"The equilibrium shows that both players are playing their dominant strategy, which is to defect. This is because defecting is the best response to the other player's strategy, regardless of what that strategy is.\n",
"\n",
+ "Loading games from the catalog\n",
+ "------------------------------\n",
+ "\n",
+ "Gambit includes a catalog of standard games that can be loaded directly by name.\n",
+ "You can list all the available games and filtering on the game type and number of players in the catalog like so:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "id": "701aa52a",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['Coord2NFG',\n",
+ " 'Game2x2',\n",
+ " 'Game2x2a',\n",
+ " 'Game2x2const',\n",
+ " 'Loopback',\n",
+ " 'PrisonersDilemma',\n",
+ " 'Sww1NFG',\n",
+ " 'Zero']"
+ ]
+ },
+ "execution_count": 13,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "gbt.catalog.games(\n",
+ " is_tree=False,\n",
+ " num_strategies=4,\n",
+ " num_players=2\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "a919ddf7",
+ "metadata": {},
+ "source": [
+ "You can then load a specific game by its name. For example, to load the \"Prisoner's Dilemma\" game from the catalog, you would do the following:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 14,
+ "id": "6db7a29a",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "Two person Prisoner's Dilemma game
\n",
+ "\n"
+ ],
+ "text/plain": [
+ "Game(title='Two person Prisoner's Dilemma game')"
+ ]
+ },
+ "execution_count": 14,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "g = gbt.catalog.PrisonersDilemma()\n",
+ "g"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "24f36b0d",
+ "metadata": {},
+ "source": [
"Saving and reading strategic form games to and from file\n",
"--------------------\n",
"\n",
@@ -433,7 +511,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 15,
"id": "f58eaa77",
"metadata": {},
"outputs": [],
@@ -451,23 +529,12 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 16,
"id": "4119a2ac",
"metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "pygambit.gambit.Game"
- ]
- },
- "execution_count": 13,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
+ "outputs": [],
"source": [
- "# gbt.read_nfg(\"test_games/prisoners_dilemma.nfg\")"
+ "# gbt.read_nfg(\"prisoners_dilemma.nfg\")"
]
}
],
diff --git a/doc/tutorials/02_extensive_form.ipynb b/doc/tutorials/02_extensive_form.ipynb
index 528970c61..ce84fe0f3 100644
--- a/doc/tutorials/02_extensive_form.ipynb
+++ b/doc/tutorials/02_extensive_form.ipynb
@@ -31,7 +31,7 @@
},
{
"cell_type": "code",
- "execution_count": 1,
+ "execution_count": 22,
"id": "5946289b",
"metadata": {},
"outputs": [],
@@ -51,7 +51,7 @@
},
{
"cell_type": "code",
- "execution_count": 2,
+ "execution_count": 23,
"id": "91ed4dfb",
"metadata": {},
"outputs": [],
@@ -72,27 +72,27 @@
},
{
"cell_type": "code",
- "execution_count": 3,
+ "execution_count": 24,
"id": "3cd94917",
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
- "