from otree.api import * doc = """ Game 1 with hidden Results """ class Constants(BaseConstants): name_in_url = 'Game_Hidden' players_per_group = 5 num_rounds = 5 num_rounds_with_all_players = 3 Initial_Forest = 10000 class Subsession(BaseSubsession): remaining_forest = models.FloatField(initial=Constants.Initial_Forest) class Group(BaseGroup): total_contribution = models.FloatField(initial=0) class Player(BasePlayer): choice = models.FloatField( min=0, max=15, label="Please choose your cutting quote for this season, which has to be between 0% and 15%" ) isSkipped = models.BooleanField(initial=False) # FUNCTIONS def set_payoffs(group: Group): subsession = group.subsession players = list(filter(lambda p: not p.isSkipped, group.get_players())) group.total_contribution = sum(p.choice for p in players) for p in players: p.payoff = round((p.choice / 100) * subsession.remaining_forest, 1) subsession.remaining_forest = round((subsession.remaining_forest - subsession.remaining_forest * (group.total_contribution / 100)) * 1.3, 1) # PAGES class Decision(Page): form_model = 'player' form_fields = ['choice'] @staticmethod def vars_for_template(player: Player): # Copy over remaining_forest from previous round if player.subsession.round_number > 1: player.subsession.remaining_forest = player.subsession.in_round(player.subsession.round_number - 1).remaining_forest @staticmethod def is_displayed(player): # Always show the screen in the first three rounds if player.round_number <= Constants.num_rounds_with_all_players: return True # Remove the worst player after round 3 calculateIsSkipped(player.group) return not player.isSkipped class ResultsWaitPage(WaitPage): template_name = 'Game_Hidden/WaitPage.html' after_all_players_arrive = set_payoffs class Results(Page): @staticmethod def vars_for_template(player: Player): return dict( isLastRound=player.round_number is Constants.num_rounds ) @staticmethod def is_displayed(player): # Always show the screen in last round if player.round_number is Constants.num_rounds: return True # Always show the screen in the first three rounds if player.round_number <= Constants.num_rounds_with_all_players: return True # Remove the worst player after round 3 calculateIsSkipped(player.group) return not player.isSkipped page_sequence = [Decision, ResultsWaitPage, Results] def calculateIsSkipped(group: Group): sortedList = group.get_players().copy() sortedList.sort(key=lambda p: p.payoff) for i in range(len(sortedList)): sortedList[i].isSkipped = i == 0 # This experiment is inspired by my Bachelors Thesis, which was about the Commons # and the book Govering the commons by Elinor Ostrom. Since I think it is complicated to choose the right amount of # participants previously and define a good quote. I estimated that 5 players and 30 reg. quote would be enough to # destroy the forest. But after running a few rounds it would be very easy to adjust the correct amount of players per # group and choose maybe a lower reg. rate. # Nevertheless, with this experiment and the settings I chose I thought, it would # be possible to show the Tragedy of the Commons in an experiment. By letting the participants know, that after # 3 rounds the lowest has to leave the game as a punishment (which is equal to Competition on markets, # where e.g. the lowest company will go bankrupt) I really want to enforce the people to use the resources # and cut trees,plus also the fact,that people can hide and will not be blamed for always choosing 15%, as in # real-life it is sometimes really hard to detect the companies polluting the environment. # On the other hand the forest has the power to regenerate on his own and by an optimal usage # would be even healthier as before. It would also be possible to set the regenerating rate to zero or # change the settings afterwards and e.g let people chat to define a quote (as for example # in a hewberg it is often the case) or as another alternative make a price for trees available, which will # automatically be adjusted to world demand or in our case supply (amount of felled trees). At the end of the 5 rounds, # intentionally the results from all participants will be hidden. Such that in another round people do not know who # is responsible. # Additionally, in my opinion it is useful to see how sales/gains will fall for all participants if they choose high # rates and how slowly the forest will regenerates once it had been destroyed.