-
Notifications
You must be signed in to change notification settings - Fork 3
/
plugin.cpp
82 lines (71 loc) · 2.51 KB
/
plugin.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/**
* Copyright (c) 2018 - Marcos Cardinot <marcos@cardinot.net>
*
* This source code is licensed under the MIT license found in
* the LICENSE file in the root directory of this source tree.
*/
#include "plugin.h"
namespace evoplex {
bool PDGame::init()
{
m_temptation = attr("temptation", -1.0).toDouble();
return m_temptation >=1.0 && m_temptation <= 2.0;
}
bool PDGame::algorithmStep()
{
// 1. each agent accumulates the payoff obtained by playing
// the game with all its neighbours and itself
for (Node node : nodes()) {
const int sX = node.attr(STRATEGY).toInt();
double score = playGame(sX, sX);
for (const Node& neighbour : node.outEdges()) {
score += playGame(sX, neighbour.attr(STRATEGY).toInt());
}
node.setAttr(SCORE, score);
}
std::vector<char> bestStrategies;
bestStrategies.reserve(nodes().size());
// 2. the best agent in the neighbourhood is selected to reproduce
for (const Node& node : nodes()) {
int bestStrategy = node.attr(STRATEGY).toInt();
double highestScore = node.attr(SCORE).toDouble();
for (const Node& neighbour : node.outEdges()) {
const double neighbourScore = neighbour.attr(SCORE).toDouble();
if (neighbourScore > highestScore) {
highestScore = neighbourScore;
bestStrategy = neighbour.attr(STRATEGY).toInt();
}
}
bestStrategies.emplace_back(binarize(bestStrategy));
}
// 3. prepare the next generation
size_t i = 0;
for (Node node : nodes()) {
int s = binarize(node.attr(STRATEGY).toInt());
s = (s == bestStrategies.at(i)) ? s : bestStrategies.at(i) + 2;
node.setAttr(STRATEGY, s);
++i;
}
return true;
}
// 0) cooperator; 1) new cooperator
// 2) defector; 3) new defector
double PDGame::playGame(const int sX, const int sY) const
{
switch (binarize(sX) * 2 + binarize(sY)) {
case 0: return 1.0; // CC : Reward for mutual cooperation
case 1: return 0.0; // CD : Sucker's payoff
case 2: return m_temptation; // DC : Temptation to defect
case 3: return 0.0; // DD : Punishment for mutual defection
default: qFatal("Error! strategy should be 0 or 1!");
}
}
// transform from 0|2 -> 0 (cooperator)
// 1|3 -> 1 (defector)
int PDGame::binarize(const int strategy) const
{
return (strategy < 2) ? strategy : strategy - 2;
}
} // evoplex
REGISTER_PLUGIN(PDGame)
#include "plugin.moc"