from otree.api import * import random c = Currency doc = """ Your app description """ # Add a chat for participants! DONE # Add sth that shows how many salmons left to fish and bears! # Define the thresholds and recovery rates # assegna a ciascun partecipante un id_in_group: is it necessary? DONE # ADD A LOCK-IN TASK, A REAL EFFORT TASK SO THAT ONLY THOSE WHO ARE SERIOUSLY INTERESTED WILL PLAY # add timeouts and a page says you should move: in the round page # Replacing dropped out player with a bot: https://otree.readthedocs.io/en/latest/multiplayer/waitpages.html # To access data from a previous round or app, you can use one of the techniques described below. # in_rounds, in_previous_rounds, in_round, etc. # For example, to get the player’s payoff in the previous round, you would do: # prev_player = player.in_round(player.round_number - 1) # print(prev_player.payoff) # to assign participants to different treatment groups, you can use creating_session. # If your game has multiple rounds, a player could have different treatments in different rounds, because # creating_session gets executed for each round independently. To prevent this, set it on the participant, # rather than the player: # def creating_session(subsession): # Balanced treatment groups # The above code makes a random drawing independently for each player, so you may end up with an imbalance. # To solve this, you can use itertools.cycle: # randomise players class Constants(BaseConstants): name_in_url = 'ecosystem_game' players_per_group = 4 num_rounds = 16 fish_value = 0.25 fish_stock = 50 bear_value = 0.10 bear_stock = 50 class Subsession(BaseSubsession): pass class Group(BaseGroup): total_harvest = models.IntegerField() bears_remained = models.IntegerField() remaining_fish_stock = models.IntegerField() remaining_bear_stock = models.IntegerField() class Player(BasePlayer): harvest = models.IntegerField( min=0, max=Constants.fish_stock, label="How many salmons do you want to harvest?" ) # Functions # define variable fish & bear stock # PAGES class Introduction(Page): """Description of the game: How to play and returns expected""" pass # show only during the first round class Instructions(Page): pass # show only during the first round class ShortGame(Page): form_model = "player" form_fields = "number_entered" def vars_for_template(player: Player): number_1 = random.randint(1, 100) number_2 = random.randint(1, 100) player.sum_of_numbers = number_1 + number_2 return { "number_1": number_1, "number_2": number_2, } def before_next_page(player: Player, timeout_happened): # after the player has pushed the button if player.sum_of_numbers == player.number_entered: player.payoff = Constants.payment_per_correct_answer class Harvest(Page): form_model = "player" form_fields = ["harvest"] class ResultsWaitPage(WaitPage): body_text = "Waiting for other participants to contribute." class Results(Page): def after_all_players_arrive(self): total_harvest = 0 for player in self.group.get_players(): total_harvest += player.harvest self.group.total_harvest = total_harvest self.group.bears_remained = total_harvest def set_payoffs(self): players = self.group.get_players() harvest = [p.harvest for p in players] self.group.total_harvest = sum(harvest) for player in players: player.payoff = self.group.total_harvest * Constants.bear_value + player.harvest * Constants.fish_value, list_of_individual_harvest: list = [player.harvest] for player in player.get_others_in_group(): list_of_individual_harvest.append(player.harvest) return { "list_of_individual_harvest": list_of_individual_harvest, } class CombinedResults(Page): def is_displayed(self): return self.round_number == Constants.num_rounds def vars_for_template(player: Player): all_players = player.in_all_rounds() combined_payoff = 0 for player in all_players: combined_payoff += player.payoff return { "combined_payoff": combined_payoff } page_sequence = [Introduction, Instructions, ShortGame, Harvest, ResultsWaitPage, Results, CombinedResults]