forked from ehauckdo/AIWoof
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathroleEstimations.py
170 lines (113 loc) · 4.97 KB
/
roleEstimations.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
164
165
166
167
168
169
170
from __future__ import division
from toolbox import *
def updateRoleEstimations(tracker):
#Copy the role map given at beginning of the game, calculate the team map
roleMap = dict(tracker.gameCompo)
teamMap = countTeam(roleMap)
#Initialize empty probability vector
voidRoleVector = dict(roleMap)
for role in voidRoleVector:
voidRoleVector[role] = 0
voidTeamVector = {'HUMAN':0, 'WEREWOLF':0}
#Set probabilities when role is known
#+ remove known roles from current maps
for id in tracker.profiles:
profile = tracker.profiles[id]
if profile['roleKnown'] and profile['teamKnown']:
role = profile['role']
team = role2divined[role] #Important: We consider teams given by a divined action
#1 for the role, 0 for the other
roleVector = dict(voidRoleVector)
roleVector[role] = 1
profile['roleProba'] = roleVector
#1 for the team, 0 for the other
teamVector = dict(voidTeamVector)
teamVector[team] = 1
profile['teamProba'] = teamVector
#remove role and team from the list of unknown attributions
roleMap[role] -= 1
teamMap[team] -= 1
for id in tracker.profiles:
profile = tracker.profiles[id]
if not profile['roleKnown'] and profile['teamKnown']:
team = profile['team']
#Counting the reamining roles for the known team
roleVector = filterTeam(roleMap, team)
totalTeam = totalDict(roleVector)
for role in roleVector:
number = roleVector[role]
#Avoid dividing by zero
if number == 0 or totalTeam == 0:
roleVector[role] = 0
else:
#Probability of being this role, knowing we're in the current team
roleVector[role] = number / totalTeam
profile['roleProba'] = roleVector
teamVector = dict(voidTeamVector)
teamVector[team] = 1
profile['teamProba'] = teamVector
#Remove team member from the list of unknown team attributions
teamMap[team] -= 1
#Calculate probabilities when role is unknown
for id in tracker.profiles:
profile = tracker.profiles[id]
if not profile['roleKnown'] and not profile['teamKnown']:
teamVector = {'HUMAN': 0,'WEREWOLF': 0}
totalTeam = totalDict(teamMap)
if totalTeam > 0:
teamVector['WEREWOLF'] = teamMap['WEREWOLF']/totalTeam
teamVector['HUMAN'] = teamMap['HUMAN']/totalTeam
conditionalRoleVector = {}
conditionalRoleVector['HUMAN'] = filterTeam(roleMap, 'HUMAN')
conditionalRoleVector['WEREWOLF'] = filterTeam(roleMap, 'WEREWOLF')
totalRoleMap = totalDict(roleMap)
for team in conditionalRoleVector:
for role in conditionalRoleVector[team]:
conditionalRoleVector[team][role] /= totalRoleMap
roleVector = dict(voidRoleVector)
for role in roleVector:
for team in teamVector:
#Bayesian probability
roleVector[role] += conditionalRoleVector[team][role]*teamVector[team]
profile['teamProba'] = teamVector
profile['roleProba'] = roleVector
checkRoleDeductions(tracker)
def countTeam(roleMap):
#Count number of humans and wolves in a role map
teamMap = {'HUMAN':0, 'WEREWOLF':0}
for role in roleMap:
team = role2divined[role]
if team in teamMap:
teamMap[team] += roleMap[role]
return teamMap
def filterTeam(roleMap, team):
#Keep only the roles from a specific team in a role map
filtered = dict(roleMap)
for role in filtered:
if not role2divined[role] == team:
filtered[role] = 0
return filtered
def checkRoleDeductions(tracker):
#Deduce team and roles based on probabilities
didDeductions = False
for id in tracker.profiles:
profile = tracker.profiles[id]
#Check if we can guess the team based on probabilities
if profile['teamKnown'] == False:
for team in profile['teamProba']:
if(profile['teamProba'][team] == 1):
profile['team'] = team
profile['teamKnown'] = True
didDeductions = True
#Check if we can guess the role based on probabilities
if profile['roleKnown'] == False:
for role in profile['roleProba']:
#Deducted team
if profile['roleProba'][role] == 1:
team = role2divined[role]
profile['roleKnown'] = True
profile['role'] = role
didDeductions = True
#If we made deductions, recalculate probabilities
if didDeductions :
updateRoleEstimations(tracker)