from otree.api import Currency as c, currency_range from ._builtin import Page, WaitPage from .models import Constants num2words = {1: 'One', 2: 'Two', 3: 'Three', 4: 'Four', 5: 'Five', 6: 'Six', 7: 'Seven', 8: 'Eight', 9: 'Nine', 10: 'Ten', 11: 'Eleven', 12: 'Twelve', 13: 'Thirteen', 14: 'Fourteen', 15: 'Fifteen', 16: 'Sixteen', 17: 'Seventeen', 18: 'Eighteen', 19: 'Nineteen', 20: 'Twenty', 30: 'Thirty', 40: 'Forty', 50: 'Fifty', 60: 'Sixty', 70: 'Seventy', 80: 'Eighty', 90: 'Ninety', 0: 'Zero'} def n2w(n): try: w = num2words[n].lower() return w except KeyError: try: w = num2words[n - n % 10].lower() + "-"+ num2words[n % 10].lower() return w except KeyError: return 'Number out of range' class Instruction (Page): form_model = 'player' form_fields = ['q1','q2','q3','q4a','q4b','q4c','q4d','q5a','q5b','q5c','q5d','q6a','q6b','q6c','q7','q8'] def is_displayed(self): return self.subsession.round_number == 1 def error_message(self, value): return self.player.set_error_message(value) live_method = "live_instruct" def vars_for_template(self): players = self.subsession.get_players() num_pairs = int((len(players) - self.subsession.num_FR) / 2) FR_prob = int(2*self.subsession.num_FR/(len(players) + self.subsession.num_FR)*100) TR_prob = 100 - FR_prob payoffs=dict() for action in range(0,11): payoffs[action]={'R0': 300 - 3*(0-action)**2, 'R1': 300 - 3*(10-action)**2, 'S0': 300 - (self.subsession.conflict+0-action)**2, 'S1': 300 - (self.subsession.conflict+10-action)**2} if self.subsession.num_FR>0: correct_answers = {"q1": 3, "q2": 5, "q3": 1, "q4a": 300, "q4b": 300-3*((10-4)**2), "q4c": 300-3*((10-8)**2), "q4d": 0, "q5a": 300 - (10+self.subsession.conflict)**2, "q5b": 300 - (self.subsession.conflict-3)**2, "q5c": 300 - (self.subsession.conflict-6)**2, "q5d": 300 - (self.subsession.conflict+10-10)**2 } else: if self.subsession.sender_Mistake > 0: correct_answers = {"q1": 2, "q2": 2, "q3": 1, 'q7': 1, 'q8': 1, "q4a": 300, "q4b": 300-3*((10-4)**2), "q4c": 300-3*((10-8)**2), "q4d": 0, "q5a": 300 - (10+self.subsession.conflict)**2, "q5b": 300 - (self.subsession.conflict-3)**2, "q5c": 300 - (self.subsession.conflict-6)**2, "q5d": 300 - (self.subsession.conflict+10-10)**2 } else: correct_answers = {"q1": 2, "q2": 2, "q3": 1, "q4a": 300, "q4b": 300-3*((10-4)**2), "q4c": 300-3*((10-8)**2), "q4d": 0, "q5a": 300 - (10+self.subsession.conflict)**2, "q5b": 300 - (self.subsession.conflict-3)**2, "q5c": 300 - (self.subsession.conflict-6)**2, "q5d": 300 - (self.subsession.conflict+10-10)**2 } return { 'read' : self.player.read, 'num_FR': self.subsession.num_FR, 'num_pairs': num_pairs, 'wnum_FR': n2w(self.subsession.num_FR), 'wnum_pairs': n2w(num_pairs), 'FR_prob' : FR_prob, 'TR_prob' : TR_prob, 'conflict': self.subsession.conflict, 'conflictplus10': self.subsession.conflict+10, 'payoffs' : payoffs, 'typeO_prob' : int(100 * self.subsession.typeO_prob), 'typeI_prob' : int(100 * (1 - self.subsession.typeO_prob)), 'participation_fee' : int(self.session.participation_fee), 'solutions' : correct_answers, 'sender_Mistake': self.subsession.sender_Mistake, 'SM_numerator': self.session.config['SM_numerator'], 'SM_denominator': self.session.config['SM_denominator'], 'SM_dmn': self.session.config['SM_denominator']- self.session.config['SM_numerator'], 'mistake_rate': int(round(self.subsession.sender_Mistake, 2)*100), 'one_mistake_rate': int(round(1- self.subsession.sender_Mistake, 2)*100) } class Usher(Page): def vars_for_template(self): players = self.subsession.get_players() FR_prob = int(2*self.subsession.num_FR/(len(players) + self.subsession.num_FR)*100) TR_prob = 100 - FR_prob if self.subsession.round_number<6: pract_or_off = 'this practice round' else: pract_or_off = 'the experiment' prac_off = "Practice Round" if self.subsession.round_number > 5: prac_off = "Official Round" title = "Round #" + str(self.subsession.round_number - 5) + ": " + prac_off return dict( roundnum=self.subsession.round_number - 5, role=self.player.roles, FR_prob = FR_prob, TR_prob = TR_prob, pract_or_off = pract_or_off, title_text=title ) class SenderPage(Page): form_model = 'player' form_fields = ['message_sent'] def is_displayed(self): return self.player.roles == 'S' def vars_for_template(self): prac_off = "Practice Round" if self.subsession.round_number > 5: prac_off = "Official Round" title = "Round #" + str(self.subsession.round_number - 5) + ": " + prac_off payoffs=dict() for action in range(0,11): payoffs[action]={'R0': 300 - 3*(0-action)**2, 'R1': 300 - 3*(10-action)**2, 'S0': 300 - (self.subsession.conflict+0-action)**2, 'S1': 300 - (self.subsession.conflict+10-action)**2} return dict( roundnum=self.subsession.round_number - 5, poison_type = self.player.type, typeO_prob = int(100 * self.subsession.typeO_prob), typeI_prob=int(100 * (1-self.subsession.typeO_prob)), payoffs = payoffs, title_text=title, conflict = self.subsession.conflict, sender_Mistake = self.subsession.sender_Mistake, SM_numerator = self.session.config['SM_numerator'], SM_denominator = self.session.config['SM_denominator'], SM_dmn = self.session.config['SM_denominator'] - self.session.config['SM_numerator'], mistake_rate = int(round(self.subsession.sender_Mistake, 2) * 100), one_mistake_rate = int(round(1 - self.subsession.sender_Mistake, 2) * 100) ) class WaitS(WaitPage): template_name = 'antidote/WaitS.html' def is_displayed(self): return self.player.roles=='FR' or self.player.roles=='TR' def vars_for_template(self): prac_off = "Practice Round" if self.subsession.round_number>5: prac_off = "Official Round" title = "Round #"+str(self.subsession.round_number -5)+": "+prac_off payoffs=dict() for action in range(0,11): payoffs[action]={'R0': 300 - 3*(0-action)**2, 'R1': 300 - 3*(10-action)**2, 'S0': 300 - (self.subsession.conflict+0-action)**2, 'S1': 300 - (self.subsession.conflict+10-action)**2} return dict(body_text="Please wait for the message from S.", title_text=title, roundnum = self.subsession.round_number -5, typeO_prob = int(100 * self.subsession.typeO_prob), typeI_prob = int(100 * (1 - self.subsession.typeO_prob)), payoffs=payoffs, conflict=self.subsession.conflict ) import random class ReceiverPage(Page): form_model = 'player' form_fields = ['action'] def is_displayed(self): return self.player.roles=='FR' or self.player.roles=='TR' def vars_for_template(self): players = self.subsession.get_players() if self.player.roles =='TR': for player in players: if player.id_in_group != self.player.id_in_group and player.pseudo_group == self.player.pseudo_group: if self.subsession.sender_Mistake == 0: self.player.message_received = player.message_sent self.player.message_sent = player.message_sent player.message_received = player.message_sent else: if player.message_sent == 1: local_random = random.Random(self.subsession.local_seed+self.player.id_in_group) draw = local_random.random() if draw >= self.subsession.sender_Mistake: self.player.message_received = player.message_sent self.player.message_sent = player.message_sent player.message_received = player.message_sent else: self.player.message_received = 1 - player.message_sent self.player.message_sent = player.message_sent player.message_received = 1 - player.message_sent else: self.player.message_received = player.message_sent self.player.message_sent = player.message_sent player.message_received = player.message_sent if self.player.roles =='FR': num_pairs = int((len(players) - self.subsession.num_FR) / 2) index = self.subsession.num_FR + (self.subsession.local_seed+self.player.id_in_group)%num_pairs if self.subsession.round_number <6: local_random = random.Random(self.subsession.local_seed) local_random.shuffle(players) # FR는 아무 S한테서 랜덤으로 받아와야 하니까 index에 local_seed를 사용!! index = self.subsession.num_FR + (self.subsession.local_seed + self.player.id_in_group) % (len(players)-self.subsession.num_FR) if players[index].roles == 'S': self.player.message_received = players[index].message_sent self.player.message_sent = players[index].message_sent if players[index].roles != 'S': index = self.subsession.num_FR + (self.subsession.local_seed + self.player.id_in_group +1) % (len(players)-self.subsession.num_FR) # S,TR번갈아 나온다는 거 이용해서 이렇게 해서 항상 S로부터 뽑아올수있게 함 self.player.message_received=players[index].message_sent self.player.message_sent = players[index].message_sent else: local_random = random.Random(99) local_random.shuffle(players) index = self.subsession.num_FR + (self.subsession.local_seed + self.player.id_in_group) % num_pairs self.player.message_received = players[index].message_sent self.player.message_sent = players[index].message_sent prac_off = "Practice Round" if self.subsession.round_number > 5: prac_off = "Official Round" title = "Round #" + str(self.subsession.round_number - 5) + ": " + prac_off payoffs = dict() for action in range(0, 11): payoffs[action] = {'R0': 300 - 3 * (0 - action) ** 2, 'R1': 300 - 3 * (10 - action) ** 2, 'S0': 300 - (self.subsession.conflict + 0 - action) ** 2, 'S1': 300 - (self.subsession.conflict + 10 - action) ** 2} if self.player.message_received == 0: message = "The Poison is TYPE 0." if self.player.message_received == 1: message = "The Poison is TYPE 1." return dict( message=message, body_text="Please wait for the message from S.", title_text=title, roundnum=self.subsession.round_number - 5, typeO_prob=int(100 * self.subsession.typeO_prob), typeI_prob=int(100 * (1 - self.subsession.typeO_prob)), payoffs=payoffs, conflict=self.subsession.conflict ) def before_next_page(self): self.player.payoff = 300 - 3*(10*self.player.type-self.player.action)**2 players = self.subsession.get_players() if self.player.roles =='TR': for player in players: if player.id_in_group != self.player.id_in_group and player.pseudo_group == self.player.pseudo_group: player.action = self.player.action player.payoff = 300 - (self.subsession.conflict+10*player.type-player.action)**2 return class WaitR(WaitPage): template_name = 'antidote/WaitR.html' def is_displayed(self): return self.player.roles=='S' def vars_for_template(self): prac_off = "Practice Round" if self.subsession.round_number>5: prac_off = "Official Round" title = "Round #"+str(self.subsession.round_number -5)+": "+prac_off payoffs=dict() for action in range(0,11): payoffs[action]={'R0': 300 - 3*(0-action)**2, 'R1': 300 - 3*(10-action)**2, 'S0': 300 - (self.subsession.conflict+0-action)**2, 'S1': 300 - (self.subsession.conflict+10-action)**2} if self.player.message_sent == 0: message = "The Poison is TYPE 0." if self.player.message_sent == 1: message = "The Poison is TYPE 1." return dict( message =message, body_text="Please wait for the message from S.", title_text=title, roundnum = self.subsession.round_number -5, typeO_prob = int(100 * self.subsession.typeO_prob), typeI_prob = int(100 * (1 - self.subsession.typeO_prob)), payoffs=payoffs, conflict=self.subsession.conflict ) class Quiz_again(Page): form_model = 'player' form_fields = ['q6a','q6b','q6c'] def is_displayed(self): return self.subsession.round_number == 5 def error_message(self, value): return self.player.set_error_message2(value) def vars_for_template(self): payoffs=dict() for action in range(0,11): payoffs[action]={'R0': 300 - 3*(0-action)**2, 'R1': 300 - 3*(10-action)**2, 'S0': 300 - (self.subsession.conflict+0-action)**2, 'S1': 300 - (self.subsession.conflict+10-action)**2} return dict( typeO_prob = int(100 * self.subsession.typeO_prob), typeI_prob=int(100 * (1-self.subsession.typeO_prob)), payoffs = payoffs, conflict = self.subsession.conflict, ) class Offround_start(Page): def is_displayed(self): return self.subsession.round_number == 5 def vars_for_template(self): prac_off = "Practice Round" if self.subsession.round_number > 5: prac_off = "Official Round" title = "Round #" + str(self.subsession.round_number - 5) + ": " + prac_off return dict( title_text = title, ) class ResultsWaitPage(WaitPage): pass class Results(Page): def vars_for_template(self): prac_off = "Practice Round" if self.subsession.round_number > 5: prac_off = "Official Round" title = "Round #" + str(self.subsession.round_number - 5) + ": " + prac_off if self.player.roles=='S': if self.player.type == 0: hcol = 5 else: hcol = 7 lcolor = "#ffd099" hcolor = "#ffad4d" else: lcolor = "#b7d9fa" hcolor = "#407fbf" if self.player.type == 0: hcol = 2 else: hcol = 4 if self.player.message_sent == 0: message_S = "The Poison is TYPE 0." if self.player.message_sent == 1: message_S = "The Poison is TYPE 1." if self.player.message_received == 0: message_R= "The Poison is TYPE 0." if self.player.message_received == 1: message_R = "The Poison is TYPE 1." payoffs = dict() for action in range(0, 11): payoffs[action] = {'R0': 300 - 3 * (0 - action) ** 2, 'R1': 300 - 3 * (10 - action) ** 2, 'S0': 300 - (self.subsession.conflict + 0 - action) ** 2, 'S1': 300 - (self.subsession.conflict + 10 - action) ** 2} return dict( action = self.player.action, hcol = hcol, lcolor = lcolor, hcolor = hcolor, title_text=title, roundnum=self.subsession.round_number - 5, typeO_prob=int(100 * self.subsession.typeO_prob), typeI_prob=int(100 * (1 - self.subsession.typeO_prob)), payoffs=payoffs, earning = int(self.player.payoff), message_R = message_R, message_S = message_S, sender_Mistake = self.subsession.sender_Mistake ) class Final_payment(Page): def cal_final_payoff(self,local_seed): local_random = random.Random(local_seed+self.player.id_in_group) chosen_round = local_random.randint(6, Constants.num_rounds) player = self.player.in_round(chosen_round) self.participant.payoff = player.payoff return self.participant.payoff, chosen_round def is_displayed(self): return self.subsession.round_number == Constants.num_rounds def vars_for_template(self): final_payment, chosen_round = self.cal_final_payoff(self.subsession.local_seed) Type_dict = {} Action_dict = {} Earning_dict = {} for m in range(6,Constants.num_rounds+1): player = self.player.in_round(m) Type_dict[m-5] = player.type Action_dict[m-5] = player.action Earning_dict[m-5] = int(player.payoff) payoffs=dict() for action in range(0,11): payoffs[action]={'R0': 300 - 3*(0-action)**2, 'R1': 300 - 3*(10-action)**2, 'S0': 300 - (self.subsession.conflict+0-action)**2, 'S1': 300 - (self.subsession.conflict+10-action)**2} return dict(money = final_payment, chosen_round = chosen_round - 5, total_payment = self.participant.payoff_plus_participation_fee(), tot_match_num = Constants.num_rounds-5, Type_dict = Type_dict, Action_dict = Action_dict, Earning_dict = Earning_dict, payoffs = payoffs, typeO_prob=int(100 * self.subsession.typeO_prob), typeI_prob=int(100 * (1 - self.subsession.typeO_prob)), conflict=self.subsession.conflict, num_FR = self.subsession.num_FR ) page_sequence = [Instruction,Usher,SenderPage, WaitS, ReceiverPage, WaitR, ResultsWaitPage, Results, Quiz_again, Offround_start, Final_payment]