from otree.api import * import itertools doc = """ Your app description This is the Period 1 of the fishery game where participants plays the baseline (unregulated) game. """ class C(BaseConstants): NAME_IN_URL = 'fishery_game_P1' PLAYERS_PER_GROUP = 2 NUM_ROUNDS = 8 INSTRUCTIONS_TEMPLATE = 'fishery_game_P1/instructions.html' class Subsession(BaseSubsession): pass class Group(BaseGroup): treatment_group = models.IntegerField() low_state = models.BooleanField(initial=True, choices=[[True, 'low state'], [False, 'high state']]) pr_low_state = models.BooleanField(initial=True) #if the state was low in previous round pr2_low_state = models.BooleanField(initial=True) #if the state was low in the round before previous fisher_entered = models.IntegerField(initial=0) #how many fishermen entered area A fisher_not_entered = models.IntegerField(initial=0) #how many entered area B prev_fisher_entered = models.IntegerField(initial=0) #how many fishermen entered area A in previous round prev_rounds = models.IntegerField(initial=0) #how many fishermen entered area A in two previous rounds p = models.FloatField(initial=0, choices=[[0.1, '90%'], [0.3, '70%'], [0.5, '50%'], [0.8, '20%'], [1, '0%']]) #probabilities change = models.BooleanField(initial=False) #if the area change has happened after random probability function was called pr_change = models.BooleanField(initial=False) #if the change has happened in the previous round class Player(BasePlayer): area_choice = models.IntegerField(initial=None, choices=[[1, 'Area A'], [0, 'Area B']], widget=widgets.RadioSelectHorizontal, label="I choose to fish in:") punishment = models.IntegerField(choices=[[1, 'Yes'], [0, 'No']], label="Punish?") total_payoff = models.CurrencyField(initial=0) # FUNCTIONS def creating_session(subsession): treatments = itertools.cycle([1, 2, 3, 4]) for group in subsession.get_groups(): group.treatment_group = next(treatments) def calc_area_change(group: Group): players = group.get_players() enterance = [p.area_choice for p in players] group.fisher_entered = sum(enterance) group.fisher_not_entered = C.PLAYERS_PER_GROUP - group.fisher_entered print('entered:', group.fisher_entered) print('not entered:', group.fisher_not_entered) if group.round_number > 1: pr1 = group.in_round(group.round_number) pr2 = group.in_round(group.round_number - 1) group.low_state = pr2.low_state print('low state in prev round', pr2.low_state) print('low state in this round', group.low_state) print('entered this round', pr1.fisher_entered) print('entered previous round', pr2.fisher_entered) group.prev_fisher_entered = pr2.fisher_entered prev_rounds = pr1.fisher_entered + pr2.fisher_entered if prev_rounds == 0: group.low_state = False print('Area recovered') else: group.low_state = group.low_state def random_area_change(group: Group): if not group.low_state: import random random_numb = random.random() random_numb = round(random_numb, 2) print('START RANDOM: Round', group.round_number) print(random_numb) if group.fisher_entered == 0: group.p = 0.1 if random_numb <= group.p: group.low_state = True group.change = True print('RANDOM 0.1 CHANGED low state:', group.low_state) else: print('0.1 - random did not affect') print('fisher entered:', group.fisher_entered, 'generated random:', random_numb, 'VS', group.p) elif group.fisher_entered == 1: group.p = 0.3 if random_numb <= group.p: group.low_state = True group.change = True print('RANDOM 0.3 CHANGED low state:', group.low_state) else: print('0.3 - random did not affect') print('fisher entered:', group.fisher_entered, 'generated random:', random_numb, 'VS', group.p) elif group.fisher_entered == 2: group.p = 0.5 if random_numb <= group.p: group.low_state = True group.change = True print('RANDOM 0.5 CHANGED low state:', group.low_state) else: print('0.5 - random did not affect') print('fisher entered:', group.fisher_entered, 'generated random:', random_numb, 'VS', group.p) elif group.fisher_entered == 3: group.p = 0.8 if random_numb <= group.p: group.low_state = True group.change = True print('RANDOM 0.8 CHANGED low state:', group.low_state) else: print('0.8 - random did not affect') print('fisher entered:', group.fisher_entered, 'generated random:', random_numb, 'VS', group.p) elif group.fisher_entered >= 4: group.p = 1 group.low_state = True group.change = True print('100% deterioration') print(group.field_display('low_state')) def set_payoffs(group: Group): players = group.get_players() for p in players: if group.low_state: if p.area_choice == 1: p.payoff = 4 else: p.payoff = 3 else: if p.area_choice == 1: p.payoff = 10 else: p.payoff = 6 def area_history(group: Group): if group.round_number == 1: group.low_state = group.low_state group.pr_low_state = group.pr_low_state else: pr1_round = group.in_round(group.round_number - 1) group.low_state = pr1_round.low_state group.pr_change = pr1_round.change group.fisher_entered = pr1_round.fisher_entered group.pr_low_state = pr1_round.pr_low_state group.prev_fisher_entered = pr1_round.prev_fisher_entered if group.round_number > 2: pr2_round = group.in_round(group.round_number - 2) group.pr2_low_state = pr2_round.pr2_low_state # PAGES class Introduction(Page): @staticmethod def is_displayed(player): return player.round_number == 1 class Decide(Page): form_model = 'player' form_fields = ['area_choice'] @staticmethod def vars_for_template(player: Player): group = player.group return area_history(group) class ResultsWaitPage(WaitPage): body_text = "Waiting for the other participant to decide." after_all_players_arrive = set_payoffs print('payoffs set') class ResultsWaitPage2(WaitPage): after_all_players_arrive = calc_area_change print('area status calculated') class Feedback(Page): pass class Probabilities(Page): @staticmethod def is_displayed(player): group = player.group return player.round_number > 2 and not group.low_state class ResultsWaitPage3(WaitPage): after_all_players_arrive = random_area_change class Random(Page): @staticmethod def is_displayed(player): group = player.group return player.round_number > 2 class Punishment(Page): form_model = 'player' form_fields = ['punishment'] class Feedback(Page): page_sequence = [Introduction, Decide, ResultsWaitPage, ResultsWaitPage2, Feedback, Probabilities, ResultsWaitPage3, Random, Punishment]