import random from otree.api import * doc = """ Your app description """ class C(BaseConstants): NAME_IN_URL = 'wfg_v2' # need to change number of players in settings.py PLAYERS_PER_GROUP = None NUM_ROUNDS = 3 Prescribed_Burn_Cost = -400 Defensive_Space_Cost = -300 # will need nine roles is total Forest_1_Owner_ROLE = "subject_1" Forest_2_Owner_ROLE = "subject_2" Forest_3_Owner_ROLE = "subject_3" Forest_4_Owner_ROLE = "subject_4" Forest_5_Owner_ROLE = "subject_5" Forest_6_Owner_ROLE = "subject_6" Forest_7_Owner_ROLE = "subject_7" Forest_8_Owner_ROLE = "subject_8" Forest_9_Owner_ROLE = "subject_9" class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): # in game choice management_choice = models.IntegerField( choices=[ [1, 'Prescribed Burn, Cost: $400'], [2, 'Defensible Space, Cost $300'], [3, 'No Action, Cost $0'], ], widget=widgets.RadioSelect ) # game mechanics for fire fire = models.BooleanField() fire_started = models.BooleanField() fire_chance = models.FloatField() # game mechnics for fire spreading UNTESTED !!!! # need to expand to 9 players !!!! # differnetiating between subject choices choice_subject_1 = models.IntegerField() choice_subject_2 = models.IntegerField() # tells where fire started fire_start_subject_1 = models.BooleanField() fire_start_subject_2 = models.BooleanField() # after game questions fire_on_actual_property = models.IntegerField( choices=[ [1, "Yes"], [2, 'No'], ], widget=widgets.RadioSelect ) damage_to_actual_home = models.BooleanField( blank=True, widgets=widgets.CheckboxInput ) damage_to_other_physical_structure = models.BooleanField( widgets=widgets.CheckboxInput, blank=True ) damage_to_actual_forest = models.BooleanField( blank=True, widgets=widgets.CheckboxInput ) damage_to_other = models.BooleanField( blank=True, widgets=widgets.CheckboxInput ) other_damage = models.StringField() first_name = models.StringField() last_name = models.StringField() email = models.StringField() # PAGES # Intro is good class IntroductionPage(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 class IntroWaitPage(WaitPage): pass class ChoicePage(Page): # player choice is good form_model = "player" form_fields = ["management_choice"] @staticmethod def vars_for_template(player: Player): # gives random number between 0 and 1 to determine fire start player.fire_chance = random.random() # reports which forest each player is managing if player.role == C.Forest_1_Owner_ROLE: forest_owned_report = 'You are managing Forest 1' if player.role == C.Forest_2_Owner_ROLE: forest_owned_report = 'You are managing Forest 2' if player.role == C.Forest_3_Owner_ROLE: forest_owned_report = 'You are managing Forest 3' if player.role == C.Forest_4_Owner_ROLE: forest_owned_report = 'You are managing Forest 4' if player.role == C.Forest_5_Owner_ROLE: forest_owned_report = 'You are managing Forest 5' if player.role == C.Forest_6_Owner_ROLE: forest_owned_report = 'You are managing Forest 6' if player.role == C.Forest_7_Owner_ROLE: forest_owned_report = 'You are managing Forest 7' if player.role == C.Forest_8_Owner_ROLE: forest_owned_report = 'You are managing Forest 8' if player.role == C.Forest_9_Owner_ROLE: forest_owned_report = 'You are managing Forest 9' return { 'player.fire_chance': player.fire_chance, 'forest_owned_report': forest_owned_report } class ResultsWaitPage(WaitPage): pass class Results(Page): @staticmethod def vars_for_template(player: Player): # reports player's own choice if player.management_choice == 1: management_choice_report = 'You chose to perform a prescribed burn. The cost was $400.' elif player.management_choice == 2: management_choice_report = 'You chose to maintain a defensive space. The cost was $300.' elif player.management_choice == 3: management_choice_report = 'You chose to do nothing.' # reports if fire stated on player's own property # if change fraction: 1/9 here also need to change it at if statement below if player.fire_chance <= 1 / 9: player.fire_started = True fire_started_report = "The fire started on your property." else: player.fire_started = False fire_started_report = "A fire did not start on your property." # game mechnics for fire spreading UNTESTED !!!! # need to expand to 9 players only at 2 !!!! # differnetiating between subject choices subject_1 = player.group.get_player_by_role(C.Forest_1_Owner_ROLE) subject_2 = player.group.get_player_by_role(C.Forest_2_Owner_ROLE) player.choice_subject_1 = subject_1.management_choice player.choice_subject_2 = subject_2.management_choice # reporting subject choices if player.choice_subject_1 == 1: group_choice_report_1 = "Prescribed burn" elif player.choice_subject_1 == 2: group_choice_report_1 = 'Defensive Space' elif player.choice_subject_1 == 3: group_choice_report_1 = 'No Action' if player.choice_subject_2 == 1: group_choice_report_2 = "Prescribed burn" elif player.choice_subject_2 == 2: group_choice_report_2 = 'Defensive Space' elif player.choice_subject_2 == 3: group_choice_report_2 = 'No Action' # tells where fire started if subject_1.fire_chance <= 1 / 9: player.fire_start_subject_1 = True elif subject_1.fire_chance > 1 / 9: player.fire_start_subject_1 = False if subject_2.fire_chance <= 1 / 9: player.fire_start_subject_2 = True elif subject_2.fire_chance > 1 / 9: player.fire_start_subject_2 = False # reporting where fire started if player.fire_start_subject_1: group_fire_report_1 = 'A fire started in Forest 1' elif not player.fire_start_subject_1: group_fire_report_1 = 'A fire did not start in Forest 1' if player.fire_start_subject_2: group_fire_report_2 = 'A fire started in Forest 2' elif not player.fire_start_subject_2: group_fire_report_2 = 'A fire did not start in Forest 2' return{ "player.fire_started": player.fire_started, "fire_started_report": fire_started_report, 'management_choice_report': management_choice_report, # need to make it so group reports only show during perfect information !!!! 'group_choice_report_1': group_choice_report_1, 'group_choice_report_2': group_choice_report_2, 'group_fire_report_1': group_fire_report_1, 'group_fire_report_2': group_fire_report_2, } class QuestionsWaitPage(WaitPage): pass class Questions(Page): form_model = "player" form_fields = ["fire_on_actual_property", "damage_to_actual_home", "damage_to_other_physical_structure", "damage_to_actual_forest", "damage_to_other", "other_damage", "first_name", "last_name", "email"] @staticmethod def is_displayed(player: Player): return player.round_number == C.NUM_ROUNDS page_sequence = [IntroductionPage, IntroWaitPage, ChoicePage, ResultsWaitPage, Results, QuestionsWaitPage, Questions]