from otree.api import * import random c = Currency doc = """ Your app description """ class Constants(BaseConstants): name_in_url = 'my_matching_pennies' players_per_group = 2 num_rounds = 4 stakes = c(100) class Subsession(BaseSubsession): def before_session_starts(Subsession): if Subsession.round_number == 1: paying_round = random.randint(1, Constants.num_rounds) Subsession.session.vars['paying_round'] = paying_round if Subsession.round_number == 3: # reverse the roles for group in Subsession.get_groups(): players = group.get_players() players.reverse() group.set_players(players) if Subsession.round_number > 3: Subsession.group_like_round(3) class Group(BaseGroup): def set_payoffs(Group): matcher = Group.get_player_by_role('Matcher') mismatcher = Group.get_player_by_role('Mismatcher') if matcher.penny_side == mismatcher.penny_side: matcher.is_winner = True mismatcher.is_winner = False else: matcher.is_winner = False mismatcher.is_winner = True for player in [mismatcher, matcher]: if (Group.round_number == Group.session.vars['paying_round'] and player.is_winner): player.payoff = Constants.stakes class Player(BasePlayer): penny_side = models.CharField( choices=['Heads', 'Tails'], widget=widgets.RadioSelect() ) is_winner = models.BooleanField() def role(player): if player.id_in_group == 1: return 'Mismatcher' if player.id_in_group == 2: return 'Matcher' # PAGES class MyPage(Page): form_model = models.Player form_fields = ['penny_side'] def vars_for_template(player): return { 'player_in_previous_rounds': player.in_previous_rounds(), } class ResultsWaitPage(WaitPage): def after_all_players_arrive(Group): Group.group.set_payoffs() class Results(Page): def is_displayed(player): return player.round_number == Constants.num_rounds def vars_for_template(player): return { 'total_payoff': sum([p.payoff for p in player.in_all_rounds()]), 'paying_round': player.session.vars['paying_round'], 'player_in_all_rounds': player.in_all_rounds(), } page_sequence = [MyPage, ResultsWaitPage, Results]