knitr::opts_chunk$set(echo = TRUE, error=TRUE) library(gtree)
Here is a jupyter notebook by Valeria Burdea that creates a sender-receive game using Gambit's Python interface. For a comparison, this tutorial shows how one can create and analyse the same game in a relatively simple fashion using gtree
.
I just copy the game description from the Jupyter notebook:
"This is a 2-player sequential game the structure of which is inspired by Glazer and Rubinstein (2004, 2006). In the first stage, the sender is dealt 2 cards - one card orange, one card blue. Each card can take a value between 1 and 9; each combination of values is equally likely. A hand is good if the sum of the two cards is at least 9; a hand is bad otherwise. Upon observing the two cards, the sender chooses one to reveal to the receiver. The receiver observes the revealed card and chooses an action between 'Accept' and 'Reject'. The incentives are such that the sender would always want the receiver to accept, while the receiver would only want to accept if the hand is good and reject otherwise."
Here is the implementation of the game using gtree
(the exact payoffs were taken from the Python code):
library(gtree) game = new_game( gameId = "SenderReceiver", params = list(numPlayers=2, maxVal=9), options = make_game_options(verbose=FALSE), stages = list( stage("DrawStage", nature = list( natureMove("orange", ~1:maxVal), natureMove("blue", ~1:maxVal) ) ), stage("RevealStage", player=1, observe = c("orange","blue"), actions = list( action("reveal",c("orange","blue")) ) ), stage("AcceptStage", player=2, compute = list( shownVal ~ ifelse(reveal=="orange", orange, blue) ), observe = c("shownVal"), actions = list( action("accept",c(TRUE, FALSE)) ) ), stage("PayoffStage", player=1:2, compute=list( hand ~ ifelse(orange+blue>=maxVal, "good","bad"), payoff_1 ~ ifelse(accept, 1,0), # Sender wants accept payoff_2 ~ case_distinction( accept & hand=="good", 1, accept & hand=="bad", 0, !accept & hand=="good",0, !accept & hand=="bad", 1 ) ) ) ) )
I would argue that gtree's game definition using stages follows in a straightforward and simple fashion the verbal game description.
Gambit's Python API is instead designed to directly specify game trees. For comparison, take a look here.
Shall we try to compute all pure SPE?
game %>% game_solve()
Ups... looks like the game is too large to be solved. Here is some additional size information.
# Get some size information about the game game %>% game_print_size_info()
The game has a gigantic number of strategy profiles.
Interestingly, the game also has only 1 subgame, even though player 1 perfectly observes the values of the orange and blue card. For an illustration, why there is only one subgame, we export a smaller version of the game in which cards only take values of 1 or 2 to a Gambit efg file.
game %>% game_change_param(maxVal = 2) %>% game_write_efg("sender_receiver.efg")
I have manually opened the efg file with Gambit and exported the following game tree as an svg graphic:
Recall the definition of a subgame, e.g. from Wikipedia:
Even though the moves of player 1 start at singleton information sets (Condition 1), candidate subgames starting at these nodes violate Condition 3.
If we cannot reduce the number of relevant strategy profiles by subgames, our internal gtree solver cannot practically solve games with so many strategy profiles. However, Gambit has solvers that can find at least one equilibrium of this game. Here we let gambit-logit solver do its magic.
To make the vignette build quicker I reduce the size of the game, but you can change maxVal to 9. (Takes then around 2 minutes to solve on my notebook).
game %>% game_change_param(maxVal = 4) %>% game_print_size_info() %>% game_gambit_solve("gambit-logit -q -e") game %>% eq_tables()
The results seem intutive: Player 2 only accepts if and only if the shown card is at least a 6. Player 1 always shows a card that is at least 6 if he has one.
You may first take a look at the Wikipedia page for quantal response equilibria. The following code uses the gambit-logit solver to compute a logit agent quantal response equilibrium using the parameter lambda=3
.
game %>% game_change_param(maxVal = 4) %>% game_print_size_info() %>% game_gambit_solve("gambit-logit -q -e -m 3") %>% eq_tables()
The python code called gambit-logit
without the option -e
. It then returns a table of (approximated) equilibria for many values of lambda
up to the maximum specified by the option -m
. I have currently not implemented a feature in gtree
to automatically parse that whole table. But if there is interest, just let me know, via Github issue or email.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.