Simulating P vs. G#
Following on from the previous section, we would like to be able to construct a way to simulate the Police vs. Guerrillas game. The functions below will create the correct game matrix and will calculate the winning percentages of the various strategies.
Based upon the winning percentages, the simulation will choose from the strategies that have performed best in the past. Using an exponential moving average (ema), the winning percentages will be updated after each round of simulation. The convergence to the correct strategy mixture for each player will be sped up as the ema will emphasize recent results over the older, less accurate results.
The simulation functions are described further below. The next code block will initialize python and load the packages we need.
Setting up the Game#
When playing Police vs. Guerrillas, we would like functions that create the correct game matrix given any values of
where, as discussed above, we have:
We will initialize the values we need:
\(p\) : number of police units
\(g\) : number of guerrilla units
\(\alpha\) : the memory factor for the exponential moving average
The player dictionaries will be created based upon the specific values of \(p\) and \(g\), and two functions will help accomplish the task:
create_players_dict()
game_matrix()
Dictionaries and Game Matrix Layout#
The create_player_dict() function creates player dictionaries that keep track of the following:
Row-Column indexes in the results table,
Strategy numbers (integers), and
Strategy names.
The game_matrix() function takes the players and their strategies as configured above, and from there develops a tenative outline of the game including initial values for the outcomes.
The code for both functions can be collapsed or expanded below:
Setting Up the Game#
The functions above work only if the values for \(p\) and \(g\) are known. If so, the player dictionaries and initial game matrix can be developed quickly. The code to do so is given below:
# Setting number of Police and Guerrillas to p and g respectively
p = 5
g = 4
# Creating the dictionaries
P = create_player_dict('P', p)
G = create_player_dict('G', g)
# Creating the game matrix
results = game_matrix(P,G)
results.style.set_caption(f"<b>{p} Police vs. {g} Guerrillas</b>").format(precision=1)
| 2 - 2 | 3 - 1 | 4 - 0 | |
|---|---|---|---|
| 3 - 2 | 0.5 | 0.5 | 0.5 |
| 4 - 1 | 0.5 | 0.5 | 0.5 |
| 5 - 0 | 0.5 | 0.5 | 0.5 |
We can access the \((i,j)\) entry in the matrix above using the pandas method
We can also use
if we know the column strategy or row strategy indentifier.
Play() Function#
The interior entries of the results dataframe will be winning percentages of the row and column strategies when played against one another. To calculate the outcomes for the interior of the dataframe, we begin by playing each column strategy against each row strategy in \(10,000\) simulated battles. The play() function code is given below.
The function above will be used in a nested for-loop to calculate the needed values and assign them to the correct entry in the results dataframe. The code below accomplishes the initialization of the results table created above.
Game Matrix: 5 Police vs. 4 Guerrillas#
p = 5
g = 4
P = create_player_dict('P', p)
G = create_player_dict('G', g)
results = game_matrix(P,G)
for i in P['index']:
for j in G['index']:
results.loc[P['strat_name'][i],G['strat_name'][j]] = play(p,g, int(P['strat_name'][i][0]),int(G['strat_name'][j][0]))
results.style.set_caption(f"<b>{p} Police vs. {g} Guerrillas</b>").format(precision=1)
| 2 - 2 | 3 - 1 | 4 - 0 | |
|---|---|---|---|
| 3 - 2 | 1 | 1/2 | 0 |
| 4 - 1 | 0 | 1/2 | 1/2 |
| 5 - 0 | 0 | 0 | 1/2 |
Game Matrix: 3 Police vs. 2 Guerrillas#
Using all the above user-defined functions, we can quickly create the new game matrix:
p = 3
g = 2
P = create_player_dict('P', p)
G = create_player_dict('G', g)
results = game_matrix(P,G)
for i in P['index']:
for j in G['index']:
results.loc[P['strat_name'][i],G['strat_name'][j]] = play(p,g, int(P['strat_name'][i][0]),int(G['strat_name'][j][0]))
results.style.set_caption(f"<b>{p} Police vs. {g} Guerrillas</b>").format(precision=1)
| 1 - 1 | 2 - 0 | |
|---|---|---|
| 2 - 1 | 1 | 1/2 |
| 3 - 0 | 0 | 1/2 |
Game Matrix: 7 Police vs. 5 Guerrillas#
p = 7
g = 5
P = create_player_dict('P', p)
G = create_player_dict('G', g)
results = game_matrix(P,G)
for i in P['index']:
for j in G['index']:
results.loc[P['strat_name'][i],G['strat_name'][j]] = play(p,g, int(P['strat_name'][i][0]),int(G['strat_name'][j][0]))
results.style.set_caption(f"<b>{p} Police vs. {g} Guerrillas</b>").format(precision=1)
| 3 - 2 | 4 - 1 | 5 - 0 | |
|---|---|---|---|
| 4 - 3 | 1 | 1/2 | 0 |
| 5 - 2 | 1/2 | 1/2 | 1/2 |
| 6 - 1 | 0 | 1/2 | 1/2 |
| 7 - 0 | 0 | 0 | 1/2 |