<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 <h1>Building game trees</h1>
<i>Theodore L. Turocy</i><br/>
<i>University of East Anglia</i>
<br/><br/>
<h3>EC'16 Workshop
24 July 2016</h3>
Step1:  One can build up extensive games from scratch and manipulate them.  This example shows one way to do that for the simple one-card poker game.
The primitives for doing this remain rather low-level, as I have never settled on a good way to write higher-level ones that apply broadly.  It has always seemed to me that different games have different "natural" ways to build them out.  It is nevertheless likely that having some more powerful idioms could be useful - suggestions are welcomed.
Step2:  Define the players; save them as variables for convenience laster.
Step3:  The root node is a chance move, between Ace and King.  Chance moves default to uniform randomisation, but I set the probabilities here anyway just for explicitness.
Step4:  After an Ace, Alice can Raise or Fold.
Step5:  She can also Raise or Fold after the King.  Calling append_move with the player, rather than the previously created move, creates a new information set for Alice.
Step6:  After Alice raises with the Ace, Bob can Meet or Pass.
Step7:  Likewise after Alice raises with the King.  Using the same move here adds the move to the same information set for Bob.
Step8:  The game so far, as an .efg file.  We see the tree structure is in place; now to deal with payoffs.
Step9:  Attach the outcomes to the corresponding terminal nodes.  Notice how we can re-use the outcomes to denote that different terminal nodes may correspond to the same logical outcome.
Step10:  Here's the game we've just built
Step11:  For comparison, here's the game we started with for the Poker example.
Step12:  We can confirm they're the same
<ASSISTANT_TASK:>
Python Code:
import gambit
Explanation: <h1>Building game trees</h1>
<i>Theodore L. Turocy</i><br/>
<i>University of East Anglia</i>
<br/><br/>
<h3>EC'16 Workshop
24 July 2016</h3>
End of explanation
g = gambit.Game.new_tree()
g.title = "A simple poker example"
Explanation: One can build up extensive games from scratch and manipulate them.  This example shows one way to do that for the simple one-card poker game.
The primitives for doing this remain rather low-level, as I have never settled on a good way to write higher-level ones that apply broadly.  It has always seemed to me that different games have different "natural" ways to build them out.  It is nevertheless likely that having some more powerful idioms could be useful - suggestions are welcomed.
End of explanation
alice = g.players.add("Alice")
bob = g.players.add("Bob")
Explanation: Define the players; save them as variables for convenience laster.
End of explanation
move = g.root.append_move(g.players.chance, 2)
move.actions[0].label = "A"
move.actions[0].prob = gambit.Rational(1, 2)
move.actions[1].label = "K"
move.actions[1].prob = gambit.Rational(1, 2)
Explanation: The root node is a chance move, between Ace and King.  Chance moves default to uniform randomisation, but I set the probabilities here anyway just for explicitness.
End of explanation
move = g.root.children[0].append_move(alice, 2)
move.label = 'a'
move.actions[0].label = "R"
move.actions[1].label = "F"
Explanation: After an Ace, Alice can Raise or Fold.
End of explanation
move = g.root.children[1].append_move(alice, 2)
move.label = 'k'
move.actions[0].label = "R"
move.actions[1].label = "F"
Explanation: She can also Raise or Fold after the King.  Calling append_move with the player, rather than the previously created move, creates a new information set for Alice.
End of explanation
move = g.root.children[0].children[0].append_move(bob, 2)
move.label = 'b'
move.actions[0].label = "M"
move.actions[1].label = "P"
Explanation: After Alice raises with the Ace, Bob can Meet or Pass.
End of explanation
g.root.children[1].children[0].append_move(move)
Explanation: Likewise after Alice raises with the King.  Using the same move here adds the move to the same information set for Bob.
End of explanation
g
alice_big = g.outcomes.add("Alice wins big")
alice_big[0] = 2
alice_big[1] = -2
alice_small = g.outcomes.add("Alice wins")
alice_small[0] = 1
alice_small[1] = -1
bob_small = g.outcomes.add("Bob wins")
bob_small[0] = -1
bob_small[1] = 1
bob_big = g.outcomes.add("Bob wins big")
bob_big[0] = -2
bob_big[1] = 2
Explanation: The game so far, as an .efg file.  We see the tree structure is in place; now to deal with payoffs.
End of explanation
g.root.children[0].children[0].children[0].outcome = alice_big
g.root.children[0].children[0].children[1].outcome = alice_small
g.root.children[0].children[1].outcome = bob_small
g.root.children[1].children[0].children[0].outcome = bob_big
g.root.children[1].children[0].children[1].outcome = alice_small
g.root.children[1].children[1].outcome = bob_small
Explanation: Attach the outcomes to the corresponding terminal nodes.  Notice how we can re-use the outcomes to denote that different terminal nodes may correspond to the same logical outcome.
End of explanation
g
Explanation: Here's the game we've just built
End of explanation
gambit.Game.read_game("poker.efg")
Explanation: For comparison, here's the game we started with for the Poker example.
End of explanation
g.write() == gambit.Game.read_game("poker.efg").write()
Explanation: We can confirm they're the same:
End of explanation
<END_TASK>