Grudges, War and Game of Thrones

Nikoleta E. Glynatsi · August 23, 2017

You will often see me talking about Game Theory. But what is Game Theory and more importantly what does it allow us to comprehend?

The right answer is many things. For example should people hold a grudge? In a war of many different parties what strategy should one use to stand victorious? Should the North and South join hands against the army of the dead?

All these questions can be answered by studying the emergence of cooperation. A topic that I am concerned with in my PhD study. The game commonly used is the famous Prisoner’s Dilemma (PD). The PD is a two player game where both players simultaneously can choose to either Cooperate or Defect. Though both sides are better off Cooperating (3) there will always be a temptation for an individual to deviate and Defect (5). The following matrix matches the players moves to payoffs.

Simulating the PD interaction is made possible thanks to an open source library called the Axelrod Python Library. The library is alive thanks to a league of extraordinary people, it is documented and tested to an extraordinarily high degree of coverage. This ensures the correctness of our results. Now that we have the basics down let us explore some scenarios!

Imagine that you are repeatedly interacting with a friend who is quite Sneaky. Your friend is cooperating with you but will also try to defect once and will repent only if punished. Should you hold a grudge against that friend? Let us create this scenario using the Axelrod library. Your friend will be playing a strategy called SneakyTitForTat and you can choose between two strategies: either hold a grudge by defecting all the way once your friend defects ( Grudger ) or after punishing your friend you can try to cooperate once again ( TitForTat ).

>>> import axelrod as axl

>>> first_match = axl.Match([axl.SneakyTitForTat(), axl.Grudger()], 
... 			    turns=20)
>>> first_match.play()[:6]
[('C', 'C'), ('C', 'C'), ('D', 'C'), ('D', 'D'), ('C', 'D'), ('C', 'D')]
>>> first_match.final_score()
(20, 55)
>>> second_match = axl.Match([axl.SneakyTitForTat(), axl.TitForTat()], 
... 			     turns=20)
>>> _ = second_match.play()
>>> second_match.final_score()
(57, 57)

In a simple match of the Iterated Prisoner's Dilemma the strategy TitForTat can be seen to score higher than Grudger. Thus, when playing against SneakyTitForTat you would be better off not holding a grudge.

Another feature of the library is simulating simplified war scenarios. In a war several players with different strategies collide in the battlefield. One can choose from over 200 strategies that are implemented within the library. Once the strategies are selected they can be placed into a tournament. Each player interacts with the rest of the players and the one with the highest average score is the winner. In the following example, six very basic strategies have been chosen and a tournament of 200 turns is repeated 5 times.

>>> import axelrod as axl

>>> axl.seed(0)
>>> players = [axl.Cooperator(), axl.Random(), axl.TitForTat(), axl.Grudger(),
...            axl.Defector()]

>>> tournament = axl.Tournament(players)
>>> results = tournament.play()
>>> results.ranked_names
['Grudger', 'Defector', 'Tit For Tat', 'Cooperator', 'Random: 0.5']

The library comes with a results summary where several measures can be explored and visualised. Such as the winner and the winning score.

>>> plot = axl.Plot(results)
>>> p = plot.boxplot()
>>> p.show()

may contain spoiler for Game of Thrones season 7

Lastly regarding the recent events of Game of Thrones season 7, should the North alliance work with the South to defeat the Night King? Evolutionary Game Theory, allows the study of such population dynamics. In this example the Moran process will be used as an evolutionary algorithm. The Moran process is a birth day process where the weakest member of one generation is replaced by a stronger individual. How are the individuals compared? They are compared based on their normalized score in a tournament against the entire population.

>>> import axelrod as axl
>>> import random

>>> N = 5
>>> players = []
>>> axl.seed(5)
>>> for _ in range(N):
...     player = random.choice([axl.Defector, axl.Cooperator])
...     players.append(player())

>>> mp = axl.MoranProcess(players=players, turns=200)
>>> mp.play()
[Counter({'Cooperator': 3, 'Defector': 2}),
 Counter({'Cooperator': 3, 'Defector': 2}),
 Counter({'Cooperator': 3, 'Defector': 2}),
 Counter({'Cooperator': 2, 'Defector': 3}),
 Counter({'Cooperator': 2, 'Defector': 3}),
 Counter({'Cooperator': 1, 'Defector': 4}),
 Counter({'Cooperator': 1, 'Defector': 4}),
 Counter({'Cooperator': 1, 'Defector': 4}),
 Counter({'Defector': 5})]
>>> p.show()

In population dynamics we do not concern ourselves with players anymore but with strategies. In our example, if two of the five lords in Westeros would always chose to defect then the rest of the lords can be seen to adapt the same behavior.

These are just simple examples of how Game Theory and the Axelrod Python Library can be used to comprehend everyday questions. There are various other scenarios that can be explored. Please find all details about the Axelord Python Library here: https://github.com/Axelrod-Python/Axelrod.

This blog post accompanies a poster which can be found here: https://nikoleta-v3.github.io/talks/talks//2017-08-28-Euroscipy/poster.pdf which was presented at Euroscipy 2017, in Erlangen Germany.

Twitter, Facebook