-
Notifications
You must be signed in to change notification settings - Fork 1
/
seer.py
executable file
·99 lines (89 loc) · 4.64 KB
/
seer.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
from collections import deque
from typing import Deque, List, Optional
from aiwolf import (Agent, ComingoutContentBuilder, Content,
DivinedResultContentBuilder, GameInfo, GameSetting, Judge,
Role, Species, Vote, VoteContentBuilder)
from aiwolf.constant import AGENT_NONE
from const import CONTENT_SKIP
from villager import HyunjiVillager
class HyunjiSeer(HyunjiVillager):
co_date: int # Scheduled comingout date.
has_co: bool # Whether or not comingout has done.
my_judge_queue: Deque[Judge] # Queue of divination results.
not_divined_agents: List[Agent] # Agents that have not been divined.
werewolves: List[Agent] # Found werewolves.
vote_talk: List[Vote] # Talk containing VOTE.
voted_reports: List[Vote] # Time series of voting reports.
request_vote_talk: List[Vote] # Talk containing REQUEST VOTE.
def __init__(self) -> None:
super().__init__()
self.co_date = 0
self.has_co = False
self.my_judge_queue = deque()
self.not_divined_agents = []
self.werewolves = []
self.vote_talk = []
self.voted_reports = []
self.request_vote_talk = []
def initialize(self, game_info: GameInfo, game_setting: GameSetting) -> None:
super().initialize(game_info, game_setting)
self.co_date = 3
self.has_co = False
self.my_judge_queue.clear()
self.not_divined_agents = self.get_others(self.game_info.agent_list)
self.werewolves.clear()
self.vote_talk.clear()
self.voted_reports.clear()
self.request_vote_talk.clear()
def day_start(self) -> None:
super().day_start()
judge: Optional[Judge] = self.game_info.divine_result
if judge is not None:
self.my_judge_queue.append(judge)
if judge.target in self.not_divined_agents:
self.not_divined_agents.remove(judge.target)
if judge.result == Species.WEREWOLF:
self.werewolves.append(judge.target)
def talk(self) -> Content:
# The list of agents that voted for me in the last turn.
voted_for_me: List[Agent] = [j.agent for j in self.voted_reports if j.target == self.me]
# The list of agents that said they would vote for me.
vote_talk_for_me: List[Agent] = [j.agent for j in self.vote_talk if j.target == self.me]
# The list of agents that requested to vote for me.
request_vote_for_me: List[Agent] = [j.agent for j in self.request_vote_talk if j.target == self.me]
# Do comingout if it's on scheduled day or a werewolf is found.
if not self.has_co and (self.game_info.day == self.co_date or self.werewolves):
self.has_co = True
return Content(ComingoutContentBuilder(self.me, Role.SEER))
# Report the divination result after doing comingout.
if self.has_co and self.my_judge_queue:
judge: Judge = self.my_judge_queue.popleft()
return Content(DivinedResultContentBuilder(judge.target, judge.result))
# Vote for one of the alive werewolves.
candidates: List[Agent] = self.get_alive(self.werewolves)
# Vote for one of the alive fake seers if there are no candidates.
if not candidates:
candidates = self.get_alive([a for a in self.comingout_map
if self.comingout_map[a] == Role.SEER])
# Vote for one of the alive agents that can vote for me this turn.
if not candidates:
candidates = self.get_alive_others(vote_talk_for_me)
# Vote for one of the alive agents that requested to vote for me this turn.
if not candidates:
candidates = self.get_alive_others(request_vote_for_me)
# Vote for one of the alive agents that voted for me in the last turn.
if not candidates:
candidates = self.get_alive(voted_for_me)
# Vote for one of the alive agents if there are no candidates.
if not candidates:
candidates = self.get_alive_others(self.game_info.agent_list)
# Declare which to vote for if not declare yet or the candidate is changed.
if self.vote_candidate == AGENT_NONE or self.vote_candidate not in candidates:
self.vote_candidate = self.random_select(candidates)
if self.vote_candidate != AGENT_NONE:
return Content(VoteContentBuilder(self.vote_candidate))
return CONTENT_SKIP
def divine(self) -> Agent:
# Divine a agent randomly chosen from undivined agents.
target: Agent = self.random_select(self.not_divined_agents)
return target if target != AGENT_NONE else self.me