<a href="https://colab.research.google.com/github/duke-sunshine/NYU-GameTheory-Summer2021/blob/main/Normal_Formal_Game_Milestone1.ipynb" target="_parent"></a>


```python
# install the tools you will use laterz
!pip install --upgrade setuptools
!pip install --upgrade pip
!pip install nashpy
```

    Requirement already satisfied: setuptools in /usr/local/lib/python3.7/dist-packages (57.1.0)
    [33mWARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv[0m
    Requirement already satisfied: pip in /usr/local/lib/python3.7/dist-packages (21.1.3)
    [33mWARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv[0m
    Requirement already satisfied: nashpy in /usr/local/lib/python3.7/dist-packages (0.0.21)
    Requirement already satisfied: scipy>=0.19.0 in /usr/local/lib/python3.7/dist-packages (from nashpy) (1.4.1)
    Requirement already satisfied: numpy>=1.12.1 in /usr/local/lib/python3.7/dist-packages (from nashpy) (1.19.5)
    [33mWARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv[0m


# Abstract the Game

## Game illustration


```python
#@title Table1: Prisoner's Dilemma
# import module
from tabulate import tabulate
table = [['','','Prisoner B',''],
         ['','','confess','deny'],
         ['Prisoner A','confess','-3,-3','0,-6'],
         ['','deny','-6,0','-1,-1']]
print(tabulate(table,tablefmt='grid'))
```

    +------------+---------+------------+-------+
    |            |         | Prisoner B |       |
    +------------+---------+------------+-------+
    |            |         | confess    | deny  |
    +------------+---------+------------+-------+
    | Prisoner A | confess | -3,-3      | 0,-6  |
    +------------+---------+------------+-------+
    |            | deny    | -6,0       | -1,-1 |
    +------------+---------+------------+-------+



```python
#@title Table1: Prisoner's Dilemma
import pandas as pd
import numpy as np
df2 = pd.DataFrame([['-3,-3','0,-6'],
                    ['-6,0','-1,-1']],
                  columns = [['Prisoner B','Prisoner B'],['confess','deny']],
                  index = [['Prisoner A','Prisoner A'],['confess','deny']])
df2
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead tr th {
        text-align: left;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr>
      <th></th>
      <th></th>
      <th colspan="2" halign="left">Prisoner B</th>
    </tr>
    <tr>
      <th></th>
      <th></th>
      <th>confess</th>
      <th>deny</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th rowspan="2" valign="top">Prisoner A</th>
      <th>confess</th>
      <td>-3,-3</td>
      <td>0,-6</td>
    </tr>
    <tr>
      <th>deny</th>
      <td>-6,0</td>
      <td>-1,-1</td>
    </tr>
  </tbody>
</table>
</div>



## Define the Game Object


```python
import nashpy as nash
import numpy as np

# Creater the game with the payoff matrix

A = np.array([[-3,0],[-6,-1]]) # A is the row player (in this case, prisoner)
B = np.array([[-3,-6],[0,-1]]) # B is the column player

game1 = nash.Game(A,B)
game1
```




    Bi matrix game with payoff matrices:
    
    Row player:
    [[-3  0]
     [-6 -1]]
    
    Column player:
    [[-3 -6]
     [ 0 -1]]



# Solve for Best Responses


```python
pip install quantecon
```

    Collecting quantecon
      Downloading quantecon-0.5.1-py3-none-any.whl (240 kB)
    [K     |████████████████████████████████| 240 kB 9.9 MB/s 
    [?25hRequirement already satisfied: numba>=0.38 in /usr/local/lib/python3.7/dist-packages (from quantecon) (0.51.2)
    Requirement already satisfied: requests in /usr/local/lib/python3.7/dist-packages (from quantecon) (2.23.0)
    Requirement already satisfied: numpy in /usr/local/lib/python3.7/dist-packages (from quantecon) (1.19.5)
    Requirement already satisfied: sympy in /usr/local/lib/python3.7/dist-packages (from quantecon) (1.7.1)
    Requirement already satisfied: scipy>=1.0.0 in /usr/local/lib/python3.7/dist-packages (from quantecon) (1.4.1)
    Requirement already satisfied: llvmlite<0.35,>=0.34.0.dev0 in /usr/local/lib/python3.7/dist-packages (from numba>=0.38->quantecon) (0.34.0)
    Requirement already satisfied: setuptools in /usr/local/lib/python3.7/dist-packages (from numba>=0.38->quantecon) (57.1.0)
    Requirement already satisfied: chardet<4,>=3.0.2 in /usr/local/lib/python3.7/dist-packages (from requests->quantecon) (3.0.4)
    Requirement already satisfied: idna<3,>=2.5 in /usr/local/lib/python3.7/dist-packages (from requests->quantecon) (2.10)
    Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /usr/local/lib/python3.7/dist-packages (from requests->quantecon) (1.24.3)
    Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.7/dist-packages (from requests->quantecon) (2021.5.30)
    Requirement already satisfied: mpmath>=0.19 in /usr/local/lib/python3.7/dist-packages (from sympy->quantecon) (1.2.1)
    Installing collected packages: quantecon
    Successfully installed quantecon-0.5.1
    [33mWARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv[0m



```python
# import the package
import quantecon.game_theory as gt
```

    /usr/local/lib/python3.7/dist-packages/numba/np/ufunc/parallel.py:363: NumbaWarning: The TBB threading layer requires TBB version 2019.5 or later i.e., TBB_INTERFACE_VERSION >= 11005. Found TBB_INTERFACE_VERSION = 9107. The TBB threading layer is disabled.
      warnings.warn(problem)



```python
coordination_game_matrix = [[4, 0],
                            [3, 2]]  # square matrix
g_Coo = gt.NormalFormGame(coordination_game_matrix)
```


```python
print(g_Coo)

```

    2-player NormalFormGame with payoff profile array:
    [[[4, 4],  [0, 3]],
     [[3, 0],  [2, 2]]]



```python
g_Coo.players[0].payoff_array  # Player 0's payoff array
```




    array([[4, 0],
           [3, 2]])




```python
g_Coo.players[1].payoff_array  # Player 1's payoff array
```




    array([[4, 0],
           [3, 2]])




```python
g_Coo.players[0].best_response(1)
```




    1




```python
g_Coo.players[0].best_response(0)
```




    0




```python
g_Coo.players[0].best_response([0.5,0.5])
```




    1



# Solve for Nash Equilibrium

## solve for the Nash Equilibrium


```python
#@title Table1: Prisoner's Dilemma
# import module
from tabulate import tabulate
table = [['','','Prisoner B',''],
         ['','','confess','deny'],
         ['Prisoner A','confess','-3,-3','0,-6'],
         ['','deny','-6,0','-1,-1']]
print(tabulate(table,tablefmt='grid'))
```

    +------------+---------+------------+-------+
    |            |         | Prisoner B |       |
    +------------+---------+------------+-------+
    |            |         | confess    | deny  |
    +------------+---------+------------+-------+
    | Prisoner A | confess | -3,-3      | 0,-6  |
    +------------+---------+------------+-------+
    |            | deny    | -6,0       | -1,-1 |
    +------------+---------+------------+-------+



```python
# find the Nash equilibrium with Support Enumeration

equilibria = game1.support_enumeration()
for eq in equilibria:
    print(eq)
```

    (array([1., 0.]), array([1., 0.]))


## calculate utility


```python
# Calculate Utilities

sigma_a = np.array([1,0])
sigma_b = np.array([1,0])
pd = nash.Game(A, B)
pd[sigma_a, sigma_b]
```




    array([-3, -3])



## abstract the game


```python
#@title Table1: Prisoner's Dilemma
# import module
from tabulate import tabulate
table = [['','','Player B',''],
         ['','','Heads','Tails'],
         ['Player A','Heads','1,-1','-1,1'],
         ['','Tails','-1,1','1,-1']]
print(tabulate(table,tablefmt='grid'))
```

    +----------+-------+----------+-------+
    |          |       | Player B |       |
    +----------+-------+----------+-------+
    |          |       | Heads    | Tails |
    +----------+-------+----------+-------+
    | Player A | Heads | 1,-1     | -1,1  |
    +----------+-------+----------+-------+
    |          | Tails | -1,1     | 1,-1  |
    +----------+-------+----------+-------+



```python
#@title Table1: Prisoner's Dilemma
import pandas as pd
import numpy as np
df2 = pd.DataFrame([['1,-1','-1,1'],
                    ['-1,1','1,-1']],
                  columns = [['Player B','Player B'],['Head','Tail']],
                  index = [['Player A','Player A'],['Head','Tail']])
df2
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead tr th {
        text-align: left;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr>
      <th></th>
      <th></th>
      <th colspan="2" halign="left">Player B</th>
    </tr>
    <tr>
      <th></th>
      <th></th>
      <th>Head</th>
      <th>Tail</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th rowspan="2" valign="top">Player A</th>
      <th>Head</th>
      <td>1,-1</td>
      <td>-1,1</td>
    </tr>
    <tr>
      <th>Tail</th>
      <td>-1,1</td>
      <td>1,-1</td>
    </tr>
  </tbody>
</table>
</div>



## Define the Game Object

# Example 1: Matching Pennies


```python
import nashpy as nash
import numpy as np

# Creater the game with the payoff matrix

A = np.array([[1,-1],[-1,1]]) # A is the row player (in this case, prisoner)
B = np.array([[-1,1],[1,-1]]) # B is the column player

game2 = nash.Game(A,B)
game2
```




    Zero sum game with payoff matrices:
    
    Row player:
    [[ 1 -1]
     [-1  1]]
    
    Column player:
    [[-1  1]
     [ 1 -1]]



## calculating best response


```python
matching_pennies_bimatrix = [[(1, -1), (-1, 1)],
                             [(-1, 1), (1, -1)]]
g_MP = gt.NormalFormGame(matching_pennies_bimatrix)
```


```python
print(g_MP)
```

    2-player NormalFormGame with payoff profile array:
    [[[ 1, -1],  [-1,  1]],
     [[-1,  1],  [ 1, -1]]]



```python
print(g_MP.players[0])  # Player instance for player 0
```

    Player in a 2-player normal form game with payoff array:
    [[ 1, -1],
     [-1,  1]]



```python
print(g_MP.players[1])  # Player instance for player 1
```

    Player in a 2-player normal form game with payoff array:
    [[-1,  1],
     [ 1, -1]]



```python
g_MP.players[0].payoff_array  # Player 0's payoff array
```




    array([[ 1, -1],
           [-1,  1]])




```python
g_MP.players[1].payoff_array  # Player 1's payoff array
```




    array([[-1,  1],
           [ 1, -1]])




```python
g_MP[0, 0]  # payoff profile for action profile (0, 0)
```




    array([ 1, -1])




```python
g_MP.players[0].best_response(1)
```




    1




```python
# By default, returns the best response action with the smallest index
g_MP.players[0].best_response([0.5, 0.5])
```




    0




```python
# With tie_breaking='random', returns randomly one of the best responses
g_MP.players[0].best_response([0.5, 0.5], tie_breaking='random')  # Try several times
```




    1




```python

# With tie_breaking=False, returns an array of all the best responses
g_MP.players[0].best_response([0.5, 0.5], tie_breaking=False)
```




    array([0, 1])




```python
g_MP.is_nash(([0.5, 0.5], [0.5, 0.5]))
```




    True




```python
g_MP.is_nash((0, 0))
```




    False




```python
g_MP.is_nash((0, [0.5, 0.5]))
```




    False



## Solve for Nash Equilibrium


```python
# find the Nash equilibrium with Support Enumeration

equilibria = game2.support_enumeration()
for eq in equilibria:
    print(eq)
```

    (array([0.5, 0.5]), array([0.5, 0.5]))



```python
def print_pure_nash_brute(g):
    """
    Print all pure Nash equilibria of a normal form game found by brute force.
    
    Parameters
    ----------
    g : NormalFormGame
    
    """
    NEs = gt.pure_nash_brute(g)
    num_NEs = len(NEs)
    if num_NEs == 0:
        msg = 'no pure Nash equilibrium'
    elif num_NEs == 1:
        msg = '1 pure Nash equilibrium:\n{0}'.format(NEs)
    else:
        msg = '{0} pure Nash equilibria:\n{1}'.format(num_NEs, NEs)

    print('The game has ' + msg)
```


```python
print_pure_nash_brute(g_MP)
```

    The game has no pure Nash equilibrium


## Caculating the Utility


```python
# Calculate Utilities

sigma_a = np.array([0.5,0.5])
sigma_b = np.array([0.5,0.5])
pd = nash.Game(A, B)
pd[sigma_a, sigma_b]
```




    array([0., 0.])




```python

```

b0becc6c218678685ec4aa55a234ee5e00f314e2
ipynb
Jupyter Notebook
Normal_Formal_Game_Milestone1.ipynb
duke-sunshine/NYU-GameTheory-Summer2021
c79727c058b24fda85fefe10f2caafea103e4dec
MIT
Normal_Formal_Game_Milestone1.ipynb
duke-sunshine/NYU-GameTheory-Summer2021
c79727c058b24fda85fefe10f2caafea103e4dec
MIT
Normal_Formal_Game_Milestone1.ipynb
duke-sunshine/NYU-GameTheory-Summer2021
c79727c058b24fda85fefe10f2caafea103e4dec
MIT
Qwen/Qwen-72B
1. YES
2. YES