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 PROPOSER_ROLE = 'Proposer' RESPONDER_ROLE = 'Responder' 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): pass #@staticmethod #def creating_session(player): #if player.round_number > 1: #for group in player.get_groups(): #players = group.get_players() #players.reverse() #group.set_players(players) @staticmethod def creating_session(subsession: Subsession): session = subsession.session import random if subsession.round_number == 2 or subsession.round_number == 4: matrix = subsession.get_group_matrix() for row in matrix: row.reverse() subsession.set_group_matrix(matrix) if subsession.round_number ==1 or subsession.round_number ==3: subsession.group_like_round(1) # PAGES 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 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." @staticmethod def is_displayed(player): return not player.group.accepted class Offer(Page): form_model = 'group' form_fields = ['offer'] @staticmethod def is_displayed(player): return player.role == C.PROPOSER_ROLE 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.role == C.RESPONDER_ROLE 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' @staticmethod def is_displayed(player): return player.group.accepted def set_payoffs(group: Group): subsession = group.subsession session = group.session if group.round_number == 1: previous_round_accepted = False else: previous_round_accepted = group.in_round(group.round_number - 1).accepted proposer = group.get_player_by_role(C.PROPOSER_ROLE) responder = group.get_player_by_role(C.RESPONDER_ROLE) for player in group.get_players(): if player.group.accepted and not previous_round_accepted: if player.role == C.PROPOSER_ROLE: player.payoff = group.current_pie - group.offer if player.role == C.RESPONDER_ROLE: 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, Introduction, BeforeStarting, Offer, WaitOffer, Response, WaitResponse, OfferRejected, PayoffCheckpoint, Results2]