11"""A utility module to create/load games for the test suite."""
2+
23import pathlib
34
5+ import numpy as np
6+
47import pygambit as gbt
58
69
710def read_from_file (fn : str ) -> gbt .Game :
811 if fn .endswith (".efg" ):
9- return gbt .read_efg (pathlib .Path ("tests/test_games" )/ fn )
12+ return gbt .read_efg (pathlib .Path ("tests/test_games" ) / fn )
1013 elif fn .endswith (".nfg" ):
11- return gbt .read_nfg (pathlib .Path ("tests/test_games" )/ fn )
14+ return gbt .read_nfg (pathlib .Path ("tests/test_games" ) / fn )
1215 else :
1316 raise ValueError (f"Unknown file extension in { fn } " )
1417
1518
1619################################################################################################
1720# Normal-form (aka strategic-form) games (nfg)
1821
22+
1923def create_2x2_zero_nfg () -> gbt .Game :
2024 """
2125 Returns
@@ -73,6 +77,7 @@ def create_coord_4x4_nfg(outcome_version: bool = False) -> gbt.Game:
7377################################################################################################
7478# Extensive-form games (efg)
7579
80+
7681def create_mixed_behav_game_efg () -> gbt .Game :
7782 """
7883 Returns
@@ -89,7 +94,8 @@ def create_myerson_2_card_poker_efg() -> gbt.Game:
8994 Returns
9095 -------
9196 Game
92- Myerson 2-card poker: Two-player extensive poker game with a chance move with two moves,
97+ Simplied "stripped down" version of Myerson 2-card poker:
98+ Two-player extensive poker game with a chance move with two moves,
9399 then player 1 can raise or fold; after raising player 2 is in an infoset with two nodes
94100 and can choose to meet or pass
95101 """
@@ -124,3 +130,112 @@ def create_selten_horse_game_efg() -> gbt.Game:
124130 5-player Selten's Horse Game
125131 """
126132 return read_from_file ("e01.efg" )
133+
134+
135+ def create_reduction_generic_payoffs_efg () -> gbt .Game :
136+ # tree with only root
137+ g = gbt .Game .new_tree (
138+ players = ["1" , "2" ], title = "2 player reduction generic payoffs"
139+ )
140+
141+ # add four children
142+ g .append_move (g .root , "2" , ["a" , "b" , "c" , "d" ])
143+
144+ # add L and R after a
145+ g .append_move (g .root .children [0 ], "1" , ["L" , "R" ])
146+
147+ # add C and D to single infoset after b and c
148+ nodes = [g .root .children [1 ], g .root .children [2 ]]
149+ g .append_move (nodes , "1" , ["C" , "D" ])
150+
151+ # add s and t from single infoset after rightmost C and D
152+ g .append_move (g .root .children [2 ].children , "2" , ["s" , "t" ])
153+
154+ # add p and q
155+ g .append_move (g .root .children [0 ].children [1 ], "2" , ["p" , "q" ])
156+
157+ # add U and V in a single infoset after p and q
158+ g .append_move (g .root .children [0 ].children [1 ].children , "1" , ["U" , "V" ])
159+
160+ # Set outcomes
161+
162+ g .set_outcome (g .root .children [0 ].children [0 ], g .add_outcome ([1 , - 1 ], label = "aL" ))
163+ g .set_outcome (
164+ g .root .children [0 ].children [1 ].children [0 ].children [0 ],
165+ g .add_outcome ([2 , - 2 ], label = "aRpU" ),
166+ )
167+ g .set_outcome (
168+ g .root .children [0 ].children [1 ].children [0 ].children [1 ],
169+ g .add_outcome ([3 , - 3 ], label = "aRpV" ),
170+ )
171+ g .set_outcome (
172+ g .root .children [0 ].children [1 ].children [1 ].children [0 ],
173+ g .add_outcome ([4 , - 4 ], label = "aRqU" ),
174+ )
175+ g .set_outcome (
176+ g .root .children [0 ].children [1 ].children [1 ].children [1 ],
177+ g .add_outcome ([5 , - 5 ], label = "aRqV" ),
178+ )
179+
180+ g .set_outcome (g .root .children [1 ].children [0 ], g .add_outcome ([6 , - 6 ], label = "bC" ))
181+ g .set_outcome (g .root .children [1 ].children [1 ], g .add_outcome ([7 , - 7 ], label = "bD" ))
182+
183+ g .set_outcome (
184+ g .root .children [2 ].children [0 ].children [0 ], g .add_outcome ([8 , - 8 ], label = "cCs" )
185+ )
186+ g .set_outcome (
187+ g .root .children [2 ].children [0 ].children [1 ], g .add_outcome ([9 , - 9 ], label = "cCt" )
188+ )
189+ g .set_outcome (
190+ g .root .children [2 ].children [1 ].children [0 ],
191+ g .add_outcome ([10 , - 10 ], label = "cDs" ),
192+ )
193+ g .set_outcome (
194+ g .root .children [2 ].children [1 ].children [1 ],
195+ g .add_outcome ([11 , - 11 ], label = "cDt" ),
196+ )
197+
198+ g .set_outcome (g .root .children [3 ], g .add_outcome ([12 , - 12 ], label = "d" ))
199+
200+ return g
201+
202+
203+ def create_reduction_one_player_generic_payoffs_efg () -> gbt .Game :
204+ g = gbt .Game .new_tree (players = ["1" ], title = "One player reduction generic payoffs" )
205+ g .append_move (g .root , "1" , ["a" , "b" , "c" , "d" ])
206+ g .append_move (g .root .children [0 ], "1" , ["e" , "f" ])
207+ g .set_outcome (g .root .children [0 ].children [0 ], g .add_outcome ([1 ]))
208+ g .set_outcome (g .root .children [0 ].children [1 ], g .add_outcome ([2 ]))
209+ g .set_outcome (g .root .children [1 ], g .add_outcome ([3 ]))
210+ g .set_outcome (g .root .children [2 ], g .add_outcome ([4 ]))
211+ g .set_outcome (g .root .children [3 ], g .add_outcome ([5 ]))
212+ return g
213+
214+
215+ def create_reduction_both_players_payoff_ties_efg () -> gbt .Game :
216+ g = gbt .Game .new_tree (players = ["1" , "2" ], title = "From GTE survey" )
217+ g .append_move (g .root , "1" , ["A" , "B" , "C" , "D" ])
218+ g .append_move (g .root .children [0 ], "2" , ["a" , "b" ])
219+ g .append_move (g .root .children [1 ], "2" , ["c" , "d" ])
220+ g .append_move (g .root .children [2 ], "2" , ["e" , "f" ])
221+ g .append_move (g .root .children [0 ].children [1 ], "2" , ["g" , "h" ])
222+ g .append_move (g .root .children [2 ].children , "1" , ["E" , "F" ])
223+
224+ g .set_outcome (g .root .children [0 ].children [0 ], g .add_outcome ([2 , 8 ]))
225+ g .set_outcome (g .root .children [0 ].children [1 ].children [0 ], g .add_outcome ([0 , 1 ]))
226+ g .set_outcome (g .root .children [0 ].children [1 ].children [1 ], g .add_outcome ([5 , 2 ]))
227+ g .set_outcome (g .root .children [1 ].children [0 ], g .add_outcome ([7 , 6 ]))
228+ g .set_outcome (g .root .children [1 ].children [1 ], g .add_outcome ([4 , 2 ]))
229+ g .set_outcome (g .root .children [2 ].children [0 ].children [0 ], g .add_outcome ([3 , 7 ]))
230+ g .set_outcome (g .root .children [2 ].children [0 ].children [1 ], g .add_outcome ([8 , 3 ]))
231+ g .set_outcome (g .root .children [2 ].children [1 ].children [0 ], g .add_outcome ([7 , 8 ]))
232+ g .set_outcome (g .root .children [2 ].children [1 ].children [1 ], g .add_outcome ([2 , 2 ]))
233+ g .set_outcome (g .root .children [3 ], g .add_outcome ([6 , 4 ]))
234+ return g
235+
236+
237+ def make_rational (input : str ):
238+ return gbt .Rational (input )
239+
240+
241+ vectorized_make_rational = np .vectorize (make_rational )
0 commit comments