from otree.api import * class C(BaseConstants): NAME_IN_URL = 'Grouping' PLAYERS_PER_GROUP = 5 NUM_ROUNDS = 1 PRIO_MINUTES = 1 EXCLUSION_MINUTES = 10 SECONDS_TO_PASSIVE = 30 class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): stopped = models.BooleanField(initial=False) inactive = models.BooleanField(initial=False) # ------------------------------------------------------------------------------------------- # # FUNCTIONS # # ------------------------------------------------------------------------------------------- # def waiting_time_exclusion(player): participant = player.participant import time # Takes wait_page_arrival in PARTICIPANT_FIELDS from previous field return time.time() - participant.wait_page_arrival > C.EXCLUSION_MINUTES*60 # note: this function goes at the module level, not inside the WaitPage. def group_by_arrival_time_method(subsession, waiting_players): print('in group_by_arrival_time_method') import time import random # record time of first person entering: first_time = time.time() # Prioritise players who waited long to proceed to game prio_players = [p for p in waiting_players if (time.time() - p.participant.wait_page_arrival > C.PRIO_MINUTES*60)] print(prio_players) if len(waiting_players) >= 5 and len(prio_players) > 0: number_of_prio = min(len(prio_players), 5) number_of_non_prio = 5 - number_of_prio non_prio_players = [p for p in waiting_players if p not in prio_players] selected_players = prio_players[:number_of_prio] + random.sample(non_prio_players, number_of_non_prio) return selected_players print('grouped with priority') # (what if we want minimum waiting time?) if (time.time() - first_time > 1.5*60) and len(waiting_players) >= 10: selected_players = random.sample(waiting_players, 5) return selected_players print('grouped after 1.5 minutes waiting') # When people just come in bulk if len(waiting_players) >= 15: selected_players = random.sample(waiting_players, 5) return selected_players print('grouped because there are so many') # After a certain time I don't care anymore: if (time.time() - first_time > 5*60) and len(waiting_players) >= 5 and len(prio_players) == 0: selected_players = random.sample(waiting_players, 5) return selected_players print('grouped because its late') # exclude people if they wait too long: for player in waiting_players: if waiting_time_exclusion(player): player.stopped = True return [player] # Depending on how many people are still in the queue # 1 hasn't progressed enough # 2-4 is within instructions or quiz # 5 successfully completed quiz # 6 failed quiz print('not enough players yet to create a group') # ------------------------------------------------------------------------------------------- # # Pages # # ------------------------------------------------------------------------------------------- # class MyWaitPage(WaitPage): template_name = 'grouping_waitpage/grouping_livepage.html' title_text = "Please Wait" group_by_arrival_time = True @staticmethod def vars_for_template(player): import time return dict( prioritised=time.time() - player.participant.wait_page_arrival > C.PRIO_MINUTES * 60, ) class Exclusion(Page): @staticmethod def is_displayed(player: Player): return player.stopped is True or player.inactive is True page_sequence = [ MyWaitPage, Exclusion, ]