Skip to content

Commit e7c1777

Browse files
Added tests for enumpoly, LP and LCP
1 parent 46121fc commit e7c1777

2 files changed

Lines changed: 509 additions & 147 deletions

File tree

tests/games.py

Lines changed: 230 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ def read_from_file(fn: str) -> gbt.Game:
1919

2020

2121
def 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+
126350
def 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

Comments
 (0)