from otree.api import * import random doc = """ This app is to be used with the Groups of 6 Participants, with a Supervisor. One worker is swapped. This is for the Majority Leader Treatment. """ class C(BaseConstants): NAME_IN_URL = 'majl_6' PLAYERS_PER_GROUP = 6 NUM_ROUNDS = 10 WORKER_1_ROLE = 'worker_1' SUPERVISOR_ROLE = 'supervisor' WORKER_2_ROLE = 'worker_2' WORKER_3_ROLE = 'worker_3' WORKER_4_ROLE = 'worker_4' WORKER_5_ROLE = 'worker_5' class Subsession(BaseSubsession): supervisor_red_message = models.LongStringField(initial=" ") supervisor_blue_message = models.LongStringField(initial=" ") supervisor_red_roll_total = models.IntegerField(initial=0) supervisor_blue_roll_total = models.IntegerField(initial=0) payoff_round = models.IntegerField(initial=0) red_group_total_claims = models.IntegerField(initial=0) blue_group_total_claims = models.IntegerField(initial=0) class Group(BaseGroup): total_claims_group = models.CurrencyField(initial=0) collective_sanction = models.BooleanField(initial=False) success_probability = models.FloatField(initial=0.00) supervisor_message = models.LongStringField(initial=" ") puzzle_payoff = models.FloatField(initial=0) time_taken_puzzle = models.IntegerField() class Player(BasePlayer): part_2_quiz_status = models.BooleanField(initial=False) part_2_first_roll_report = models.IntegerField(min=1, max=6,) part_2_second_roll_report = models.IntegerField(min=1, max=6,) part_2_third_roll_report = models.IntegerField(min=1, max=6,) payoff_for_round = models.IntegerField(initial=0) part_1_puzzle_status = models.StringField( initial='Not Completed',) part_1_puzzle_quiz_status = models.BooleanField(initial=False) time_elapsed_to_solve = models.StringField( initial='00:00', blank=True) group_color = models.StringField() sanction_on_player = models.BooleanField(initial=False) time_taken_puzzle = models.IntegerField() def assign_group(player): group_id = player.group.id_in_subsession if player.role == 'supervisor': if (group_id % 2) != 0: player.group_color = player.participant.player_group_color = "red" elif (group_id % 2) == 0: player.group_color = player.participant.player_group_color = "blue" else: player.group_color = player.participant.player_group_color = "red" elif player.role == 'worker_2': if (group_id % 2) != 0: player.group_color = player.participant.player_group_color = "blue" elif (group_id % 2) == 0: player.group_color = player.participant.player_group_color = "red" else: player.group_color = player.participant.player_group_color = "red" else: if (group_id % 2) != 0: player.group_color = player.participant.player_group_color = "red" elif (group_id % 2) == 0: player.group_color = player.participant.player_group_color = "blue" else: player.group_color = player.participant.player_group_color = "red" # PAGES class welcome(Page): @ staticmethod def is_displayed(player: Player): return player.round_number == 1 class part_1_puzzle_quiz(Page): form_model = "player" form_fields = ['part_1_puzzle_quiz_status'] @ staticmethod def is_displayed(player): return player.round_number == 1 class wait_before_puzzle(WaitPage): wait_for_all_groups = True @ staticmethod def is_displayed(player): return player.round_number == 1 class part_1_puzzle_page(Page): form_model = 'player' form_fields = ['part_1_puzzle_status', 'time_elapsed_to_solve',] timeout_seconds = 60*10 @staticmethod def vars_for_template(player: Player): group_id = player.group.id_in_subsession return { "group_id": group_id, } @ staticmethod def before_next_page(player: Player, timeout_happened): if player.part_1_puzzle_status == "Done": time_temp = player.time_elapsed_to_solve.split( ":") time_for_player = 600 - \ (int(time_temp[0])*60 + int(time_temp[1])) player.time_taken_puzzle = time_for_player elif player.part_1_puzzle_status == "Not Completed": player.time_taken_puzzle = 99999 else: player.time_taken_puzzle = 99999 @ staticmethod def is_displayed(player): return player.round_number == 1 class part_2_welcome(Page): @ staticmethod def is_displayed(player): return player.round_number == 1 class part_2_quiz_page(Page): form_model = "player" form_fields = ['part_2_quiz_status'] @ staticmethod def is_displayed(player): return player.round_number == 1 class wait_for_round(WaitPage): template_name = "majl_6/wait_for_message.html" @ staticmethod def is_displayed(player): return (player.round_number <= 10) class wait_for_message(WaitPage): template_name = "majl_6/wait_for_message.html" wait_for_all_groups = True @ staticmethod def is_displayed(player): return (player.round_number <= 10) and not (player.role == 'supervisor') class message_instructions_supervisor(Page): @ staticmethod def vars_for_template(player: Player): assign_group(player) return { 'player_group_color': player.group_color } def is_displayed(player): return player.round_number == 1 and player.role == 'supervisor' class message_instructions_worker(Page): @ staticmethod def vars_for_template(player: Player): assign_group(player) return { 'player_group_color': player.group_color } def is_displayed(player): return player.round_number == 1 and not (player.role == 'supervisor') and not (player.role == 'worker_2') class message_instructions_swapped_worker(Page): @ staticmethod def vars_for_template(player: Player): assign_group(player) return { 'player_group_color': player.group_color } def is_displayed(player): return player.round_number == 1 and player.role == 'worker_2' class message_sender_supervisor(Page): form_model = "group" form_fields = ['supervisor_message', ] @ staticmethod def vars_for_template(player: Player): assign_group(player) return { 'player_group_color': player.group_color, 'round': player.round_number, } @ staticmethod def before_next_page(player: Player, timeout_happened): if player.group_color == "blue": player.subsession.supervisor_blue_message = player.group.supervisor_message elif player.group_color == "red": player.subsession.supervisor_red_message = player.group.supervisor_message else: player.subsession.supervisor_blue_message = " " player.subsession.supervisor_red_message = " " if timeout_happened: player.group.supervisor_message = "" @ staticmethod def is_displayed(player): return (player.round_number <= 10) and player.role == 'supervisor' class message_receiver_worker(Page): def vars_for_template(player: Player): assign_group(player) if player.group_color == "red": supervisor_message = player.subsession.field_maybe_none( 'supervisor_red_message') elif player.group_color == "blue": supervisor_message = player.subsession.field_maybe_none( 'supervisor_blue_message') return { 'supervisor_message': supervisor_message, 'player_group_color': player.group_color, 'round': player.round_number, } @ staticmethod def is_displayed(player): return (player.round_number <= 10) and not (player.role == 'supervisor') and not (player.role == 'worker_2') class message_receiver_swapped_worker(Page): def vars_for_template(player: Player): assign_group(player) if player.group_color == "red": supervisor_message = player.subsession.field_maybe_none( 'supervisor_red_message') elif player.group_color == "blue": supervisor_message = player.subsession.field_maybe_none( 'supervisor_blue_message') return { 'supervisor_message': supervisor_message, 'player_group_color': player.group_color, 'round': player.round_number, } @ staticmethod def is_displayed(player): return (player.round_number <= 10) and player.role == 'worker_2' class part_2_roll_1_page(Page): form_model = "player" form_fields = ['part_2_first_roll_report', ] @ staticmethod def vars_for_template(player: Player): return { 'round': player.round_number, } @ staticmethod def is_displayed(player): return (player.round_number <= 10) class part_2_roll_2_page(Page): form_model = "player" form_fields = ['part_2_second_roll_report', ] @ staticmethod def vars_for_template(player: Player): return { 'round': player.round_number, } @ staticmethod def is_displayed(player): return (player.round_number <= 10) class part_2_roll_3_page(Page): form_model = "player" form_fields = ['part_2_third_roll_report', ] @ staticmethod def vars_for_template(player: Player): return { 'round': player.round_number, } @ staticmethod def is_displayed(player): return (player.round_number <= 10) class part_2_ResultsWaitPage(WaitPage): wait_for_all_groups = True @ staticmethod def after_all_players_arrive(subsession: Subsession): groups_list = subsession.get_groups() group_1 = groups_list[0] group_2 = groups_list[1] if group_1: players_list = group_1.get_players() player_1 = players_list[0] player_2 = players_list[1] player_3 = players_list[2] player_4 = players_list[3] player_5 = players_list[4] player_6 = players_list[5] if player_1.round_number == 1: total_time_solve_group_1 = 0 for i in range(0, len(players_list)): if players_list[i].in_round(1).part_1_puzzle_status == "Done": time_temp = players_list[i].time_elapsed_to_solve.split( ":") time_for_player = 600 - \ (int(time_temp[0])*60 + int(time_temp[1])) total_time_solve_group_1 += time_for_player elif players_list[i].in_round(1).part_1_puzzle_status == "Not Completed": players_list[i].group.puzzle_payoff = 0 total_time_solve_group_1 = 99999 break elif players_list[i].in_round(1).part_1_puzzle_status == " ": players_list[i].group.puzzle_payoff = 0 total_time_solve_group_1 = 99999 break elif players_list[i].in_round(1).part_1_puzzle_status == None: players_list[i].group.puzzle_payoff = 0 total_time_solve_group_1 = 99999 break else: players_list[i].group.puzzle_payoff = 0 total_time_solve_group_1 = 99999 break player_1.group.time_taken_puzzle = total_time_solve_group_1 player_1_total = player_1.part_2_first_roll_report + \ player_1.part_2_second_roll_report + player_1.part_2_third_roll_report player_2_total = subsession.supervisor_red_roll_total = player_2.part_2_first_roll_report + \ player_2.part_2_second_roll_report + player_2.part_2_third_roll_report player_3_total = player_3.part_2_first_roll_report + \ player_3.part_2_second_roll_report + player_3.part_2_third_roll_report player_4_total = player_4.part_2_first_roll_report + \ player_4.part_2_second_roll_report + player_4.part_2_third_roll_report player_5_total = player_5.part_2_first_roll_report + \ player_5.part_2_second_roll_report + player_5.part_2_third_roll_report player_6_total = player_6.part_2_first_roll_report + \ player_6.part_2_second_roll_report + player_6.part_2_third_roll_report if group_2: players_list = group_2.get_players() player_7 = players_list[0] player_8 = players_list[1] player_9 = players_list[2] player_10 = players_list[3] player_11 = players_list[4] player_12 = players_list[5] if player_7.round_number == 1: total_time_solve_group_2 = 0 for i in range(0, len(players_list)): if players_list[i].in_round(1).part_1_puzzle_status == "Done": time_temp = players_list[i].time_elapsed_to_solve.split( ":") time_for_player = 600 - \ (int(time_temp[0])*60 + int(time_temp[1])) total_time_solve_group_2 += time_for_player elif players_list[i].in_round(1).part_1_puzzle_status == "Not Completed": players_list[i].group.puzzle_payoff = 0 total_time_solve_group_2 = 99999 break elif players_list[i].in_round(1).part_1_puzzle_status == " ": players_list[i].group.puzzle_payoff = 0 total_time_solve_group_2 = 99999 break elif players_list[i].in_round(1).part_1_puzzle_status == None: players_list[i].group.puzzle_payoff = 0 total_time_solve_group_2 = 99999 break else: players_list[i].group.puzzle_payoff = 0 total_time_solve_group_2 = 99999 break player_7.group.time_taken_puzzle = total_time_solve_group_2 player_7_total = player_7.part_2_first_roll_report + \ player_7.part_2_second_roll_report + player_7.part_2_third_roll_report player_8_total = subsession.supervisor_blue_roll_total = player_8.part_2_first_roll_report + \ player_8.part_2_second_roll_report + player_8.part_2_third_roll_report player_9_total = player_9.part_2_first_roll_report + \ player_9.part_2_second_roll_report + player_9.part_2_third_roll_report player_10_total = player_10.part_2_first_roll_report + \ player_10.part_2_second_roll_report + player_10.part_2_third_roll_report player_11_total = player_11.part_2_first_roll_report + \ player_11.part_2_second_roll_report + player_11.part_2_third_roll_report player_12_total = player_12.part_2_first_roll_report + \ player_12.part_2_second_roll_report + player_12.part_2_third_roll_report if player_1.round_number == 1: if total_time_solve_group_1 < total_time_solve_group_2: if total_time_solve_group_1 != 99999: group_1.puzzle_payoff = (3) group_2.puzzle_payoff = (0) else: group_1.puzzle_payoff = (0) group_2.puzzle_payoff = (0) elif total_time_solve_group_1 > total_time_solve_group_2: if total_time_solve_group_2 != 99999: group_1.puzzle_payoff = (0) group_2.puzzle_payoff = (3) else: group_1.puzzle_payoff = (0) group_2.puzzle_payoff = (0) else: group_1.puzzle_payoff = (0) group_2.puzzle_payoff = (0) subsession.red_group_total_claims = player_1_total + \ player_2_total + player_9_total + \ player_4_total + player_5_total + player_6_total subsession.blue_group_total_claims = player_7_total + \ player_8_total + player_3_total + \ player_10_total + player_11_total + player_12_total if subsession.red_group_total_claims >= 72: group_1.collective_sanction = True group_1.success_probability = round(random.uniform(0, 1), 4) if group_1.success_probability > 0.25: player_1.payoff_for_round = player_1_total player_2.payoff_for_round = player_2_total player_9.payoff_for_round = player_9_total player_4.payoff_for_round = player_4_total player_5.payoff_for_round = player_5_total player_6.payoff_for_round = player_6_total player_1.sanction_on_player = True player_2.sanction_on_player = True player_9.sanction_on_player = True player_4.sanction_on_player = True player_5.sanction_on_player = True player_6.sanction_on_player = True elif group_1.success_probability <= 0.25: player_1.payoff_for_round = 0 player_1.sanction_on_player = True player_2.payoff_for_round = 0 player_2.sanction_on_player = True player_9.payoff_for_round = 0 player_9.sanction_on_player = True player_4.payoff_for_round = 0 player_4.sanction_on_player = True player_5.payoff_for_round = 0 player_5.sanction_on_player = True player_6.payoff_for_round = 0 player_6.sanction_on_player = True else: group_1.collective_sanction = False player_1.payoff_for_round = player_1_total player_2.payoff_for_round = player_2_total player_9.payoff_for_round = player_9_total player_4.payoff_for_round = player_4_total player_5.payoff_for_round = player_5_total player_6.payoff_for_round = player_6_total if subsession.blue_group_total_claims >= 72: group_2.collective_sanction = True group_2.success_probability = round(random.uniform(0, 1), 4) if group_2.success_probability > 0.25: player_7.payoff_for_round = player_7_total player_8.payoff_for_round = player_8_total player_3.payoff_for_round = player_3_total player_10.payoff_for_round = player_10_total player_11.payoff_for_round = player_11_total player_12.payoff_for_round = player_12_total player_7.sanction_on_player = True player_8.sanction_on_player = True player_3.sanction_on_player = True player_10.sanction_on_player = True player_11.sanction_on_player = True player_12.sanction_on_player = True elif group_2.success_probability <= 0.25: player_7.payoff_for_round = 0 player_7.sanction_on_player = True player_8.payoff_for_round = 0 player_8.sanction_on_player = True player_3.payoff_for_round = 0 player_3.sanction_on_player = True player_10.payoff_for_round = 0 player_10.sanction_on_player = True player_11.payoff_for_round = 0 player_11.sanction_on_player = True player_12.payoff_for_round = 0 player_12.sanction_on_player = True else: group_2.collective_sanction = False player_7.payoff_for_round = player_7_total player_8.payoff_for_round = player_8_total player_3.payoff_for_round = player_3_total player_10.payoff_for_round = player_10_total player_11.payoff_for_round = player_11_total player_12.payoff_for_round = player_12_total if player_1.round_number == 10: if subsession.payoff_round == 0: subsession.payoff_round = random.randint(1, 10) else: pass @ staticmethod def is_displayed(player): return (player.round_number <= 10) class part_2_results(Page): @ staticmethod def vars_for_template(player: Player): groups_list = player.subsession.get_groups() group_1 = groups_list[0] group_2 = groups_list[1] assign_group(player) player_payoff_round = player.payoff_for_round if player.group_color == "red": success_probability = group_1.success_probability elif player.group_color == "blue": success_probability = group_2.success_probability if (player.round_number == 10): player.participant.player_role = player.role payoff_round = player.participant.payoff_round = player.subsession.payoff_round part_1_payoff = player.in_round(1).group.puzzle_payoff player.participant.part_1_payoff = part_1_payoff if payoff_round <= 10 and payoff_round > 0: part_2_payoff = player.participant.part_2_payoff = player.in_round( payoff_round).payoff_for_round player.payoff = part_1_payoff + part_2_payoff if (not (player.participant.part_1_payoff)) or (player.participant.part_1_payoff == None): player.participant.part_1_payoff = 0 else: pass if not (player.participant.part_2_payoff) or (player.participant.part_2_payoff == None): player.participant.part_2_payoff = 0 else: pass if player.group_color == "red": group_total = player.subsession.red_group_total_claims elif player.group_color == "blue": group_total = player.subsession.blue_group_total_claims return { 'round': player.round_number, 'player_group_color': player.group_color, 'player_payoff_round': player_payoff_round, 'success_probability': success_probability, 'group_total': group_total, } @ staticmethod def is_displayed(player): return (player.round_number <= 10) page_sequence = [welcome, part_1_puzzle_quiz, wait_before_puzzle, part_1_puzzle_page, part_2_welcome, part_2_quiz_page, message_instructions_supervisor, message_instructions_worker, message_instructions_swapped_worker, message_sender_supervisor, wait_for_message, message_receiver_worker, message_receiver_swapped_worker, wait_for_round, part_2_roll_1_page, part_2_roll_2_page, part_2_roll_3_page, part_2_ResultsWaitPage, part_2_results, ]