Skip to content

Commit 666ad00

Browse files
authored
Raise UndefinedOperationError for game.player.{actions,infosets,nodes} on non-trees (#701)
1 parent 78ca12f commit 666ad00

File tree

3 files changed

+58
-2
lines changed

3 files changed

+58
-2
lines changed

src/pygambit/game.pxi

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -745,7 +745,16 @@ class Game:
745745
.. versionchanged:: 16.4
746746
Changed from a method ``nodes()`` to a property.
747747

748+
Raises
749+
------
750+
UndefinedOperationError
751+
If the game does not have a tree representation.
748752
"""
753+
if not self.is_tree:
754+
raise UndefinedOperationError(
755+
"Operation only defined for games with a tree representation"
756+
)
757+
749758
return GameNodes.wrap(self.game)
750759

751760
@property
@@ -1888,11 +1897,20 @@ class Game:
18881897

18891898
.. versionadded:: 16.4.0
18901899

1900+
Raises
1901+
------
1902+
UndefinedOperationError
1903+
If the game does not have a tree representation.
1904+
18911905
See also
18921906
--------
18931907
Player.infosets
18941908
Infoset.members
18951909
"""
1910+
if not self.is_tree:
1911+
raise UndefinedOperationError(
1912+
"Operation only defined for games with a tree representation"
1913+
)
18961914
self.game.deref().SortInfosets()
18971915

18981916
def add_player(self, label: str = "") -> Player:

src/pygambit/player.pxi

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,15 +228,34 @@ class Player:
228228
previously, information sets were (expensively) re-sorted after every change
229229
to the game tree.
230230

231+
Raises
232+
------
233+
UndefinedOperationError
234+
If the game does not have a tree representation.
235+
231236
See also
232237
--------
233238
Game.sort_infosets
234239
"""
240+
if not self.game.is_tree:
241+
raise UndefinedOperationError(
242+
"Operation only defined for games with a tree representation"
243+
)
235244
return PlayerInfosets.wrap(self.player)
236245

237246
@property
238247
def actions(self) -> PlayerActions:
239-
"""Returns the set of actions available to the player at some information set."""
248+
"""Returns the set of actions available to the player at some information set.
249+
250+
Raises
251+
------
252+
UndefinedOperationError
253+
If the game does not have a tree representation.
254+
"""
255+
if not self.game.is_tree:
256+
raise UndefinedOperationError(
257+
"Operation only defined for games with a tree representation"
258+
)
240259
return PlayerActions.wrap(self)
241260

242261
@property

tests/test_strategic.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,24 @@ def test_strategic_game_actions():
1111
_ = game.actions
1212

1313

14+
def test_strategic_game_player_actions():
15+
game = gbt.Game.new_table([2, 2])
16+
with pytest.raises(gbt.UndefinedOperationError):
17+
_ = game.players[0].actions
18+
19+
1420
def test_strategic_game_infosets():
1521
game = gbt.Game.new_table([2, 2])
1622
with pytest.raises(gbt.UndefinedOperationError):
1723
_ = game.infosets
1824

1925

26+
def test_strategic_game_player_infosets():
27+
game = gbt.Game.new_table([2, 2])
28+
with pytest.raises(gbt.UndefinedOperationError):
29+
_ = game.players[0].infosets
30+
31+
2032
def test_strategic_game_root():
2133
game = gbt.Game.new_table([2, 2])
2234
with pytest.raises(gbt.UndefinedOperationError):
@@ -25,7 +37,14 @@ def test_strategic_game_root():
2537

2638
def test_strategic_game_nodes():
2739
game = gbt.Game.new_table([2, 2])
28-
assert list(game.nodes) == []
40+
with pytest.raises(gbt.UndefinedOperationError):
41+
_ = game.nodes
42+
43+
44+
def test_strategic_game_sort_infosets():
45+
game = gbt.Game.new_table([2, 2])
46+
with pytest.raises(gbt.UndefinedOperationError):
47+
_ = game.sort_infosets()
2948

3049

3150
def test_game_behav_profile_error():

0 commit comments

Comments
 (0)