This repository was archived by the owner on Aug 29, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwerewolf.py
142 lines (113 loc) · 4.84 KB
/
werewolf.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
from role import Role
def get_allowed_variance(player_count):
return (player_count / 4) + 1
def is_valid(roles, allow_cult, allow_tanner, allow_fool):
num_players = len(roles)
if num_players < 5:
return False
if (not allow_cult or num_players < 11) and (Role.Cultist in roles or
Role.CultistHunter in roles):
return False
if not allow_tanner and Role.Tanner in roles:
return False
if not allow_fool and Role.Fool in roles:
return False
if (Role.Sorcerer in roles or Role.Traitor in roles) and not any(
wolf in roles for wolf in Role.wolves()):
return False
if Role.ApprenticeSeer in roles and Role.Seer not in roles:
return False
if Role.Cultist in roles and Role.CultistHunter not in roles:
return False
if not any(enemy in roles for enemy in Role.enemies()):
return False
return True
def get_village_strength(roles):
village_strength = 0
village_roles = [role for role in roles if (role not in
Role.non_villagers())]
for role in village_roles:
village_strength += role.strength(roles)
return village_strength
def get_non_village_strength(roles):
non_village_strength = 0
non_village_roles = [role for role in roles if (role in
Role.non_villagers())]
for role in non_village_roles:
non_village_strength += role.strength(roles)
return non_village_strength
def is_balanced(roles):
village_strength = get_village_strength(roles)
non_village_strength = get_non_village_strength(roles)
final_strength = abs(village_strength - non_village_strength)
return (final_strength <= get_allowed_variance(len(roles)))
def get_possible(role, players, config):
wanted = set()
if role not in players['certain']:
for i, _ in enumerate(players['uncertain']):
current_projection = players['uncertain'][:]
current_projection[i] = role
for j, curr_role in enumerate(players['uncertain']):
if i == j:
continue
c2 = current_projection[:]
for non_villager in Role.non_villagers():
if non_villager == role:
continue
c2[j] = non_villager
valid = is_valid(c2 + players['certain'],
config['allow_cult'], config['allow_tanner'],
config['allow_fool'])
balanced = config['chaos'] or is_balanced(c2 + players['certain'])
if(valid and balanced):
wanted.add(curr_role)
return wanted
def project_truth(players, config):
assert(config['player_count'] == len(players['certain']) + len(players['uncertain']))
print("Certain players: " + str(players['certain']))
print("Uncertain players: " + str(players['uncertain']) + "\n")
print("Safe:")
for player in players['certain']:
print("-> " + str(player))
print("")
if len(players['uncertain']) == 0:
print("No uncertainty to be projected, game is over.")
return
elif len(players['uncertain']) == 1:
print("No uncertainty to be projected.")
print("Enemy is " + str(players['uncertain']))
return
fakers = {}
for i, role in enumerate(players['uncertain']):
current_projection = players['uncertain'][:]
for possible_role in Role.non_villagers():
current_projection[i] = possible_role
valid = is_valid(current_projection + players['certain'],
config['allow_cult'], config['allow_tanner'],
config['allow_fool'])
balanced = config['chaos'] or is_balanced(current_projection + players['certain'])
if(valid and balanced):
if role not in fakers:
fakers[role] = set()
fakers[role].add(possible_role)
if not fakers:
print("The given roles made it impossible to predict. Too much unreliability.")
return
bad_roles = [Role.Tanner, Role.Sorcerer, Role.Cursed, Role.Traitor,
Role.WildChild]
for role in bad_roles:
for rr in get_possible(role, players, config):
if rr not in fakers:
fakers[rr] = set()
fakers[rr].add(role)
probably_safe_players = [x for x in players['uncertain'] if x not in fakers.keys()]
print("Probably safe:")
for psp in probably_safe_players:
print("-> " + str(psp) + ";")
print("")
print("Possibly fake:")
for faker, possibilities in fakers.items():
print("-> " + str(faker) + ";")
for i, p in enumerate(possibilities):
print(" => (" + str(i) + ") " + str(p) + (" *" if p in Role.enemies() else ""))
print("")