Skip to content

Commit 7af604c

Browse files
Merge branch 'master' into fix/542
2 parents 4fcd208 + f6cdb55 commit 7af604c

18 files changed

Lines changed: 484 additions & 104 deletions

.all-contributorsrc

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,69 @@
11
{
22
"projectName": "gambit",
3-
"projectOwner": "gambitproject"
4-
}
3+
"projectOwner": "gambitproject",
4+
"files": [
5+
"README.md"
6+
],
7+
"commitType": "docs",
8+
"commitConvention": "angular",
9+
"contributorsPerLine": 7,
10+
"contributors": [
11+
{
12+
"login": "tturocy",
13+
"name": "Ted Turocy",
14+
"avatar_url": "https://avatars.githubusercontent.com/u/180959?v=4",
15+
"profile": "https://github.com/tturocy",
16+
"contributions": [
17+
"code",
18+
"doc",
19+
"research",
20+
"maintenance",
21+
"ideas"
22+
]
23+
},
24+
{
25+
"login": "rahulsavani",
26+
"name": "Rahul Savani",
27+
"avatar_url": "https://avatars.githubusercontent.com/u/743139?v=4",
28+
"profile": "http://www.csc.liv.ac.uk/~rahul",
29+
"contributions": [
30+
"code",
31+
"doc",
32+
"research",
33+
"maintenance",
34+
"ideas"
35+
]
36+
},
37+
{
38+
"login": "edwardchalstrey1",
39+
"name": "Ed Chalstrey",
40+
"avatar_url": "https://avatars.githubusercontent.com/u/5486164?v=4",
41+
"profile": "https://edchalstrey.com/",
42+
"contributions": [
43+
"code",
44+
"doc",
45+
"tutorial"
46+
]
47+
},
48+
{
49+
"login": "StephenPasteris",
50+
"name": "StephenPasteris",
51+
"avatar_url": "https://avatars.githubusercontent.com/u/140617768?v=4",
52+
"profile": "https://github.com/StephenPasteris",
53+
"contributions": [
54+
"research",
55+
"code"
56+
]
57+
},
58+
{
59+
"login": "d-kad",
60+
"name": "Daniel Kadnikov",
61+
"avatar_url": "https://avatars.githubusercontent.com/u/165307096?v=4",
62+
"profile": "https://github.com/d-kad",
63+
"contributions": [
64+
"research",
65+
"code"
66+
]
67+
}
68+
]
69+
}

