def edit_plan(self, action_group, action, source, targets): if self.state['phase'] != 'Night': raise ValueError('not night time') glue.run('plan', self.state_path, self.actions_path, self.plan_path, input={ 'actionGroup': action_group, 'action': action, 'source': source, 'targets': targets })
def get_deaths_view(self, turn, phase): state_path = self.state_path + '.' + phase + '.' + str(turn) state_post_path = self.state_path + '.' + \ self.get_post_suffix(phase, turn) return self.interpret_raw_deaths( glue.run('view-deaths', state_path, state_post_path))
def get_current_messages_view(self, player_id, raw_plan): state_pre_path = self.state_path + '.' + self.state['phase'].lower() + \ '.' + str(self.state['turn']) return self.interpret_messages( raw_plan, glue.run('view-messages', state_pre_path, self.state_path).get(player_id, []))
def apply_impulse(self, action_group, action, source, targets): if self.state['phase'] != 'Day': raise ValueError('not day time') glue.run('impulse', self.state_path, self.actions_path, self.plan_path, input={ 'actionGroup': action_group, 'action': action, 'source': source, 'targets': targets }) self.load_state() self.load_players()
def modkill(self, target, reason): glue.run('modkill', self.state_path, self.plan_path, input={ 'target': next( player_id for player_id, player in self.meta['players'].items() if player['name'] == target), 'reason': reason, 'modifyPlan': self.state['phase'] == 'Night' }) self.load_state() self.load_players()
def get_messages_view(self, turn, phase, player_id, raw_plan): state_path = self.state_path + '.' + phase + '.' + str(turn) state_post_path = self.state_path + '.' + \ self.get_post_suffix(phase, turn) return self.interpret_messages( raw_plan, glue.run('view-messages', state_path, state_post_path).get(player_id, []))
def run_night(self): plan_path = self.plan_path + '.night.' + str(self.state['turn']) actions_path = self.actions_path + '.night.' + str(self.state['turn']) os.rename(self.plan_path, plan_path) os.rename(self.actions_path, actions_path) glue.run('run-night', self.state_path, actions_path, plan_path) shutil.copy(self.state_path, self.state_path + '.day.' + str(self.state['turn'])) self.load_state() self.load_players() self.make_ballot() self.make_actions() self.make_plan()
def get_ballot(self, turn): raw = self.get_raw_ballot(turn) orig_players = glue.run('view-players', self.state_path + '.day.' + str(turn)) players = glue.run( 'view-players', self.state_path + '.' + self.get_post_suffix('day', turn)) candidates = {player_id for player_id, player in orig_players.items() if player['causeOfDeath'] is None} & \ {player_id for player_id, player in players.items() if player['causeOfDeath'] is None or next(iter(player['causeOfDeath'])) == 'Lynched'} return { 'votes': { self.meta['players'][player_id]['name']: self.meta['players'][raw[player_id]]['name'] if player_id in raw else None for player_id in candidates } }
def get_phase_state(self, player_id): winners = self.get_raw_winners() if winners is not None: return { 'phase': 'End', 'winners': [ self.meta['players'][player_id]['name'] for player_id in winners ], 'players': { self.meta['players'][player_id]['name']: { 'fullRole': self.get_full_role(player_id), } for player_id, player in self.players.items() }, 'log': self.get_game_log(), 'planned': self.get_game_planned(), } if self.state['phase'] == 'Night': return { 'phase': 'Night', 'end': self.meta['schedule']['phase_end'], 'deaths': self.get_current_deaths_view(), 'plan': self.get_current_plan_view(player_id), } if self.state['phase'] == 'Day': # We need to get the plan in this way such that we can see actions # on their last use that are in the plan. raw_plan = self.filter_raw_plan_view( player_id, glue.run('view-plan', self.state_path + '.day.' + str(self.state['turn']), self.plan_path)) return { 'phase': 'Day', 'end': self.meta['schedule']['phase_end'], 'ballot': self.get_current_ballot(), 'deaths': self.get_current_deaths_view(), 'messages': self.get_current_messages_view(player_id, raw_plan), 'plan': self.interpret_raw_plan_view(raw_plan) }
def vote(self, source, target): if self.state['phase'] != 'Day': raise ValueError('not day time') # check for twilight if time.time() > self.meta['schedule']['phase_end'] - \ self.meta['schedule']['twilight_duration']: raise ValueError('in twilight') return glue.run('vote', self.state_path, self.ballot_path, input={ 'source': source, 'target': target })
def __init__(self, name, motd=None, consensus='MostVotes', end_on_consensus_met=False, night_end=datetime.time(10, 0), day_end=datetime.time(12, 15), twilight_duration=datetime.timedelta(0), tz='Etc/UTC', locale=None): self.state = { 'history': [], 'turn': 1, 'phase': 'Night', 'modActionIndex': 0, 'actions': {}, 'factions': {}, 'players': {}, 'consensus': consensus, 'rng': glue.run('new-rng') } tzinfo = pytz.timezone(tz) self.meta = { 'name': name, 'schedule': { 'night_end': night_end.isoformat(), 'day_end': day_end.isoformat(), 'twilight_duration': int(twilight_duration.total_seconds()), 'phase_end': None, 'tz': tz, }, 'locale': locale, 'motd': motd, 'end_on_consensus_met': end_on_consensus_met, 'actions': {}, 'factions': {}, 'players': {}, 'secret': random.getrandbits(256).to_bytes(256 // 8, 'little') } self.datacons = _DataConstructorFactory() self.effect_trace_index = 0 self.action_group = 0
def get_game_history(self): return { turn: { phase: [{ 'command': self.meta['actions'][act['action']]['command'], 'source': self.meta['players'][act['source']]['name'], 'targets': [ self.meta['players'][target]['name'] for target in act['targets'] ], 'trace': act['trace'], } for act in acts] for phase, acts in phases.items() } for turn, phases in glue.run('view-history', self.state_path).items() }
def get_current_deaths_view(self): state_pre_path = self.state_path + '.' + self.state['phase'].lower() + \ '.' + str(self.state['turn']) return self.interpret_raw_deaths( glue.run('view-deaths', state_pre_path, self.state_path))
def get_current_raw_plan_view(self): return glue.run('view-plan', self.state_path, self.plan_path)
def get_raw_plan_view(self, turn, phase): return glue.run('view-plan', self.state_path + '.' + phase + '.' + str(turn), self.plan_path + '.' + phase + '.' + str(turn))
def make_actions(self): glue.run('view-action-groups', self.state_path, self.actions_path)
def get_raw_winners(self): return glue.run('view-winners', self.state_path)
def load_players(self): self.players = glue.run('view-players', self.state_path)