from otree.api import * c = Currency doc = """ Implementation of the Generous/Spiteful Game from the Model Thinker """ class Constants(BaseConstants): name_in_url = 'g_s_game' players_per_group = None num_rounds = 20 class Subsession(BaseSubsession): number_g = models.IntegerField(initial=0) payoff_g = models.IntegerField(initial=0) payoff_k = models.IntegerField(initial=0) class Group(BaseGroup): pass class Player(BasePlayer): choose_g = models.BooleanField(label="Choose your Action", choices=[[True, 'G'], [False, 'S'], ], widget=widgets.RadioSelectHorizontal) # Functions def set_payoffs(subsession: Subsession): players = subsession.get_players() actions = [p.choose_g for p in players] subsession.number_g = sum(actions) subsession.payoff_g = 1 + 2 * subsession.number_g subsession.payoff_k = 2 + 2 * subsession.number_g for p in players: if p.choose_g: p.payoff = subsession.payoff_g else: p.payoff = subsession.payoff_k def creating_session(subsession): if subsession.round_number == 1: for player in subsession.get_players(): participant = player.participant participant.vars['is_dropout'] = False print(participant.vars['is_dropout']) # PAGES class Instructions(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 @staticmethod def get_timeout_seconds(player): return 90 @staticmethod def vars_for_template(player: Player): session = player.session learning_rule = session.config['learning_rule'] if player.round_number > 1: previous_choice = player.in_round(player.round_number - 1).choose_g previous_payoff = player.in_round(player.round_number - 1).payoff print(previous_choice) print(previous_payoff) return dict(learning_rule=learning_rule, previous_choice=previous_choice, previous_payoff=previous_payoff,) else: return dict(learning_rule=learning_rule,) class Choice(Page): form_model = 'player' form_fields = ['choose_g'] @staticmethod def vars_for_template(player: Player): session = player.session subsession = player.subsession learning_rule = session.config['learning_rule'] if player.round_number > 1: previous_choice = player.in_round(player.round_number - 1).choose_g previous_payoff = player.in_round(player.round_number - 1).payoff previous_payoff_g = subsession.in_round(player.round_number - 1).payoff_g previous_payoff_k = subsession.in_round(player.round_number - 1).payoff_k print(previous_choice) print(previous_payoff) return dict(learning_rule=learning_rule, previous_choice=previous_choice, previous_payoff=previous_payoff, previous_payoff_g=previous_payoff_g, previous_payoff_k=previous_payoff_k) else: return dict(learning_rule=learning_rule,) @staticmethod def get_timeout_seconds(player): participant = player.participant if participant.vars['is_dropout']: return 7 # instant timeout, 1 second else: return 30 @staticmethod def before_next_page(player, timeout_happened): subsession = player.subsession session = player.session participant = player.participant if timeout_happened: participant.vars['is_dropout'] = True if player.round_number == 1: player.choose_g = True elif subsession.in_round(player.round_number - 1).number_g >= session.num_participants / 2: player.choose_g = True else: player.choose_g = False class ResultsWaitPage(WaitPage): wait_for_all_groups = True after_all_players_arrive = set_payoffs class Results(Page): @staticmethod def is_displayed(player: Player): return player.round_number == Constants.num_rounds @staticmethod def get_timeout_seconds(player): return 60 @staticmethod def vars_for_template(player: Player): session = player.session learning_rule = session.config['learning_rule'] return dict(learning_rule=learning_rule) page_sequence = [Instructions, Choice, ResultsWaitPage, Results]