forked from HolaHansi/game_theory
-
Notifications
You must be signed in to change notification settings - Fork 0
/
test_game_representations.py
163 lines (139 loc) · 6.34 KB
/
test_game_representations.py
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
import unittest
import random as r
import math
from games import NormalFormGame, SecurityGame
class TestHarsanyiTransformation(unittest.TestCase):
@staticmethod
def _combinations(n, r):
"""
Compute number of n, r combinations w.o. replacement
"""
f = math.factorial
return f(n) // f(r) // f(n-r)
def setUp(self):
"""
1) Generate a bayesian security game, turn it into normal form,
and generate the harsanyi transformed normal form.
2) Generate a bayesian normal form game, generate harsanyi transformed
normal form game.
"""
self.sec_game = SecurityGame(10,3,2)
self.sec_norm_game = NormalFormGame(game=self.sec_game,
harsanyi=False)
self.sec_norm_hars_game = NormalFormGame(game=self.sec_norm_game)
# generate bayesian game
self.bayse_norm_game = NormalFormGame(num_defender_strategies=5,
num_attacker_strategies=10,
num_attacker_types=3)
self.bayse_norm_hars_game = NormalFormGame(game= self.bayse_norm_game)
def tearDown(self):
pass
def test_dimensions(self):
"""
Test if dimensions on transformed representations are correct
"""
# sec_game -> sec_norm_game
self.assertSequenceEqual(
(
self.sec_norm_game.num_defender_strategies,
self.sec_norm_game.num_attacker_strategies,
self.sec_norm_game.num_attacker_types
),
(
self._combinations(self.sec_game.num_targets,
self.sec_game.max_coverage),
self.sec_game.num_targets,
self.sec_game.num_attacker_types
),
msg="sec_norm_game dimensions are not correct")
# sec_norm_game -> sec_norm_hars_game
self.assertSequenceEqual(
(
self.sec_norm_hars_game.num_defender_strategies,
self.sec_norm_hars_game.num_attacker_strategies,
self.sec_norm_hars_game.num_attacker_types
),
(
self.sec_norm_game.num_defender_strategies,
self.sec_norm_game.num_attacker_strategies ** \
self.sec_norm_game.num_attacker_types,
1
),
msg="sec_norm_hars_game dimensions are not correct"
)
# bayse_norm_game -> bayse_norm_hars_game
self.assertSequenceEqual(
(
self.bayse_norm_hars_game.num_defender_strategies,
self.bayse_norm_hars_game.num_attacker_strategies,
self.bayse_norm_hars_game.num_attacker_types,
),
(
self.bayse_norm_game.num_defender_strategies,
self.bayse_norm_game.num_attacker_strategies ** \
self.bayse_norm_game.num_attacker_types,
1
),
msg="bayse_norm_hars_game dimensions are not correct"
)
def test_payoffs_sec_norm_game(self):
"""
Test if payoffs have been computed correctly for sec_norm_game
"""
# repeat test 10 times
for test_no in range(10):
# generate random coordinates
i = r.randrange(0, self.sec_norm_game.num_defender_strategies)
j = r.randrange(0, self.sec_norm_game.num_attacker_strategies)
k = r.randrange(0, self.sec_norm_game.num_attacker_types)
# get coverage corresponding to defender strategy i
covered_targets = self.sec_norm_game.defender_coverage_tuples[i]
if j in covered_targets:
correct_def_payoff = self.sec_game.defender_covered[j, k]
correct_att_payoff = self.sec_game.attacker_covered[j, k]
else:
correct_def_payoff = self.sec_game.defender_uncovered[j, k]
correct_att_payoff = self.sec_game.attacker_uncovered[j, k]
# get payoffs for random coordinates
sec_norm_def_payoff = self.sec_norm_game.defender_payoffs[i,j,k]
sec_norm_att_payoff = self.sec_norm_game.attacker_payoffs[i,j,k]
self.assertAlmostEqual(sec_norm_def_payoff,
correct_def_payoff,
msg="sec_norm_game: defender payoff is wrong")
self.assertAlmostEqual(sec_norm_att_payoff,
correct_att_payoff,
msg="sec_norm_game: attacker payoff is wrong")
def test_payoffs_sec_norm_hars_game(self):
"""
Test if payoffs have been computed correctly for sec_norm_hars_game
"""
# repeat test 10 times
for test_no in range(10):
# generate random coordinates
i = r.randrange(0, self.sec_norm_hars_game.num_defender_strategies)
j = r.randrange(0, self.sec_norm_hars_game.num_attacker_strategies)
# get attacker pure strategy tuple corresponding to attacker
# strategy j
attacker_pure_strategy_tuple = \
self.sec_norm_hars_game.attacker_pure_strategy_tuples[j]
# compute correct payoffs
correct_def_payoff = 0
correct_att_payoff = 0
for k, j_p in enumerate(attacker_pure_strategy_tuple):
correct_def_payoff += \
self.sec_norm_game.defender_payoffs[i,j_p,k] * \
self.sec_norm_game.attacker_type_probability[k]
correct_att_payoff += \
self.sec_norm_game.attacker_payoffs[i,j_p,k] * \
self.sec_norm_game.attacker_type_probability[k]
# get payoffs for random coordinates
hars_def_payoff = self.sec_norm_hars_game.defender_payoffs[i,j,0]
hars_att_payoff = self.sec_norm_hars_game.attacker_payoffs[i,j,0]
self.assertAlmostEqual(hars_def_payoff,
correct_def_payoff,
msg="sec_norm_hars_game: def payoff wrong")
self.assertAlmostEqual(hars_att_payoff,
correct_att_payoff,
msg="sec_norm_hars_game: att payoff wrong")
if __name__ == '__main__':
unittest.main()