- Introduction
- Prerequisites and building
- Creating Matches
- Running the Tournament
- Adding Your Strategy
- Testing
- Contributing
- Acknowledgments
Welcome to the implementation of Axelrod's Iterated Prisoner's Dilemma Tournament! This repository contains the code (in C++) for simulating and participating in the famous Axelrod's Iterated Prisoner's Dilemma (IPD) Tournament. The tournament is a classic example in game theory, where participants (strategies) compete against each other in a series of repeated prisoner's dilemma games.
The only prerequisites for library are CMake 3.22+ and a C++20 (and MinGW if you are going to use makefile) compiler.
Building:
$ mkdir build
$ cd build
$ cmake .. -G"MinGW Makefiles" # or use ony generator you want
$ make shakhbat_pd_lib
After a successful compilation The library should reside in ./lib
directory as libshakhbat_pd_lib.a
.
Use this command to copy the static library and include headers in the package
folder.
$ make install
In the package
folder will be libshakhbat_pd_lib.a
and include
folder.
You need to include include\shakhbat_pd.hpp
and static link libshakhbat_pd_lib.a
into your project.
Running :
$ make play
This will link (and build if not builded) the library with play.cpp
, and produce play.exe
which you can run
You can create your own match between two strategies using the qlm::Match
function.
// first strategy
qlm::FirstByJoss strategy_0;
// second strategy
qlm::TitForTat strategy_1;
// match parameters
const unsigned int num_rounds = 15;
const qlm::PayOff pay_off {}; // default pay off
const int seed = 0; // seed for probabilistic strategies
qlm::MatchResult match = qlm::Match(strategy_0, strategy_1, num_rounds, pay_off, seed);
// print results
match.Print();
// save results as csv file
match.SaveAsCSV("match_results.csv");
The output :
First by Joss: 0.9 VS TitForTat
Match result of 15 rounds :
First by Joss: 0.9 Wins ,Score : 42
TitForTat Losses ,Score : 37
| Round | First by Joss: 0.9 | TitForTat |
| ----- | ------------------ | --------- |
| 0 | COOPERATE | COOPERATE |
| 1 | COOPERATE | COOPERATE |
| 2 | COOPERATE | COOPERATE |
| 3 | COOPERATE | COOPERATE |
| 4 | DEFECT | COOPERATE |
| 5 | COOPERATE | DEFECT |
| 6 | DEFECT | COOPERATE |
| 7 | COOPERATE | DEFECT |
| 8 | DEFECT | COOPERATE |
| 9 | COOPERATE | DEFECT |
| 10 | DEFECT | COOPERATE |
| 11 | COOPERATE | DEFECT |
| 12 | DEFECT | COOPERATE |
| 13 | COOPERATE | DEFECT |
| 14 | DEFECT | COOPERATE |
| ----- | ------------------ | --------- |
To run the Axelrod's Iterated Prisoner's Dilemma Tournament
To add your own strategy to compete in the tournament, follow these steps:
- Write your strategy as a class publicly internets from
Strategy
and place the declaration instrategies.hpp
- If you only need the
constructor
,Reset
,FirstAction
, andAction
function to be written (most probably), then use this macro- DECLARE_STRATEGY(MyStrategy, n); // n is the number of flags you want
std::bitset<n> flags
- DECLARE_STRATEGY(MyStrategy, n); // n is the number of flags you want
- In the constructor you initialize the information of your strategy :
name
,info
,properties
. - The
FirstAction
will be called when your strategy starts first. - The
Action
is your action function and will take the opponent action as input and you access the history of actions. - you can use this function
void UpdateHistory(const Choice my_play, const Choice opponent_play)
to update history insideAction
function. - Make CPP file with your class name
MyStrategy.cpp
insidesource/strategies
and write the implementation there.
The testing process involves a comparison between strategies playing against each other in this C++ library and the and Axelrod Python library.
The results (winner, score, actions) are generated by both libraries and compared to ensure consistency.
Before running the tests, make sure you have the Axelrod library
Compile the C++ library and run the test
$ make
$ make run_test
Inside Axelrod.py add the strategy to the list strategy_list
.
strategy_list = [axl.Cooperator(), ... , axl.YourNewStrategy()]
Inside shakhbat_pd_test.cpp push the strategy to the vector FillStrategies
.
void FillStrategies()
{
ADD_STRATEGY(qlm::Cooperator);
.
.
.
ADD_STRATEGY(qlm::YourNewStrategy);
}
The python list and CPP vector must have the same number of strategies and in the same order.
If you would like to contribute to this project, please fork the repository, make your changes, and submit a pull request. Contributions are welcome!
Axelrod, r. (1980a). effective choice in the prisoner’s dilemma