from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, # Currency as c, currency_range Currency as c, ) import random doc = """ This is an iterated Prisoner's Dilemma where players play against a computer player that executes a particular strategy. """ class Constants(BaseConstants): name_in_url = 'prisoner' players_per_group = 3 # players_per_group = 1 num_rounds = 3*3 rounds_per_session = 3 instructions_template = 'prisoner/instructions.html' history_template = 'prisoner/history.html' # payoff if 1 player defects and the other cooperates""", betray_payoff = c(300) betrayed_payoff = c(0) # payoff if both players cooperate or both defect both_cooperate_payoff = c(200) both_defect_payoff = c(100) decision_letter = { 'Cooperate': 'C', 'Defect': 'D' } decision_name = { 'C': 'Cooperate', 'D': 'Defect' } bot_strategies = ['tit-for-tat', 'true-random', 'grim-trigger'] class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): decision = models.StringField( choices=['Cooperate', 'Defect'], doc="""This player's decision""", widget=widgets.RadioSelect ) bot_decision = models.StringField() bot_payoff = models.CurrencyField() bot_strategy = models.StringField() name = models.StringField( label='What is your fictitious name?' ) age = models.IntegerField( label='What is your age?', ) gender = models.StringField( choices=['Male', 'Female', 'Other'], label='What is your gender?', widget=widgets.RadioSelect) guess_strategy = models.StringField( label='What strategy do you think the bot used? Please name or describe the strategy in the box below:', widget=widgets.Textarea, ) comments = models.StringField( label='Please note down any other comments you may have in the box below:', widget=widgets.Textarea, blank=True ) def bot_player(self): # set current session number session_number = ((self.round_number - 1) // Constants.rounds_per_session) + 1 # set current round number in current session round_in_session = self.round_number - ((session_number-1) * Constants.rounds_per_session) # bot always cooperates in first round of each session if self.round_number == 1: self.bot_decision = 'Cooperate' self.participant.vars['all_bot_decisions'] = [Constants.decision_letter[self.bot_decision]] # set bot strategy in first round self.bot_strategy = Constants.bot_strategies[self.id_in_group-1] # bot decisions in subsequent rounds depends on bot strategy & player's prev choices else: prev_player = self.in_round(self.round_number-1) self.bot_strategy = prev_player.bot_strategy if self.bot_strategy == 'tit-for-tat': self.bot_decision = prev_player.decision if self.bot_strategy == 'true-random': self.bot_decision = random.choice(['Cooperate', 'Defect']) if self.bot_strategy == 'grim-trigger': if prev_player.decision == 'Defect': self.bot_decision = 'Defect' elif prev_player.bot_decision == 'Defect': self.bot_decision = 'Defect' else: self.bot_decision = 'Cooperate' self.participant.vars['all_bot_decisions'].append(Constants.decision_letter[self.bot_decision]) return self.bot_decision # main method def set_payoff(self): payoff_matrix = { 'Cooperate': { 'Cooperate': Constants.both_cooperate_payoff, 'Defect': Constants.betrayed_payoff }, 'Defect': { 'Cooperate': Constants.betray_payoff, 'Defect': Constants.both_defect_payoff } } bot_decision = self.bot_player() self.payoff = payoff_matrix[self.decision][bot_decision] self.bot_payoff = payoff_matrix[bot_decision][self.decision] if self.round_number == 1: self.participant.vars['all_my_decisions'] = [Constants.decision_letter[self.decision]] self.participant.vars['all_my_payoffs'] = [self.payoff] self.participant.vars['all_bot_payoffs'] = [self.bot_payoff] else: self.participant.vars['all_my_decisions'].append(Constants.decision_letter[self.decision]) self.participant.vars['all_my_payoffs'].append(self.payoff) self.participant.vars['all_bot_payoffs'].append(self.bot_payoff)