from otree.api import * author = 'Yuki Takahashi' doc = """ Opened on Sep 9, 2023 This is an ultimatum game where we time the moment the responder sees the proposer's offer on the screen. """ class C(BaseConstants): NAME_IN_URL = 'ultimatum_game' PLAYERS_PER_GROUP = 2 NUM_ROUNDS = 1 INSTRUCTIONS_TEMPLATE = 'UltGame/Instructions.html' ENDOWMENT = cu(100) PAYOFF_IF_REJECTED = cu(0) PROPOSER_ROLE = 'Proposer' RESPONDER_ROLE = 'Responder' class Subsession(BaseSubsession): pass class Group(BaseGroup): amount_offered = models.CurrencyField() offer_accepted = models.BooleanField( doc="""if offered amount is accepted""", widget=widgets.RadioSelectHorizontal, choices=[ [1, 'Accept'], [0, 'Reject'], ] ) class Player(BasePlayer): pass # FUNCTIONS def set_payoffs(group: Group): proposer = group.get_player_by_role(C.PROPOSER_ROLE) responder = group.get_player_by_role(C.RESPONDER_ROLE) if group.offer_accepted: proposer.payoff = C.ENDOWMENT - group.amount_offered responder.payoff = C.ENDOWMENT + group.amount_offered else: proposer.payoff = C.PAYOFF_IF_REJECTED responder.payoff = C.PAYOFF_IF_REJECTED # PAGES class Introduction(Page): pass class Offer(Page): form_model = 'group' form_fields = ['amount_offered'] @staticmethod def is_displayed(player: Player): return player.role == C.PROPOSER_ROLE class WaitForProposer(WaitPage): pass class Accept(Page): form_model = 'group' form_fields = ['offer_accepted'] @staticmethod def is_displayed(player: Player): return player.role == C.RESPONDER_ROLE class ResultsWaitPage(WaitPage): @staticmethod def after_all_players_arrive(group: Group): set_payoffs(group) class Results(Page): @staticmethod def vars_for_template(player): if player.group.offer_accepted == False: response = 'Reject' if player.group.offer_accepted == True: response = 'Accept' return dict(response=response) page_sequence = [Introduction, Offer, WaitForProposer, Accept, ResultsWaitPage, Results]