@@ -19,7 +19,7 @@ def read_from_file(fn: str) -> gbt.Game:
1919
2020
2121def create_efg_corresponding_to_bimatrix_game (
22- A : np .ndarray , B : np .ndarray , title : str
22+ A : np .ndarray , B : np .ndarray , title : str
2323) -> gbt .Game :
2424 """
2525 There is no direct pygambit method to create an EFG from a stategic-form game.
@@ -123,6 +123,230 @@ def create_2x2_zero_sum_efg(missing_term_outcome: bool = False) -> gbt.Game:
123123 return g
124124
125125
126+ def create_perfect_info_with_chance_efg () -> gbt .Game :
127+ # Tests case in which sequence profile probabilities don't sum to 1
128+ g = gbt .Game .new_tree (players = ["1" , "2" ], title = "2 player perfect info with chance" )
129+ g .append_move (g .root , "1" , ["a" , "b" ])
130+ g .append_move (g .root .children [0 ], g .players .chance , ["L" , "R" ])
131+ g .append_move (g .root .children [0 ].children [0 ], "2" , ["A" , "B" ])
132+ g .append_move (g .root .children [0 ].children [1 ], "2" , ["C" , "D" ])
133+ g .set_outcome (
134+ g .root .children [0 ].children [0 ].children [0 ], g .add_outcome ([- 2 , 2 ], label = "aLA" )
135+ )
136+ g .set_outcome (
137+ g .root .children [0 ].children [0 ].children [1 ], g .add_outcome ([- 2 , 2 ], label = "aLB" )
138+ )
139+ g .set_outcome (
140+ g .root .children [0 ].children [1 ].children [0 ], g .add_outcome ([- 2 , 2 ], label = "aRC" )
141+ )
142+ g .set_outcome (
143+ g .root .children [0 ].children [1 ].children [1 ], g .add_outcome ([- 2 , 2 ], label = "aRD" )
144+ )
145+ g .set_outcome (g .root .children [1 ], g .add_outcome ([- 1 , 1 ], label = "b" ))
146+ return g
147+
148+
149+ def create_one_card_poker_lacking_outcome_efg () -> gbt .Game :
150+ g = gbt .Game .new_tree (players = ["Bob" , "Alice" ],
151+ title = "One card poker game, after Myerson (1991)" )
152+ g .append_move (g .root , g .players .chance , ["King" , "Queen" ])
153+ for node in g .root .children :
154+ g .append_move (node , "Alice" , ["Raise" , "Fold" ])
155+ g .append_move (g .root .children [0 ].children [0 ], "Bob" , ["Meet" , "Pass" ])
156+ g .append_infoset (g .root .children [1 ].children [0 ],
157+ g .root .children [0 ].children [0 ].infoset )
158+ alice_winsbig = g .add_outcome ([- 1 , 1 ], label = "Alice wins big" )
159+ bob_winsbig = g .add_outcome ([3 , - 3 ], label = "Bob wins big" )
160+ bob_wins = g .add_outcome ([2 , - 2 ], label = "Bob wins" )
161+ g .set_outcome (g .root .children [0 ].children [0 ].children [0 ], alice_winsbig )
162+ g .set_outcome (g .root .children [0 ].children [1 ], bob_wins )
163+ g .set_outcome (g .root .children [1 ].children [0 ].children [0 ], bob_winsbig )
164+ g .set_outcome (g .root .children [1 ].children [1 ], bob_wins )
165+ return g
166+
167+
168+ def create_perfect_info_internal_outcomes_efg () -> gbt .Game :
169+ g = gbt .Game .new_tree (players = ["1" , "2" ], title = "2 player perfect info win lose" )
170+ g .append_move (g .root , "2" , ["a" , "b" ])
171+ g .append_move (g .root .children [0 ], "1" , ["L" , "R" ])
172+ g .append_move (g .root .children [1 ], "1" , ["L" , "R" ])
173+ g .append_move (g .root .children [0 ].children [0 ], "2" , ["l" , "r" ])
174+ g .set_outcome (g .root .children [0 ], g .add_outcome ([- 100 , 50 ], label = "a" ))
175+ g .set_outcome (
176+ g .root .children [0 ].children [0 ].children [0 ], g .add_outcome ([101 , - 51 ], label = "aLl" )
177+ )
178+ g .set_outcome (
179+ g .root .children [0 ].children [0 ].children [1 ], g .add_outcome ([99 , - 49 ], label = "aLr" )
180+ )
181+ g .set_outcome (g .root .children [0 ].children [1 ], g .add_outcome ([101 , - 51 ], label = "aR" ))
182+ g .set_outcome (g .root .children [1 ].children [0 ], g .add_outcome ([1 , - 1 ], label = "bL" ))
183+ g .set_outcome (g .root .children [1 ].children [1 ], g .add_outcome ([- 1 , 1 ], label = "bR" ))
184+ return g
185+
186+
187+ def create_three_action_internal_outcomes_efg () -> gbt .Game :
188+ # Test 3 actions at infoset, internal outcomes and missing some outcomes at leaves
189+ g = gbt .Game .new_tree (players = ["1" , "2" ],
190+ title = "3 action, internal outcomes, lacking terminal outcomes" )
191+ g .append_move (g .root , g .players .chance , ["H" , "L" ])
192+ for i in range (2 ):
193+ g .append_move (g .root .children [i ], "1" , ["A" , "B" , "C" ])
194+ for i in range (3 ):
195+ g .append_move (g .root .children [0 ].children [i ], "2" , ["X" , "Y" ])
196+ g .append_infoset (g .root .children [1 ].children [i ], g .root .children [0 ].children [i ].infoset )
197+ o_1 = g .add_outcome ([1 , - 1 ], label = "1" )
198+ o_m1 = g .add_outcome ([- 1 , 1 ], label = "-1" )
199+ o_2 = g .add_outcome ([2 , - 2 ], label = "2" )
200+ o_m2 = g .add_outcome ([- 2 , 2 ], label = "-2" )
201+ g .set_outcome (g .root .children [0 ].children [0 ], o_1 )
202+ g .set_outcome (g .root .children [1 ].children [2 ], o_m1 )
203+ g .set_outcome (g .root .children [0 ].children [0 ].children [1 ], o_m2 )
204+ g .set_outcome (g .root .children [0 ].children [1 ].children [0 ], o_m1 )
205+ g .set_outcome (g .root .children [0 ].children [1 ].children [1 ], o_1 )
206+ g .set_outcome (g .root .children [0 ].children [2 ].children [0 ], o_1 )
207+ g .set_outcome (g .root .children [1 ].children [0 ].children [1 ], o_1 )
208+ g .set_outcome (g .root .children [1 ].children [1 ].children [0 ], o_1 )
209+ g .set_outcome (g .root .children [1 ].children [1 ].children [1 ], o_m1 )
210+ g .set_outcome (g .root .children [1 ].children [2 ].children [1 ], o_2 )
211+ return g
212+
213+
214+ def create_entry_accomodation_efg () -> gbt .Game :
215+ g = gbt .Game .new_tree (players = ["1" , "2" ],
216+ title = "Entry-accomodation game with internal outcomes" )
217+ g .append_move (g .root , "1" , ["S" , "T" ])
218+ g .append_move (g .root .children [0 ], "2" , ["E" , "O" ])
219+ g .append_infoset (g .root .children [1 ], g .root .children [0 ].infoset )
220+ g .append_move (g .root .children [0 ].children [0 ], "1" , ["A" , "F" ])
221+ g .append_move (g .root .children [1 ].children [0 ], "1" , ["A" , "F" ])
222+ g .set_outcome (g .root .children [0 ], g .add_outcome ([3 , 2 ]))
223+ g .set_outcome (g .root .children [0 ].children [0 ].children [1 ], g .add_outcome ([- 3 , - 1 ]))
224+ g .set_outcome (g .root .children [0 ].children [1 ], g .add_outcome ([- 2 , 1 ]))
225+ g .set_outcome (g .root .children [1 ].children [0 ].children [0 ], g .add_outcome ([2 , 3 ]))
226+ g .set_outcome (g .root .children [1 ].children [0 ].children [1 ], g .add_outcome ([1 , 0 ]))
227+ g .set_outcome (g .root .children [1 ].children [1 ], g .add_outcome ([3 , 1 ]))
228+ return g
229+
230+
231+ def create_non_zero_sum_lacking_outcome_efg () -> gbt .Game :
232+ g = gbt .Game .new_tree (players = ["1" , "2" ], title = "Non constant-sum game lacking outcome" )
233+ g .append_move (g .root , g .players .chance , ["H" , "T" ])
234+ g .set_chance_probs (g .root .infoset , ["1/2" , "1/2" ])
235+ g .append_move (g .root .children [0 ], "1" , ["A" , "B" ])
236+ g .append_infoset (g .root .children [1 ], g .root .children [0 ].infoset )
237+ g .append_move (g .root .children [0 ].children [0 ], "2" , ["X" , "Y" ])
238+ g .append_infoset (g .root .children [0 ].children [1 ], g .root .children [0 ].children [0 ].infoset )
239+ g .append_infoset (g .root .children [1 ].children [0 ], g .root .children [0 ].children [0 ].infoset )
240+ g .append_infoset (g .root .children [1 ].children [1 ], g .root .children [0 ].children [0 ].infoset )
241+ g .set_outcome (g .root .children [0 ].children [0 ].children [0 ], g .add_outcome ([2 , 1 ]))
242+ g .set_outcome (g .root .children [0 ].children [0 ].children [1 ], g .add_outcome ([- 1 , 2 ]))
243+ g .set_outcome (g .root .children [0 ].children [1 ].children [0 ], g .add_outcome ([1 , - 1 ]))
244+ g .set_outcome (g .root .children [1 ].children [0 ].children [0 ], g .add_outcome ([1 , 0 ]))
245+ g .set_outcome (g .root .children [1 ].children [0 ].children [1 ], g .add_outcome ([0 , 1 ]))
246+ g .set_outcome (g .root .children [1 ].children [1 ].children [0 ], g .add_outcome ([- 1 , 1 ]))
247+ g .set_outcome (g .root .children [1 ].children [1 ].children [1 ], g .add_outcome ([2 , - 1 ]))
248+ return g
249+
250+
251+ def create_chance_in_middle_efg () -> gbt .Game :
252+ g = gbt .Game .new_tree (players = ["1" , "2" ],
253+ title = "Chance in middle game" )
254+ g .append_move (g .root , "1" , ["A" , "B" ])
255+ g .append_move (g .root .children [0 ], g .players .chance , ["H" , "L" ])
256+ g .set_chance_probs (g .root .children [0 ].infoset , ["1/5" , "4/5" ])
257+ g .append_move (g .root .children [1 ], g .players .chance , ["H" , "L" ])
258+ g .set_chance_probs (g .root .children [1 ].infoset , ["7/10" , "3/10" ])
259+ g .set_outcome (g .root .children [0 ].children [0 ], g .add_outcome ([- 1 , 1 ], label = "a" ))
260+ for i in range (2 ):
261+ g .append_move (g .root .children [0 ].children [i ], "2" , ["X" , "Y" ])
262+ ist = g .root .children [0 ].children [i ].infoset
263+ g .append_infoset (g .root .children [1 ].children [i ], ist )
264+ for i in range (2 ):
265+ for j in range (2 ):
266+ g .append_move (g .root .children [i ].children [0 ].children [j ], "1" , ["C" , "D" ])
267+ ist = g .root .children [i ].children [0 ].children [j ].infoset
268+ g .append_infoset (g .root .children [i ].children [1 ].children [j ], ist )
269+ o_1 = g .add_outcome ([1 , - 1 ], label = "1" )
270+ o_m1 = g .add_outcome ([- 1 , 1 ], label = "-1" )
271+ o_h = g .add_outcome (["1/2" , "-1/2" ], label = "0.5" )
272+ o_mh = g .add_outcome (["-1/2" , "1/2" ], label = "-0.5" )
273+ g .set_outcome (g .root .children [0 ].children [0 ].children [0 ].children [0 ], o_1 )
274+ g .set_outcome (g .root .children [0 ].children [0 ].children [0 ].children [1 ], o_m1 )
275+ g .set_outcome (g .root .children [0 ].children [0 ].children [1 ].children [0 ], o_h )
276+ g .set_outcome (g .root .children [0 ].children [0 ].children [1 ].children [1 ], o_mh )
277+ g .set_outcome (g .root .children [0 ].children [1 ].children [0 ].children [0 ], o_h )
278+ g .set_outcome (g .root .children [0 ].children [1 ].children [0 ].children [1 ], o_mh )
279+ g .set_outcome (g .root .children [0 ].children [1 ].children [1 ].children [0 ], o_1 )
280+ g .set_outcome (g .root .children [0 ].children [1 ].children [1 ].children [1 ], o_m1 )
281+ g .set_outcome (g .root .children [1 ].children [0 ].children [0 ].children [0 ], o_h )
282+ g .set_outcome (g .root .children [1 ].children [0 ].children [0 ].children [1 ], o_mh )
283+ g .set_outcome (g .root .children [1 ].children [0 ].children [1 ].children [0 ], o_1 )
284+ g .set_outcome (g .root .children [1 ].children [0 ].children [1 ].children [1 ], o_m1 )
285+ g .set_outcome (g .root .children [1 ].children [1 ].children [0 ].children [0 ], o_1 )
286+ g .set_outcome (g .root .children [1 ].children [1 ].children [0 ].children [1 ], o_m1 )
287+ g .set_outcome (g .root .children [1 ].children [1 ].children [1 ].children [0 ], o_h )
288+ g .set_outcome (g .root .children [1 ].children [1 ].children [1 ].children [1 ], o_mh )
289+ return g
290+
291+
292+ def create_large_payoff_game_efg () -> gbt .Game :
293+ g = gbt .Game .new_tree (players = ["1" , "2" ], title = "Large payoff game" )
294+ g .append_move (g .root , g .players .chance , ["L" , "R" ])
295+ for i in range (2 ):
296+ g .append_move (g .root .children [i ], "1" , ["A" , "B" ])
297+ for i in range (2 ):
298+ g .append_move (g .root .children [0 ].children [i ], "2" , ["X" , "Y" ])
299+ g .append_infoset (g .root .children [1 ].children [i ], g .root .children [0 ].children [i ].infoset )
300+ o_large = g .add_outcome ([10000000000000000000 , - 10000000000000000000 ], label = "large payoff" )
301+ o_1 = g .add_outcome ([1 , - 1 ], label = "1" )
302+ o_m1 = g .add_outcome ([- 1 , 1 ], label = "-1" )
303+ o_zero = g .add_outcome ([0 , 0 ], label = "0" )
304+ g .set_outcome (g .root .children [0 ].children [0 ].children [0 ], o_large )
305+ g .set_outcome (g .root .children [0 ].children [0 ].children [1 ], o_1 )
306+ g .set_outcome (g .root .children [0 ].children [1 ].children [0 ], o_m1 )
307+ g .set_outcome (g .root .children [0 ].children [1 ].children [1 ], o_zero )
308+ g .set_outcome (g .root .children [1 ].children [0 ].children [0 ], o_m1 )
309+ g .set_outcome (g .root .children [1 ].children [0 ].children [1 ], o_1 )
310+ g .set_outcome (g .root .children [1 ].children [1 ].children [0 ], o_zero )
311+ g .set_outcome (g .root .children [1 ].children [1 ].children [1 ], o_large )
312+ return g
313+
314+
315+ def create_3_player_with_internal_outcomes_efg () -> gbt .Game :
316+ g = gbt .Game .new_tree (players = ["1" , "2" , "3" ], title = "3 player game with internal outcomes" )
317+ g .append_move (g .root , g .players .chance , ["H" , "T" ])
318+ g .set_chance_probs (g .root .infoset , ["1/2" , "1/2" ])
319+ g .append_move (g .root .children [0 ], "1" , ["a" , "b" ])
320+ g .append_move (g .root .children [1 ], "1" , ["c" , "d" ])
321+ g .append_move (g .root .children [0 ].children [0 ], "2" , ["A" , "B" ])
322+ g .append_infoset (g .root .children [1 ].children [0 ], g .root .children [0 ].children [0 ].infoset )
323+ g .append_move (g .root .children [0 ].children [1 ], "3" , ["W" , "X" ])
324+ g .append_infoset (g .root .children [1 ].children [1 ], g .root .children [0 ].children [1 ].infoset )
325+ g .append_move (g .root .children [0 ].children [0 ].children [0 ], "3" , ["Y" , "Z" ])
326+ iset = g .root .children [0 ].children [0 ].children [0 ].infoset
327+ g .append_infoset (g .root .children [0 ].children [0 ].children [1 ], iset )
328+ g .append_move (g .root .children [0 ].children [1 ].children [1 ], "2" , ["C" , "D" ])
329+ o = g .add_outcome ([1 , 2 , 3 ])
330+ g .set_outcome (g .root .children [1 ], o )
331+ o = g .add_outcome ([3 , 1 , 4 ])
332+ g .set_outcome (g .root .children [0 ].children [0 ].children [0 ].children [0 ], o )
333+ o = g .add_outcome ([4 , 0 , 1 ])
334+ g .set_outcome (g .root .children [0 ].children [0 ].children [0 ].children [1 ], o )
335+ o = g .add_outcome ([1 , 0 , 1 ])
336+ g .set_outcome (g .root .children [1 ].children [0 ].children [0 ], o )
337+ o = g .add_outcome ([2 , - 1 , - 2 ])
338+ g .set_outcome (g .root .children [1 ].children [0 ].children [1 ], o )
339+ o = g .add_outcome ([1 , 3 , 2 ])
340+ g .set_outcome (g .root .children [0 ].children [1 ].children [0 ], o )
341+ o = g .add_outcome ([2 , 4 , 1 ])
342+ g .set_outcome (g .root .children [0 ].children [1 ].children [1 ].children [0 ], o )
343+ o = g .add_outcome ([4 , 1 , 3 ])
344+ g .set_outcome (g .root .children [0 ].children [1 ].children [1 ].children [1 ], o )
345+ o = g .add_outcome ([- 1 , 2 , - 1 ])
346+ g .set_outcome (g .root .children [1 ].children [1 ].children [0 ], o )
347+ return g
348+
349+
126350def create_matching_pennies_efg (with_neutral_outcome : bool = False ) -> gbt .Game :
127351 """
128352 The version with_neutral_outcome adds a (0,0) payoff outcomes at a non-terminal node.
@@ -990,14 +1214,14 @@ def _redu_strats(self, player, level):
9901214 first_half = tmp [:n_half ]
9911215 second_half = tmp [n_half :]
9921216 n_stars = (
993- self .get_n_infosets (level )[1 ] - self .get_n_infosets (level - 1 )[1 ] - 1
1217+ self .get_n_infosets (level )[1 ] - self .get_n_infosets (level - 1 )[1 ] - 1
9941218 )
9951219 stars = "*" * n_stars
9961220 return (
997- ["11" + t + stars for t in first_half ]
998- + ["12" + t + stars for t in second_half ]
999- + ["21" + stars + t for t in first_half ]
1000- + ["22" + stars + t for t in second_half ]
1221+ ["11" + t + stars for t in first_half ]
1222+ + ["12" + t + stars for t in second_half ]
1223+ + ["21" + stars + t for t in first_half ]
1224+ + ["22" + stars + t for t in second_half ]
10011225 )
10021226
10031227
0 commit comments