from otree.api import * doc = """ Public goods with punishment, roughly based on Fehr & Gaechter 2000. """ class Constants(BaseConstants): name_in_url = 'no_pun_public_goods' players_per_group = 4 num_rounds = 3 endowment = cu(20) multiplier = 2 # max_punishment = 10 # punishment_schedule = { # 0: 0, # 1: 1, # 2: 2, # 3: 4, # 4: 6, # 5: 9, # 6: 12, # 7: 16, # 8: 20, # 9: 25, # 10: 30, # } class Subsession(BaseSubsession): pass class Group(BaseGroup): total_contribution = models.CurrencyField() individual_share = models.CurrencyField() # def make_punishment_field(id_in_group): # return models.IntegerField( # min=0, max=Constants.max_punishment, label="Punishment to player {}".format(id_in_group) # ) class Player(BasePlayer): contribution = models.CurrencyField( min=0, max=Constants.endowment, label="How much will you contribute?" ) # punish_p1 = make_punishment_field(1) # punish_p2 = make_punishment_field(2) # punish_p3 = make_punishment_field(3) # punish_p4 = make_punishment_field(4) # self_cost_of_punishment = models.CurrencyField() # punishment_received = models.CurrencyField() # def get_self_field(player: Player): # return 'punish_p{}'.format(player.id_in_group) # def punishment_fields(player: Player): # fields = ['punish_p1', 'punish_p2', 'punish_p3', 'punish_p4'] # # can't punish yourself # fields.remove(get_self_field(player)) # return fields def set_payoffs(group: Group): players = group.get_players() contributions = [p.contribution for p in players] group.total_contribution = sum(contributions) group.individual_share = ( group.total_contribution * Constants.multiplier / Constants.players_per_group ) for p in players: # self_field = get_self_field(p) p.payoff = ( Constants.endowment - p.contribution + group.individual_share ) # PAGES class Introduction(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 class Contribute(Page): form_model = 'player' form_fields = ['contribution'] class WaitPage1(WaitPage): # pass after_all_players_arrive = set_payoffs # class Punish(Page): # form_model = 'player' # get_form_fields = punishment_fields # @staticmethod # def vars_for_template(player: Player): # return dict( # other_players=player.get_others_in_group(), # schedule=Constants.punishment_schedule.items(), # ) # class WaitPage2(WaitPage): # after_all_players_arrive = set_payoffs class Results(Page): pass # page_sequence = [ # Contribute, # WaitPage1, # Punish, # WaitPage2, # Results, # ] page_sequence = [ Introduction, Contribute, WaitPage1, Results, ]