Exemple #1
0
    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
                 })
Exemple #2
0
    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))
Exemple #3
0
 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, []))
Exemple #4
0
    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()
Exemple #5
0
    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()
Exemple #6
0
    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, []))
Exemple #7
0
    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()
Exemple #8
0
    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
            }
        }
Exemple #9
0
    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)
            }
Exemple #10
0
    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
                        })
Exemple #11
0
    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
Exemple #12
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()
     }
Exemple #13
0
 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))
Exemple #14
0
 def get_current_raw_plan_view(self):
     return glue.run('view-plan', self.state_path, self.plan_path)
Exemple #15
0
 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))
Exemple #16
0
 def make_actions(self):
     glue.run('view-action-groups', self.state_path, self.actions_path)
Exemple #17
0
 def get_raw_winners(self):
     return glue.run('view-winners', self.state_path)
Exemple #18
0
 def load_players(self):
     self.players = glue.run('view-players', self.state_path)