Skip to content

Commit d9ec124

Browse files
committed
allow string input for expected payoff tables in test_rsf
1 parent c7a6477 commit d9ec124

2 files changed

Lines changed: 85 additions & 6 deletions

File tree

tests/games.py

Lines changed: 79 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
11
"""A utility module to create/load games for the test suite."""
22
import pathlib
33

4+
import numpy as np
5+
46
import pygambit as gbt
57

68

79
def read_from_file(fn: str) -> gbt.Game:
810
if fn.endswith(".efg"):
9-
return gbt.read_efg(pathlib.Path("tests/test_games")/fn)
11+
return gbt.read_efg(pathlib.Path("tests/test_games") / fn)
1012
elif fn.endswith(".nfg"):
11-
return gbt.read_nfg(pathlib.Path("tests/test_games")/fn)
13+
return gbt.read_nfg(pathlib.Path("tests/test_games") / fn)
1214
else:
1315
raise ValueError(f"Unknown file extension in {fn}")
1416

1517

1618
################################################################################################
1719
# Normal-form (aka strategic-form) games (nfg)
1820

21+
1922
def create_2x2_zero_nfg() -> gbt.Game:
2023
"""
2124
Returns
@@ -73,6 +76,7 @@ def create_coord_4x4_nfg(outcome_version: bool = False) -> gbt.Game:
7376
################################################################################################
7477
# Extensive-form games (efg)
7578

79+
7680
def create_mixed_behav_game_efg() -> gbt.Game:
7781
"""
7882
Returns
@@ -124,3 +128,76 @@ def create_selten_horse_game_efg() -> gbt.Game:
124128
5-player Selten's Horse Game
125129
"""
126130
return read_from_file("e01.efg")
131+
132+
133+
def create_reduction_generic_payoffs_efg() -> gbt.Game:
134+
# tree with only root
135+
g = gbt.Game.new_tree(players=["1", "2"], title="TEST")
136+
137+
# add four children
138+
g.append_move(g.root, "2", ["a", "b", "c", "d"])
139+
140+
# add L and R after a
141+
g.append_move(g.root.children[0], "1", ["L", "R"])
142+
143+
# add C and D to single infoset after b and c
144+
nodes = [g.root.children[1], g.root.children[2]]
145+
g.append_move(nodes, "1", ["C", "D"])
146+
147+
# add s and t from single infoset after rightmost C and D
148+
g.append_move(g.root.children[2].children, "2", ["s", "t"])
149+
150+
# add p and q
151+
g.append_move(g.root.children[0].children[1], "2", ["p", "q"])
152+
153+
# add U and V in a single infoset after p and q
154+
g.append_move(g.root.children[0].children[1].children, "1", ["U", "V"])
155+
156+
# Set outcomes
157+
158+
g.set_outcome(g.root.children[0].children[0], g.add_outcome([1, -1], label="aL"))
159+
g.set_outcome(
160+
g.root.children[0].children[1].children[0].children[0],
161+
g.add_outcome([2, -2], label="aRpU"),
162+
)
163+
g.set_outcome(
164+
g.root.children[0].children[1].children[0].children[1],
165+
g.add_outcome([3, -3], label="aRpV"),
166+
)
167+
g.set_outcome(
168+
g.root.children[0].children[1].children[1].children[0],
169+
g.add_outcome([4, -4], label="aRqU"),
170+
)
171+
g.set_outcome(
172+
g.root.children[0].children[1].children[1].children[1],
173+
g.add_outcome([5, -5], label="aRqV"),
174+
)
175+
176+
g.set_outcome(g.root.children[1].children[0], g.add_outcome([6, -6], label="bC"))
177+
g.set_outcome(g.root.children[1].children[1], g.add_outcome([7, -7], label="bD"))
178+
179+
g.set_outcome(
180+
g.root.children[2].children[0].children[0], g.add_outcome([8, -8], label="cCs")
181+
)
182+
g.set_outcome(
183+
g.root.children[2].children[0].children[1], g.add_outcome([9, -9], label="cCt")
184+
)
185+
g.set_outcome(
186+
g.root.children[2].children[1].children[0],
187+
g.add_outcome([10, -10], label="cDs"),
188+
)
189+
g.set_outcome(
190+
g.root.children[2].children[1].children[1],
191+
g.add_outcome([11, -11], label="cDt"),
192+
)
193+
194+
g.set_outcome(g.root.children[3], g.add_outcome([12, -12], label="d"))
195+
196+
return g
197+
198+
199+
def make_rational(input: str):
200+
return gbt.Rational(input)
201+
202+
203+
vectorized_make_rational = np.vectorize(make_rational)

tests/test_rsf.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,10 @@
126126
# 2-player (zero-sum) game with reduction for both players and generic payoffs
127127
# (
128128
# games.create_reduction_generic_payoffs_efg(),
129-
# [["11*", "12*", "211", "221", "212", "222"],
130-
# ["1*1", "1*2", "2**", "31*", "32*", "4**"] ],
129+
# [
130+
# ["11*", "12*", "211", "221", "212", "222"],
131+
# ["1*1", "1*2", "2**", "31*", "32*", "4**"],
132+
# ],
131133
# [
132134
# np.array(
133135
# [
@@ -148,7 +150,7 @@
148150
# ["1", "2", "3", "4", "5", "6"],
149151
# ["1", "2", "3", "4", "5", "6"],
150152
# ]
151-
# )
153+
# ),
152154
# ],
153155
# ),
154156
],
@@ -167,5 +169,5 @@ def test_reduced_strategic_form(
167169
for i, player in enumerate(game.players):
168170
assert strategy_labels[i] == [s.label for s in player.strategies]
169171
# convert strings to rationals
170-
exp_array = arrays[i].astype(gbt.Rational)
172+
exp_array = games.vectorized_make_rational(np_arrays_of_rsf[i])
171173
assert (arrays[i] == exp_array).all()

0 commit comments

Comments
 (0)