ChangeLog

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
### Changed
66
- In the graphical interface, removed option to configure information set link drawing; information sets
77
are always drawn and indicators are always drawn if an information set spans multiple levels.
8+
- In `pygambit`, indexing the children of a node by a string inteprets the string as an action label,
9+
not a label of a child node. In addition, indexing by an action object is now supported. (#587)
810

911
### Added
1012
- Tests for EFG Nash solvers -- `enumpoly_solve`, `lp_solve`, `lcp_solve` -- in behavior stratgegies

Makefile.am

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,9 @@ agg_SOURCES = \
285285

286286
game_SOURCES = \
287287
src/gambit.h \
288+
src/games/gameseq.cc \
289+
src/games/gameseq.h \
290+
src/games/ndarray.h \
288291
src/games/number.h \
289292
src/games/gameobject.h \
290293
src/games/game.cc \
@@ -398,9 +401,6 @@ gambit_nashsupport_SOURCES = \
398401

399402
gambit_enumpoly_SOURCES = \
400403
${core_SOURCES} ${game_SOURCES} ${gambit_nashsupport_SOURCES} \
401-
src/solvers/enumpoly/ndarray.h \
402-
src/solvers/enumpoly/gameseq.cc \
403-
src/solvers/enumpoly/gameseq.h \
404404
src/solvers/enumpoly/indexproduct.h \
405405
src/solvers/enumpoly/rectangle.h \
406406
src/solvers/enumpoly/poly.cc \

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,19 @@ installable via PyPI.
4141
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
4242
<!-- prettier-ignore-start -->
4343
<!-- markdownlint-disable -->
44+
<table>
45+
<tbody>
46+
<tr>
47+
<td align="center" valign="top" width="14.28%"><a href="https://github.com/tturocy"><img src="https://avatars.githubusercontent.com/u/180959?v=4?s=100" width="100px;" alt="Ted Turocy"/><br /><sub><b>Ted Turocy</b></sub></a><br /><a href="#code-tturocy" title="Code">💻</a> <a href="#doc-tturocy" title="Documentation">📖</a> <a href="#research-tturocy" title="Research">🔬</a> <a href="#maintenance-tturocy" title="Maintenance">🚧</a> <a href="#ideas-tturocy" title="Ideas, Planning, & Feedback">🤔</a></td>
48+
<td align="center" valign="top" width="14.28%"><a href="http://www.csc.liv.ac.uk/~rahul"><img src="https://avatars.githubusercontent.com/u/743139?v=4?s=100" width="100px;" alt="Rahul Savani"/><br /><sub><b>Rahul Savani</b></sub></a><br /><a href="#code-rahulsavani" title="Code">💻</a> <a href="#doc-rahulsavani" title="Documentation">📖</a> <a href="#research-rahulsavani" title="Research">🔬</a> <a href="#maintenance-rahulsavani" title="Maintenance">🚧</a> <a href="#ideas-rahulsavani" title="Ideas, Planning, & Feedback">🤔</a></td>
49+
</tr>
50+
<tr>
51+
<td align="center" valign="top" width="14.28%"><a href="https://edchalstrey.com/"><img src="https://avatars.githubusercontent.com/u/5486164?v=4?s=100" width="100px;" alt="Ed Chalstrey"/><br /><sub><b>Ed Chalstrey</b></sub></a><br /><a href="#code-edwardchalstrey1" title="Code">💻</a> <a href="#doc-edwardchalstrey1" title="Documentation">📖</a> <a href="#tutorial-edwardchalstrey1" title="Tutorials">✅</a></td>
52+
<td align="center" valign="top" width="14.28%"><a href="https://github.com/d-kad"><img src="https://avatars.githubusercontent.com/u/165307096?v=4?s=100" width="100px;" alt="Daniel "/><br /><sub><b>Daniel </b></sub></a><br /><a href="#research-d-kad" title="Research">🔬</a> <a href="#code-d-kad" title="Code">💻</a></td>
53+
<td align="center" valign="top" width="14.28%"><a href="https://github.com/StephenPasteris"><img src="https://avatars.githubusercontent.com/u/140617768?v=4?s=100" width="100px;" alt="StephenPasteris"/><br /><sub><b>StephenPasteris</b></sub></a><br /><a href="#research-StephenPasteris" title="Research">🔬</a> <a href="#code-StephenPasteris" title="Code">💻</a></td>
54+
</tr>
55+
</tbody>
56+
</table>
4457

4558
<!-- markdownlint-restore -->
4659
<!-- prettier-ignore-end -->

doc/developer.build.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -181,15 +181,15 @@ Building the Python extension
181181

182182
The :ref:`pygambit Python package <pygambit>` is in ``src/pygambit``
183183
in the Gambit source tree. We recommend to install `pygambit`
184-
as part of a virtual environment rather than in the system's Python.
185-
Use `pip` to install from the **root directory of the source tree**, optionally including the `-e` flag for an editable install:
184+
as part of a virtual environment rather than in the system's Python (for example using `venv`).
185+
Use `pip` to install from the **root directory of the source tree**:
186186

187187
.. code-block:: bash
188188
189+
python -m venv venv
190+
source venv/bin/activate
189191
python -m pip install .
190192
191-
There is a set of test cases in `src/pygambit/tests`, which can be run
192-
using `pytest`.
193193
194194
Once installed, simply ``import pygambit`` in your Python shell or
195195
script to get started.

doc/developer.contributing.rst

Lines changed: 52 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -45,50 +45,82 @@ version.
4545
git clone https://github.com/gambitproject/gambit.git # or your fork URL
4646
cd gambit
4747

48-
3. Create a new branch for your changes ::
48+
3. Follow the instructions in the :ref:`building-from-source` page to set up your development environment and build Gambit from source. If you only plan to make changes to the PyGambit Python code, you can skip to :ref:`build-python`.
49+
50+
4. Create a new branch for your changes ::
4951

5052
git checkout -b feature/your-feature-name
5153

52-
4. Make your changes. Commit each change with a clear commit message ::
54+
5. Make your changes. Commit each change with a clear commit message ::
5355

5456
git add .
5557
git commit -m "Add feature X or fix bug Y"
5658

57-
5. Push your changes to your fork or branch ::
59+
6. Push your changes to your fork or branch ::
5860

5961
git push origin feature/your-feature-name
6062

61-
6. Open a pull request on GitHub to the master branch of the upstream repository, describing your changes and linking to any relevant issues.
62-
7. Core developers will review your changes, provide feedback, and merge them into the master branch if they meet the project's standards.
63+
7. Open a pull request on GitHub to the master branch of the upstream repository, describing your changes and linking to any relevant issues.
64+
8. Core developers will review your changes, provide feedback, and merge them into the master branch if they meet the project's standards.
65+
66+
Testing your changes
67+
--------------------
68+
69+
Be sure to familiarise yourself with :ref:`contributing-code` before reading this section.
70+
71+
By default, pull requests on GitHub will trigger the running of Gambit's test suite using GitHub Actions.
72+
You can also run the tests locally before submitting your pull request, using `pytest`.
73+
74+
1. Install the test dependencies (into the virtual environment where you installed PyGambit): ::
75+
76+
pip install -r tests/requirements.txt
77+
78+
2. Navigate to the Gambit repository and run the tests: ::
79+
80+
pytest
81+
82+
Adding to the test suite
83+
^^^^^^^^^^^^^^^^^^^^^^^^
84+
85+
Tests can be added to the test suite by creating new test files in the ``tests`` directory.
86+
Tests should be written using the `pytest` framework.
87+
Refer to existing test files for examples of how to write tests or see the `pytest documentation <https://docs.pytest.org/en/stable/>`_ for more information.
88+
6389

6490
Editing this documentation
65-
--------------------------
91+
---------------------------
6692

67-
1. `Install Pandoc <https://pandoc.org/installing.html>`_ for your OS
93+
Be sure to familiarise yourself with :ref:`contributing-code` before reading this section.
6894

69-
2. If you haven't already, clone the Gambit repository from GitHub: ::
95+
You can make changes to the documentation by editing the `.rst` files in the ``doc`` directory.
96+
Creating a pull request with your changes will automatically trigger a build of the documentation via the ReadTheDocs service, which can be viewed online.
97+
You can also build the documentation locally to preview your changes before submitting a pull request.
7098

71-
git clone https://github.com/gambitproject/gambit.git
72-
cd gambit
99+
1. `Install Pandoc <https://pandoc.org/installing.html>`_ for your OS
73100

74-
3. Either install the docs requirements into your existing PyGambit development environment, or create a new virtual environment and install both the requirements and PyGambit there. For example, you can use `venv` to create a new environment: ::
101+
2. Install the docs dependencies (into the virtual environment where you installed PyGambit): ::
75102

76-
python -m venv docenv
77-
source docenv/bin/activate
103+
pip install -r doc/requirements.txt
78104

79-
4. Install the requirements and make the docs: ::
105+
3. Navigate to the Gambit repo and build the docs: ::
80106

81-
pip install .
82107
cd doc
83-
pip install -r requirements.txt
84108
make html # or make livehtml for live server with auto-rebuild
85109

86-
5. Open ``doc/_build/html/index.html`` in your browser to view the documentation.
110+
4. Open ``doc/_build/html/index.html`` in your browser to view the documentation.
111+
112+
113+
114+
115+
Recognising contributions
116+
-------------------------
87117

88-
6. Make any changes you want to the `.rst` files in the ``doc`` directory and rebuild the documentation to check your changes.
118+
Gambit is set up with `All Contributors <https://allcontributors.org/>`__ to recognise all types of contributions, including code, documentation, bug reports, and more.
89119

90-
7. Follow the usual GitHub workflow (see :ref:`contributing-code` above) to commit your changes and push them to the repository.
120+
You can see the list of contributors on the README page of the `Gambit GitHub repo <https://github.com/gambitproject/gambit>`__.
91121

92-
8. Core developers will review your changes and merge to the master branch, which automatically deploys the documentation via the ReadTheDocs service.
122+
To add a contributor, comment on a GitHub Issue or Pull Request, asking @all-contributors to add a contributor:
93123

124+
@all-contributors please add @<username> for <contributions>
94125

126+
Refer to the `emoji key <https://allcontributors.org/docs/en/emoji-key>`__ for a list of contribution types.

src/games/behavspt.cc

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
//
2222

2323
#include "gambit.h"
24+
#include "gameseq.h"
2425

2526
namespace Gambit {
2627

@@ -259,4 +260,55 @@ std::list<GameNode> BehaviorSupportProfile::GetMembers(const GameInfoset &p_info
259260
return answer;
260261
}
261262

263+
//========================================================================
264+
// BehaviorSupportProfile: Sequence form
265+
//========================================================================
266+
267+
std::shared_ptr<GameSequenceForm> BehaviorSupportProfile::GetSequenceForm() const
268+
{
269+
if (!m_sequenceForm) {
270+
m_sequenceForm = std::make_shared<GameSequenceForm>(*this);
271+
}
272+
return m_sequenceForm;
273+
}
274+
275+
SequencesWrapper BehaviorSupportProfile::GetSequences() const
276+
{
277+
return SequencesWrapper(GetSequenceForm()->GetSequences());
278+
}
279+
280+
PlayerSequencesWrapper BehaviorSupportProfile::GetSequences(GamePlayer &p_player) const
281+
{
282+
return PlayerSequencesWrapper(GetSequenceForm()->GetSequences(p_player));
283+
}
284+
285+
int BehaviorSupportProfile::GetConstraintEntry(const GameInfoset &p_infoset,
286+
const GameAction &p_action) const
287+
{
288+
return GetSequenceForm()->GetConstraintEntry(p_infoset, p_action);
289+
}
290+
291+
const Rational &BehaviorSupportProfile::GetPayoff(
292+
const std::map<GamePlayer, std::shared_ptr<GameSequenceRep>> &p_profile,
293+
const GamePlayer &p_player) const
294+
{
295+
return GetSequenceForm()->GetPayoff(p_profile, p_player);
296+
}
297+
298+
MixedBehaviorProfile<double> BehaviorSupportProfile::ToMixedBehaviorProfile(
299+
const std::map<std::shared_ptr<GameSequenceRep>, double> &p_profile) const
300+
{
301+
return GetSequenceForm()->ToMixedBehaviorProfile(p_profile);
302+
}
303+
304+
InfosetsWrapper BehaviorSupportProfile::GetInfosets() const
305+
{
306+
return InfosetsWrapper(GetSequenceForm()->GetInfosets());
307+
}
308+
309+
ContingenciesWrapper BehaviorSupportProfile::GetContingencies() const
310+
{
311+
return ContingenciesWrapper(GetSequenceForm()->GetContingencies());
312+
}
313+
262314
} // end namespace Gambit

src/games/behavspt.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,13 @@
2929

3030
namespace Gambit {
3131

32+
class GameSequenceForm;
33+
class GameSequenceRep;
34+
class SequencesWrapper;
35+
class PlayerSequencesWrapper;
36+
class InfosetsWrapper;
37+
class ContingenciesWrapper;
38+
3239
/// This class represents a subset of the actions in an extensive game.
3340
/// It is enforced that each player has at least one action at each
3441
/// information set; thus, the actions in a support can be viewed as
@@ -139,6 +146,20 @@ class BehaviorSupportProfile {
139146
/// Returns a copy of the support with dominated actions eliminated
140147
BehaviorSupportProfile Undominated(bool p_strict) const;
141148
//@}
149+
150+
mutable std::shared_ptr<GameSequenceForm> m_sequenceForm;
151+
std::shared_ptr<GameSequenceForm> GetSequenceForm() const;
152+
SequencesWrapper GetSequences() const;
153+
PlayerSequencesWrapper GetSequences(GamePlayer &p_player) const;
154+
int GetConstraintEntry(const GameInfoset &p_infoset, const GameAction &p_action) const;
155+
const Rational &
156+
GetPayoff(const std::map<GamePlayer, std::shared_ptr<GameSequenceRep>> &p_profile,
157+
const GamePlayer &p_player) const;
158+
GameRep::Players GetPlayers() const { return GetGame()->GetPlayers(); }
159+
MixedBehaviorProfile<double>
160+
ToMixedBehaviorProfile(const std::map<std::shared_ptr<GameSequenceRep>, double> &) const;
161+
InfosetsWrapper GetInfosets() const;
162+
ContingenciesWrapper GetContingencies() const;
142163
};
143164

144165
} // end namespace Gambit

src/games/game.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ class UndefinedException final : public std::runtime_error {
8282
class MismatchException : public std::runtime_error {
8383
public:
8484
MismatchException() : std::runtime_error("Operation between objects in different games") {}
85+
explicit MismatchException(const std::string &s) : std::runtime_error(s) {}
8586
~MismatchException() noexcept override = default;
8687
};
8788

@@ -444,7 +445,7 @@ class GameNodeRep : public std::enable_shared_from_this<GameNodeRep> {
444445
GameNode GetChild(const GameAction &p_action)
445446
{
446447
if (p_action->GetInfoset().get() != m_infoset) {
447-
throw MismatchException();
448+
throw MismatchException("Action is from a different information set than node");
448449
}
449450
return m_children.at(p_action->GetNumber() - 1);
450451
}

0 commit comments

Comments
 (0)