from otree.api import * doc = """ In Cournot competition, firms simultaneously decide the units of products to manufacture. The unit selling price depends on the total units produced. In this implementation, there are 2 firms competing for 1 period. """ class C(BaseConstants): NAME_IN_URL = 'stackelberg' PLAYERS_PER_GROUP = 2 NUM_ROUNDS = 1 INSTRUCTIONS_TEMPLATE = 'cournot/instructions.html' # Total production capacity of all players TOTAL_CAPACITY = 60 MAX_UNITS_PER_PLAYER = int(TOTAL_CAPACITY / PLAYERS_PER_GROUP) class Subsession(BaseSubsession): pass class Group(BaseGroup): unit_price = models.CurrencyField() total_units = models.IntegerField(doc="""Total units produced by all players""") class Player(BasePlayer): units = models.IntegerField( min=0, max=C.MAX_UNITS_PER_PLAYER, doc="""Quantity of units to produce""", label="How many units will you produce (from 0 to 30)?", ) code1 = models.StringField(label='Please enter your ID.', min_length=3, max_length=3) code2 = models.StringField(label='Please enter your ID again.', min_length=3, max_length=3) #birth = models.CharField(label='Please insert your date of birth in DD/MM/YYYY format (to be used only as a back-up for the ID)', max_lenght=10, validators=MinLengthValidator(10)) #age = models.IntegerField(label='What is your age?', min=13, max=125) #gender = models.StringField( # choices=[['Male', 'Male'], ['Female', 'Female'],['Non-binary/Non-conforming','Non-binary/Non-conforming'],['Prefer not to respond','Prefer not to respond']], # label='What is your gender?', # widget=widgets.RadioSelect, #) # FUNCTIONS def set_payoffs(group: Group): players = group.get_players() group.total_units = sum([p.units for p in players]) group.unit_price = C.TOTAL_CAPACITY - group.total_units for p in players: p.payoff = group.unit_price * p.units def other_player(player: Player): return player.get_others_in_group()[0] # PAGES class Demographics(Page): form_model = 'player' form_fields = ['code1', 'code2'] class Introduction(Page): pass class ChoiceOne(Page): form_model = 'player' form_fields = ['units'] @staticmethod def is_displayed(player: Player): return player.id_in_group == 1 class ChoiceTwoWaitPage(WaitPage): def vars_for_template(self: Player): if self.id_in_group == 1: body_text = "Waiting for the other participant to decide." else: body_text = 'You are to decide second. Waiting for the other participant to decide first.' return {'body_text': body_text} class ChoiceTwo(Page): form_model = 'player' form_fields = ['units'] @staticmethod def is_displayed(player: Player): return player.id_in_group == 2 def vars_for_template(player: Player): return dict(other_player_units=other_player(player).units) class ResultsWaitPage(WaitPage): after_all_players_arrive = set_payoffs class Results(Page): @staticmethod def vars_for_template(player: Player): return dict(other_player_units=other_player(player).units) page_sequence = [Demographics, Introduction, ChoiceOne, ChoiceTwoWaitPage, ChoiceTwo, ResultsWaitPage, Results]