benjjo / game_theory

A practical look at the Axelrod tournament.

Home Page:https://www.youtube.com/watch?v=mScpHTIi-kM

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Game Theory - Axelrod Tournament

This Python program simulates a tournament in the vein of the Axelrod Tournament, where different strategies compete against each other in the game of the Prisoner's Dilemma. Strategies include TitForTat and AlwaysDefect for example. This Tournament is an attempt to replicate and help understand the works of "Strategies for the Iterated Prisoner’s Dilemma" (Anagh Malik, 2020), and is heavily influenced by the Youtube channel Veritasium and their presentation "What The Prisoner's Dilemma Reveals About Life, The Universe, and Everything".

The key component to replicating the results presented in the Veritasium presentation is the random error generator. This is to simulate false positives/negatives to simulate real world situations. Veritasium use the example: "On 26 September 1983, during the Cold War, the Soviet nuclear early warning system Oko reported the launch of one intercontinental ballistic missile with four more missiles behind it, from the United States. Petrov, suspecting a false alarm, decided to wait for a confirmation that never came."

This is a work in progress and created out of curiosity. The end goal is to simply replicate the results of the Axelrod Tournament and setup some simple python code for others to expand on if that should tickle one's fancy.

Description

Classes GameRunner The GameRunner class runs a specified number of games between two strategies and calculates the scores.

The Tournament class orchestrates multiple GameRunner sessions for various pairs of strategies, keeping an overall tally of scores.

The Strategy class is the base class for different strategies. It includes common methods like make_choice, set_choice and get_choice. It includes common attributes including name and init_choice.

Subclass examples: TitForTat is a strategy that cooperates initially and then mimics the opponent's last move. AlwaysDefect is a strategy that always chooses to defect.

Example usage:

I simply run the prisoners_dilema.py script in a python shell to retrieve the output. Or something like PyCharm/VS-Code/Jupyter-Lab will enable you to see the output printed to the screen. The below shows the code that is tacked onto the end of the script. Update to modify the output.

from Strategies import *

# No random elements # Add more strategies as needed
strategies_non_random = [TitForTat, AlwaysDefect, GenerousTitForTat, ModalTFT, AlwaysCooperate,
                         Friedman, Graaskamp, Nydegger, DefectOnce, TitForTwoTats, WinStayLooseShift,
                         Benjo, Shubik, Downing]

# Introduced random elements
strategies_random = [TitForTat, AlwaysDefect, GenerousTitForTat, Joss, TidemanChieruzzi, Random,
                     AlwaysCooperate, Friedman, Graaskamp, Nydegger, DefectOnce, Downing,
                     TitForTwoTats, WinStayLooseShift, Benjo, Shubik, ModalTFT]

# All the strategies
strategies_all = [TitForTat, AlwaysDefect, AlwaysCooperate, GenerousTitForTat, Friedman,
                  Joss, Graaskamp, TidemanChieruzzi, Nydegger, TitForTwoTats, Random, Shubik,
                  WinStayLooseShift, Benjo, ModalTFT, ModalDefector, Downing]

# games = random.randint(200, 1000)
games = 2000

# Running games
tournament = Tournament(strategies_all, num_games_per_match=games, noise=True)  # Mess with the parameters if you want.
overall_scores = tournament.round_robin()

sorted_scores = sorted(overall_scores.items(), key=lambda x: x[1], reverse=True)
print("")
print('*'*44)
print(" Overall Scores, sorted by highest ranking:")
print('*'*44)
print(f"Number of games: {games}\n")
for strategy, score in sorted_scores:
    print(f"{strategy:>20}: {score}")
print('*'*44)

Example output

********************************************
 Overall Scores, sorted by highest ranking:
********************************************
GenerousTitForTat: 4475
TitForTat: 4067
Friedman: 4064
AlwaysDefect: 3837
AlwaysCooperate: 3832
********************************************
********************************************
 Overall Scores, sorted by highest ranking:
********************************************
Nydegger: 7852
AlwaysCooperate: 7201
GenerousTitForTat: 7157
TitForTat: 6692
Graaskamp: 6421
Friedman: 6074
AlwaysDefect: 5139
Joss: 5090
********************************************
********************************************
 Overall Scores, sorted by highest ranking:
********************************************
Number of games: 303

TitForTwoTats: 15191
Nydegger: 14571
GenerousTitForTat: 14360
AlwaysCooperate: 13977
TitForTat: 13168
Random: 13130
Graaskamp: 12810
Joss: 11382
Friedman: 11051
AlwaysDefect: 10284
********************************************
********************************************
 Overall Scores, sorted by highest ranking:
********************************************
Number of games: 2000

   GenerousTitForTat: 74207
           TitForTat: 72877
       TitForTwoTats: 72112
               Benjo: 71256
              Random: 66892
            ModalTFT: 65699
     AlwaysCooperate: 64952
   WinStayLooseShift: 64364
            Nydegger: 62681
           Graaskamp: 61749
                Joss: 60123
            Friedman: 59906
    TidemanChieruzzi: 59730
              Shubik: 59649
        AlwaysDefect: 59537
       ModalDefector: 59421
             Downing: 58230
********************************************

References

Malik, A. (2020). Strategies for the Iterated Prisoner’s Dilemma. November 2020. Retrieved from https://arxiv.org/pdf/2111.11561.pdf

Muller, D. (2023, December 24). What The Prisoner's Dilemma Reveals About Life, The Universe, and Everything. Retrieved from https://www.youtube.com/watch?v=mScpHTIi-kM

About

A practical look at the Axelrod tournament.

https://www.youtube.com/watch?v=mScpHTIi-kM


Languages

Language:Python 100.0%