-
Notifications
You must be signed in to change notification settings - Fork 0
/
game.jl
107 lines (87 loc) · 2.61 KB
/
game.jl
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
include("./network_generator.jl")
module Game
using StatsBase, Statistics, LightGraphs
using ..NetworkGenerator
export Model, choose_initial_cooperators, initialize_strategy!, count_payoff!, pairwise_fermi!, count_fc
mutable struct Agent
strategy::Symbol
payoff::Float64
neighbors_id::Vector{Int}
Agent(neighbors_id::Vector{Int}) = new(
Symbol(""),
0.0,
neighbors_id
)
end
mutable struct Model
initial_cooperators::Vector{Int}
agents::Vector{Agent}
end
function Model(topology:: SimpleGraph, initial_cooperators::Vector{Int})
all_neighbors = NetworkGenerator.get_all_neighbors(topology)
model = Model(
initial_cooperators,
[Agent(neighbors_id) for neighbors_id in all_neighbors]
)
return model
end
struct PayoffMatrix
dg::Float64
dr::Float64
R::Float64
S::Float64
T::Float64
P::Float64
PayoffMatrix(dg::Float64, dr::Float64) = new(
dg,
dr,
1.0,
-dr,
1.0 + dg,
0.0
)
end
function choose_initial_cooperators(population::Int)
initial_cooperators = StatsBase.self_avoid_sample!(1:population, collect(1:div(population, 2)))
return initial_cooperators
end
function initialize_strategy!(model::Model)
for (id, agent) in enumerate(model.agents)
if id in model.initial_cooperators
agent.strategy = :C
else
agent.strategy = :D
end
end
end
function count_payoff!(model::Model, payoff_matrix::PayoffMatrix)
for agent in model.agents
agent.payoff = 0.0
for nb_id in agent.neighbors_id
neighbor = model.agents[nb_id]
if agent.strategy == :C && neighbor.strategy == :C
agent.payoff += payoff_matrix.R
elseif agent.strategy == :D && neighbor.strategy == :C
agent.payoff += payoff_matrix.T
elseif agent.strategy == :C && neighbor.strategy == :D
agent.payoff += payoff_matrix.S
elseif agent.strategy == :D && neighbor.strategy == :D
agent.payoff += payoff_matrix.P
end
end
end
end
function pairwise_fermi!(model::Model)
for agent in model.agents
opponent_id = rand(agent.neighbors_id)
neighbor = model.agents[opponent_id]
if neighbor.strategy != agent.strategy && rand() < 1 / ( 1 + exp((agent.payoff - neighbor.payoff) / 0.1 ) )
agent.strategy = neighbor.strategy
end
end
end
function count_fc(model::Model)
fc = [ifelse(agent.strategy == :C, 1, 0) for agent in model.agents] |> Statistics.mean
return fc
end
end