from otree.api import * c = cu doc = 'This is a multi-stage game, with one player being the monopoly and the rest being the consumers. ' class C(BaseConstants): NAME_IN_URL = 'Track_and_Hide_60_0' PLAYERS_PER_GROUP = None NUM_ROUNDS = 10 TRACKING_PRECISION = 0.6 HIDING_COST = cu(0) VALUATION_SCALAR = 100 PAYOFF_GOODS = cu(0) ENDOWMENT = cu(0) class Subsession(BaseSubsession): pass def creating_sessions(subsession: Subsession): session = subsession.session subsession.group_randomly(fixed_id_in_group = True) class Group(BaseGroup): pass def value_generation(group: Group): session = group.session for p in group.get_players(): x = (p.id_in_group-1)*round(C.VALUATION_SCALAR/(session.num_participants-1),1) if x > C.VALUATION_SCALAR: p.Valuation = C.VALUATION_SCALAR else: p.Valuation = x def payoff_set(group: Group): consumers = [p for p in group.get_players() if p.id_in_group > 1] monopoly = group.get_player_by_id(1) x = 0 for p in consumers: if p.Identification: p.Contract = True p.payoff = C.ENDOWMENT+ C.PAYOFF_GOODS x += p.Valuation else: if p.Hide_choice: if monopoly.Uniform_price > p.Valuation: p.payoff = C.ENDOWMENT-C.HIDING_COST else: p.payoff = C.ENDOWMENT-C.HIDING_COST+p.Valuation-monopoly.Uniform_price+C.PAYOFF_GOODS p.Contract = True x += monopoly.Uniform_price else: if monopoly.Uniform_price > p.Valuation: p.payoff = C.ENDOWMENT else: p.payoff = C.ENDOWMENT+p.Valuation-monopoly.Uniform_price+C.PAYOFF_GOODS p.Contract = True x += monopoly.Uniform_price monopoly.payoff = x def info_for_monopoly(group: Group): consumers_id = [p for p in group.get_players() if p.Identification == True] num_id = len(consumers_id) ide_revenue = [p.Valuation for p in consumers_id] consumers_uni = [p for p in group.get_players() if p.Contract == True] num_uni = len(consumers_uni) - num_id uni_price = group.get_player_by_id(1).Uniform_price track_prob = C.TRACKING_PRECISION*100 return dict(num_of_id = num_id, id_list = ide_revenue, num_of_uni = num_uni, uniform_price = uni_price, total_con = len(consumers_uni), track_p = track_prob) class Player(BasePlayer): Hide_choice = models.BooleanField(choices=[[True, 'Hide'], [False, 'Not Hide']], initial=False, label='Once you hide, you will not be price discriminated and you will only receive the uniform price offer. Do you want to hide?', widget=widgets.RadioSelectHorizontal) Uniform_price = models.CurrencyField(label='The uniform price will be the price your consumers get when you fail to identify their valuation.(1 points = 1 euro) ', max=C.VALUATION_SCALAR, min=0) Identification = models.BooleanField(initial=False) Valuation = models.CurrencyField(initial=0) Contract = models.BooleanField(initial=False) Totall_payoff = models.CurrencyField(initial=0) def ide_generation(player: Player): import random if player.Hide_choice: player.Identification = False else: x = random.uniform(0,1) if x <= C.TRACKING_PRECISION: player.Identification = True else: player.Identification = False def custom_export(players): yield ['participant_code', 'id_in_group'] for p in players: pp = p.participant yield [pp.code, p.id_in_group] class Please_wait_for_all_participants(WaitPage): title_text = 'Please wait for all participants' class Introduction(Page): form_model = 'player' @staticmethod def before_next_page(player: Player, timeout_happened): group = player.group value_generation(group) class Price_setting(Page): form_model = 'player' form_fields = ['Uniform_price'] @staticmethod def is_displayed(player: Player): group = player.group return player.id_in_group == 1 @staticmethod def vars_for_template(player: Player): return dict(pob = C.TRACKING_PRECISION*100) class Hide_Chosing(Page): form_model = 'player' form_fields = ['Hide_choice'] @staticmethod def is_displayed(player: Player): group = player.group return not player.id_in_group == 1 @staticmethod def vars_for_template(player: Player): session = player.session subsession = player.subsession group = player.group if subsession.round_number>1: Monopoly = group.get_player_by_id(1) x = Monopoly.in_previous_rounds()[-1] uni_in_previoius = x.Uniform_price y = player.in_previous_rounds()[-1] if y.Hide_choice: hide = "Hide" else: hide = "Not Hide" return dict(hide_choice = hide, uni_price_pre = uni_in_previoius ) else: return dict() @staticmethod def before_next_page(player: Player, timeout_happened): ide_generation(player) class MyWaitPage(WaitPage): after_all_players_arrive = payoff_set class Result(Page): form_model = 'player' @staticmethod def vars_for_template(player: Player): group = player.group return info_for_monopoly(group) class Final_page(Page): form_model = 'player' @staticmethod def is_displayed(player: Player): group = player.group return group.round_number == C.NUM_ROUNDS page_sequence = [Please_wait_for_all_participants, Introduction, Price_setting, Hide_Chosing, MyWaitPage, Result, Final_page]