from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range, ) import random author = 'Chanjoo Lee' doc = """ Repeated cheap talk """ class Constants(BaseConstants): name_in_url = 'repeated_CT' players_per_group = None num_rounds = 2 Roles=['S','R','R_vs_bot'] incentive = 15000 num_prac_rounds = 1 class Subsession(BaseSubsession): expertise=models.FloatField(initial=0.9) robotR=models.IntegerField(initial=0) gamemode=models.IntegerField(initial=0) local_seed=models.IntegerField(initial=-1) local_seed2 = models.IntegerField(initial=-1) num_S=models.IntegerField(initial=1) def creating_session(self): self.expertise=self.session.config['expertise'] self.robotR=self.session.config['robotR'] self.gamemode=self.session.config['gamemode'] self.num_S=self.session.config['num_S'] players=self.get_players() self.local_seed = random.randint(0, 999) self.local_seed2 = random.randint(0, 999) if self.robotR == 0: local_random = random.Random(99) local_random.shuffle(players) to_shuffle = players[self.num_S:] random.Random(self.local_seed + self.round_number).shuffle(to_shuffle) players = players[ :self.num_S] + to_shuffle # The first num_S player are not shuffled for index in range(0, len(players)): if index < self.num_S: # for the first num_R_vs_bot players, they are assigned R against robot S players[index].roles = Constants.Roles[0] players[index].pseudo_group = index + 1 local_random = random.Random(self.local_seed + players[index].pseudo_group) draw = local_random.random() if draw <= 2 / 3: players[index].type = 0 # Blue else: players[index].type = 1 # Red local_random2 = random.Random(self.local_seed + players[index].pseudo_group+1) draw2 = local_random2.random() if draw2 <= self.expertise: players[index].shell = players[index].type else: players[index].shell = 1-players[index].type if self.gamemode == 2: local_random3 = random.Random(self.local_seed2 + players[index].pseudo_group) draw3 = local_random3.random() if draw3 <= 2 / 3: players[index].type2 = 0 # Blue else: players[index].type2 = 1 # Red local_random4 = random.Random(self.local_seed2 + players[index].pseudo_group + 1) draw4 = local_random4.random() if draw4 <= self.expertise: players[index].shell2 = players[index].type2 else: players[index].shell2 = 1 - players[index].type2 elif self.num_S <= index < 2 * self.num_S: # R players[index].roles = Constants.Roles[1] players[index].pseudo_group = index - self.num_S + 1 players[index].type = players[index - self.num_S].type players[index].shell = players[index - self.num_S].shell if self.gamemode == 2: players[index].type2 = players[index - self.num_S].type2 players[index].shell2 = players[index - self.num_S].shell2 else: # R with robot S players[index].roles = Constants.Roles[2] players[index].pseudo_group = index - self.num_S + 1 local_random = random.Random(self.local_seed + players[index].pseudo_group) draw = local_random.random() if draw <= 2 / 3: players[index].type = 0 # Blue else: players[index].type = 1 # Red local_random2 = random.Random(self.local_seed + players[index].pseudo_group + 1) draw2 = local_random2.random() if draw2 <= self.expertise: players[index].shell = players[index].type else: players[index].shell = 1 - players[index].type if self.gamemode == 2: local_random3 = random.Random(self.local_seed2 + players[index].pseudo_group) draw3 = local_random3.random() if draw3 <= 2 / 3: players[index].type2 = 0 # Blue else: players[index].type2 = 1 # Red local_random4 = random.Random(self.local_seed2 + players[index].pseudo_group + 1) draw4 = local_random4.random() if draw4 <= self.expertise: players[index].shell2 = players[index].type2 else: players[index].shell2 = 1 - players[index].type2 else: self.num_S=self.session.num_participants for index in range(0, len(players)): players[index].roles = Constants.Roles[0] local_random = random.Random(self.local_seed + index) draw = local_random.random() if draw <= 2 / 3: players[index].type = 0 # Blue else: players[index].type = 1 # Red local_random2 = random.Random(self.local_seed + index + 1) draw2 = local_random2.random() if draw2 <= self.expertise: players[index].shell = players[index].type else: players[index].shell = 1 - players[index].type if self.gamemode == 2: local_random3 = random.Random(self.local_seed2 + index) draw3 = local_random3.random() if draw3 <= 2 / 3: players[index].type2 = 0 # Blue else: players[index].type2 = 1 # Red local_random4 = random.Random(self.local_seed2 + index) draw4 = local_random4.random() if draw4 <= self.expertise: players[index].shell2 = players[index].type2 else: players[index].shell2 = 1 - players[index].type2 class Group(BaseGroup): pass class Player(BasePlayer): roles = models.StringField() type = models.IntegerField(initial=-1, min=0, max=1) shell=models.IntegerField(initial=-1,min=0,max=1) type2 = models.IntegerField(initial=-1, min=0, max=1) shell2 = models.IntegerField(initial=-1, min=0, max=1) recom_0=models.FloatField() recom_1=models.FloatField() recom2_0=models.FloatField() recom2_1=models.FloatField() message_sent = models.IntegerField(initial=-1) message_sent2 = models.IntegerField(initial=-1) conjecture = models.IntegerField(initial=-1, min=0, max=1) conjecture2 = models.IntegerField(initial=-1, min=0, max=1) R_sbelief = models.FloatField() R_tbelief = models.FloatField() S_tbelief = models.FloatField() message_received = models.IntegerField(initial=-1, min=0, max=1) message_received2 = models.CurrencyField(initial=-1, min=0, max=1) pseudo_group = models.IntegerField() payoff1 = models.CurrencyField() roundpay = models.CurrencyField() exer_0 = models.FloatField() exer_1 = models.FloatField() finalDeg0 = models.FloatField() finalDeg1 = models.FloatField() Rpayoff = models.IntegerField(initial=-1, min=0, max=Constants.incentive) Rpayoff1 = models.IntegerField(initial=-1, min=0, max=Constants.incentive) check_slider_one = models.IntegerField() check_slider_two = models.IntegerField() def live_instruct(self, data): if data['read'] == 1: if self.read == -1: self.read = 1 return {self.id_in_group: {'read': self.read}} read = models.IntegerField(initial=-1) q1a = models.IntegerField(choices=[[1, "True"], [2, "False"]], widget=widgets.RadioSelectHorizontal, label="A. My role will be randomly assigned in each round. So, I may be able to play the role of Sender as well.") q1b = models.IntegerField(choices=[[1, "True"], [2, "False"]], widget=widgets.RadioSelectHorizontal, label="B. I will be randomly paired with H-Sender in each round.") q1c = models.IntegerField(choices=[[1, "True"], [2, "False"]], widget=widgets.RadioSelectHorizontal, label="C. I will be randomly paired with H-Sender with 50% chance and C-Sender with 50% chance.") q2a = models.IntegerField(choices=[[1, "True"], [2, "False"]], widget=widgets.RadioSelectHorizontal, label="A. My role will be randomly assigned in each round. So, I may be able to play the role of Receiver as well.") q2b = models.IntegerField(choices=[[1, 'True'], [2, 'False']], widget=widgets.RadioSelectHorizontal, label="B. I will be randomly paired with Receiver in each round.") q2c = models.IntegerField(choices=[[1, 'True'], [2, 'False']], widget=widgets.RadioSelectHorizontal, label="C. The receiver I am paired with knows that I am the H-Sender.") q3 = models.IntegerField(choices=[[1, 'True'], [2, 'False']], widget=widgets.RadioSelectHorizontal, label="Each round consists of two stages. In both stages, I will be paired with the same sender.") q4 = models.IntegerField(choices=[[1, 'True'], [2, 'False']], widget=widgets.RadioSelectHorizontal, label="At the beginning of each round, one ball will be randomly chosen from the urn for each pair. The same ball will determine the earnings of players in both stages.") q5 = models.IntegerField(choices=[[1, 'True'], [2, 'False']], widget=widgets.RadioSelectHorizontal, label="A urn has 30 balls. Each ball consists of inner core and outer shell. The colors of the inner core and the outer shell are the same in 90% of the balls in the urn.") q6 = models.IntegerField(choices=[[1, 'True'], [2, 'False']], widget=widgets.RadioSelectHorizontal, label="If I am assigned to be Receiver, then I am going to receive 15000원 when my action matches with the color of the shell of the chosen ball.") q7 = models.IntegerField(choices=[[1, 'True'], [2, 'False']], widget=widgets.RadioSelectHorizontal, label="If I am assigned to be H-Sender, then I am going to receive 15000원 when the action taken by Receiver in my pair matches with the color of the core of the chosen ball.") q8 = models.IntegerField(choices=[[1, 'True'], [2, 'False']], widget=widgets.RadioSelectHorizontal, label="My final earning will be calculated based on one randomly chosen round. The earlier official rounds are more likely to be chosen than the later official rounds.") def set_error_message(self, value): if self.subsession.gamemode == 2: correct_answers = {"q1a": 2, "q1b": 2, "q1c": 1, "q2a": 2, "q2b": 1, "q2c": 2, "q3": 1, "q4": 2, "q5": 1, "q6": 2, "q7": 2, "q8": 2 } else: correct_answers = {"q1a": 2, "q1b": 2, "q1c": 1, "q2a": 2, "q2b": 1, "q2c": 2, "q5": 1, "q6": 2, "q7": 2, "q8": 2 } list_answers = list(value.items())[0:] list_correct_answers = list(correct_answers.items()) if list_answers != list_correct_answers: Text = 'Some of your answers are incorrect. It indicates that your understanding may not be fully accurate. ' \ 'Please try it again. You can always go back to the experimental instructions if you find anything unclear.' return Text