from typing import List from otree.api import * doc = """ This is a one-shot "Prisoner's Dilemma". Two players are asked separately whether they want to cooperate or defect. Their choices directly determine the payoffs. """ class Constants(BaseConstants): name_in_url = 'pd' players_per_group = 2 num_rounds = 3 instructions_template = 'prisoner/instructions.html' payoff_table = [ [[[cu(200), cu(200)], [cu(100), cu(300)]], [[cu(300), cu(100)], [cu(400), cu(400)]]], [[[cu(200), cu(200)], [cu(500), cu(100)]], [[cu(100), cu(500)], [cu(400), cu(400)]]], [[[cu(300), cu(200)], [cu(000), cu(100)]], [[cu(100), cu(000)], [cu(200), cu(300)]]], # TODO: check ] class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): decision = models.StringField( choices=[['Left', 'Left'], ['Right', 'Right']], doc="""This player's decision""", widget=widgets.RadioSelect, ) # FUNCTIONS def creating_session(subsession: Subsession): subsession.group_randomly() def set_payoffs(group: Group): for p in group.get_players(): set_payoff(p) def other_player(player: Player): return player.get_others_in_group()[0] def set_payoff(player: Player): payoff_matrix = Constants.payoff_table[player.round_number-1] p1_choose_right = player.group.get_player_by_id(1).decision == 'Right' p2_choose_right = player.group.get_player_by_id(2).decision == 'Right' player.payoff = payoff_matrix[p1_choose_right][p2_choose_right][player.id_in_group-1] def get_payoff_dict(player: Player) -> str: payoff = Constants.payoff_table[player.round_number - 1] return dict( same_choice_same_payoff = (payoff[0][0][0] == payoff[0][0][1]), ll0 = payoff[0][0][0], ll1 = payoff[0][0][1], lr0 = payoff[0][1][0], lr1 = payoff[0][1][1], rl0 = payoff[1][0][0], rl1 = payoff[1][0][1], rr0 = payoff[1][1][0], rr1 = payoff[1][1][1], ) # PAGES class Introduction(Page): timeout_seconds = 180 @staticmethod def vars_for_template(player: Player): return get_payoff_dict(player) class Decision(Page): timeout_seconds = 90 form_model = 'player' form_fields = ['decision'] @staticmethod def vars_for_template(player: Player): return get_payoff_dict(player) class ResultsWaitPage(WaitPage): after_all_players_arrive = set_payoffs class NextGameWaitPage(WaitPage): wait_for_all_groups = True body_text = 'Please wait for all participants to finish before moving to the next round.' class Results(Page): timeout_seconds = 30 @staticmethod def vars_for_template(player: Player): me = player opponent = other_player(me) return dict( my_decision=me.decision, opponent_decision=opponent.decision, same_choice=me.decision == opponent.decision, ) page_sequence = [Introduction, Decision, ResultsWaitPage, Results, NextGameWaitPage]