from otree.api import * import random doc = """ Your app description """ class C(BaseConstants): NAME_IN_URL = 'monty_hall' PLAYERS_PER_GROUP = None NUM_ROUNDS = 5 CHOICES = [1,2,3] class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): ## can write it like first_chosen_door & revealed door ## prefix should be the same if its for the same idea ## so start with door and extent with what its for door_first_chosen = models.IntegerField(choices=C.CHOICES) door_revealed = models.IntegerField() door_not_revealed = models.IntegerField() door_finally_chosen = models.IntegerField() door_with_prize = models.IntegerField() is_winner = models.BooleanField() def final_choices(player: Player): ## return only players chosen & not revealed return [player.door_first_chosen, player.door_not_revealed] # PAGES class Decision1(Page): form_model = 'player' form_fields = ['door_first_chosen'] @staticmethod def before_next_page(player, timeout_happened): ## logic to randomly show a door other_doors = C.CHOICES.copy() other_doors.remove(player.door_first_chosen) ## cant open this door random.shuffle(other_doors) player.door_with_prize = random.choice(C.CHOICES) ## sort them by prize door, only necessary if the prize door isnt chosen already other_doors.sort(key=lambda door:door==player.door_with_prize) [player.door_revealed, player.door_not_revealed] = other_doors class Decision2(Page): form_model = 'player' form_fields = ['door_finally_chosen'] @staticmethod def before_next_page(player, timeout_happened): player.is_winner = player.door_finally_chosen == player.door_with_prize ## no waitpage as its a one player game class Results(Page): pass page_sequence = [Decision1, Decision2, Results]