from otree.api import * doc = """ Bargaining Game with a Shrinking Pie """ class C(BaseConstants): NAME_IN_URL = 'rubinstein' PLAYERS_PER_GROUP = 2 NUM_ROUNDS = 4 initial_pie = cu(100) dimnishing = cu(25) class Subsession(BaseSubsession): pass class Group(BaseGroup): offer = models.CurrencyField(min=0, max=100, label='How much do you want to offer?') response = models.StringField(choices=['Accept', 'Reject'], label='Do you accept the offer?') accepted = models.BooleanField(initial=False) current_pie = models.CurrencyField(initial=C.initial_pie) def offer_error_message(group, value): print('value is', value) if group.round_number==2 and value>75: return 'You cannot make an offer more than the total remaining pie size!' if group.round_number==3 and value>50: return 'You cannot make an offer more than the total remaining pie size!' if group.round_number==4 and value>25: return 'You cannot make an offer more than the total remaining pie size!' # def offer_max(grou): class Player(BasePlayer): myrole = models.StringField() offer = models.CurrencyField() class MyWaitPage(WaitPage): group_by_arrival_time = True title_text = "Please Wait!" body_text = "This might take a few minutes. The next part of the study will begin when you pair with another person randomly." @staticmethod def is_displayed(player): return player.round_number == 1 class My(WaitPage): @staticmethod def is_displayed(player): if player.round_number == 1: if player.id_in_group==1: player.myrole = 'proposer' else: player.myrole = 'responder' if player.round_number == 2: if player.id_in_group==1: player.myrole = 'responder' else: player.myrole = 'proposer' if player.round_number == 3: if player.id_in_group==1: player.myrole = 'proposer' else: player.myrole = 'responder' if player.round_number == 4: if player.id_in_group==1: player.myrole = 'responder' else: player.myrole = 'proposer' class Introduction(Page): @staticmethod def is_displayed(player): return player.round_number == 1 timeout_seconds = 120 class BeforeStarting(WaitPage): after_all_players_arrive = 'update_pie' title_text = "Please Wait!" body_text = "This might take a few minutes." #return group.id class Offer(Page): form_model = 'group' form_fields = ['offer'] @staticmethod def is_displayed(player): return player.myrole == 'proposer' and not player.group.accepted def update_pie(group: Group): print('update_pie...') if group.round_number == 1: group.current_pie = C.initial_pie else: group.current_pie = group.in_round(group.round_number - 1).current_pie - C.dimnishing group.accepted = group.in_round(group.round_number - 1).accepted class WaitOffer(WaitPage): pass class Response(Page): form_model = 'group' form_fields = ['response'] @staticmethod def is_displayed(player): return player.myrole == 'responder' and not player.group.accepted @staticmethod def before_next_page(player, timeout_happened): if player.group.response == 'Accept': player.group.accepted = True else: player.group.accepted = False class PayoffCheckpoint(WaitPage): after_all_players_arrive = 'set_payoffs' def set_payoffs(group): if group.round_number == 1: previous_round_accepted = False else: previous_round_accepted = group.in_round(group.round_number - 1).accepted for player in group.get_players(): if player.group.accepted and not previous_round_accepted: if player.myrole == 'proposer': player.payoff = group.current_pie - group.offer if player.myrole == 'responder': player.payoff = group.offer if player.group.accepted and previous_round_accepted: player.payoff = player.in_round(player.round_number - 1).payoff class OfferRejected(Page): @staticmethod def is_displayed(player): return not player.group.accepted class WaitResponse(WaitPage): pass class Results(Page): timeout_seconds = 0.5 @staticmethod def is_displayed(player): return player.group.accepted or player.round_number == C.NUM_ROUNDS class Results2(Page): @staticmethod def is_displayed(player: Player): return player.round_number == C.NUM_ROUNDS page_sequence = [MyWaitPage, My, Introduction, BeforeStarting, Offer, WaitOffer, Response, WaitResponse, OfferRejected, PayoffCheckpoint, Results2]