from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) doc = """ This is a one-period public goods game with 3 players. """ class Constants(BaseConstants): name_in_url = 'public_goods' players_per_group = 4 num_rounds = 6 instructions_template = 'public_goods/Instructions.html' # """Amount allocated to each player""" endowment = c(20) multiplier = 1.6 # punished_reduction = 2 # punisher_reduction = 1 class Subsession(BaseSubsession): def creating_session(self): # Randomizing players but keeping their group ids fixed self.group_randomly(fixed_id_in_group=True) # # if self.round_number == num_rounds: # before_last_round = self.player.in_round(2).Results # for p in self.get_players(): # def vars_for_admin_report(self): contributions = [p.contribution for p in self.get_players() if p.contribution != None] if contributions: return { 'avg_contribution': sum(contributions)/len(contributions), 'min_contribution': min(contributions), 'max_contribution': max(contributions), } else: return { 'avg_contribution': '(no data)', 'min_contribution': '(no data)', 'max_contribution': '(no data)', } class Group(BaseGroup): total_contribution = models.CurrencyField() individual_share = models.CurrencyField() min_contribution = models.CurrencyField() #is_punish = models.BooleanField() min_player = models.IntegerField(initial=0) # l1 = [] # def set_payoffs(self): # self.total_contribution = sum([p.contribution for p in self.get_players()]) # self.individual_share = self.total_contribution * Constants.multiplier / Constants.players_per_group # for p in self.get_players(): # # p.payoff = (Constants.endowment - p.contribution) + self.individual_share def set_payoffs(self): self.total_contribution = sum([p.contribution for p in self.get_players()]) self.individual_share = self.total_contribution * Constants.multiplier / Constants.players_per_group # Get the minimum contribution self.min_contribution = min([p.contribution for p in self.get_players()]) # Calculate all payoffs Normally for p in self.get_players(): p.payoff = (Constants.endowment - p.contribution) + self.individual_share print("Minimum COntribution Outside LOop ",self.min_contribution) for p in self.get_players(): print("Player COntribution ",p.contribution) print("Minimum COntribution ",self.min_contribution) #Find the player with the minimum contribution if p.contribution == self.min_contribution: self.min_player = p.id_in_group print("Minimum Player In Loop",self.min_player) print("Minimum Player Outside",self.min_player) # self.l1.append(self.min_player) # print(self.l1) # print(self.l1) # If Punish is True, reduce payoffs of players for p in self.get_players(): # if p.contribution == self.min_contribution: # self.min_player = p.id_in_group # self.l1.append(self.min_player) # #Check player's decisiion to # if p.is_punish == 1: punished = self.get_player_by_role('punished') print("Punished Payoff Before ",punished.payoff) print("LEVEL VALUE ",p.level) if p.level == 0: # punished = self.get_player_by_role('punished') # # p.payoff = (Constants.endowment - p.contribution) + self.individual_share p.payoff = (p.payoff - 0) punished.payoff = (punished.payoff - 0) print("Punished Payoff After ",punished.payoff) print("Punished is ",punished.id_in_group) elif p.level == 1: # punished = self.get_player_by_role('punished') # # p.payoff = (Constants.endowment - p.contribution) + self.individual_share p.payoff = (p.payoff - 1) punished.payoff = (punished.payoff - 2) print("Punished Payoff After ",punished.payoff) print("YOU CHOSE ",p.level) elif p.level == 2: # punished = self.get_player_by_role('punished') # # p.payoff = (Constants.endowment - p.contribution) + self.individual_share p.payoff = (p.payoff - 2) punished.payoff = (punished.payoff - 4) print("Punished Payoff After ",punished.payoff) print("YOU CHOSE ",p.level) elif p.level == 3: # punished = self.get_player_by_role('punished') # p.payoff = (Constants.endowment - p.contribution) + self.individual_share p.payoff = (p.payoff - 3) punished.payoff = (punished.payoff - 6) print("Punished Payoff After ",punished.payoff) print("YOU CHOSE ",p.level) elif p.level == 4: # punished = self.get_player_by_role('punished') # p.payoff = (Constants.endowment - p.contribution) + self.individual_share p.payoff = (p.payoff - 4) punished.payoff = (punished.payoff - 8) print("Punished Payoff After ",punished.payoff) elif p.level == 5: # punished = self.get_player_by_role('punished') # p.payoff = (Constants.endowment - p.contribution) + self.individual_share p.payoff = (p.payoff - 5) punished.payoff = (punished.payoff - 10) print("Punished Payoff After ",punished.payoff) print("Punished is ",punished.id_in_group) elif p.level == 6: # punished = self.get_player_by_role('punished') # p.payoff = (Constants.endowment - p.contribution) + self.individual_share p.payoff = (p.payoff - 6) punished.payoff = (punished.payoff - 12) print("Punished Payoff After ",punished.payoff) elif p.level == 7: # punished = self.get_player_by_role('punished') # p.payoff = (Constants.endowment - p.contribution) + self.individual_share p.payoff = (p.payoff - 7) punished.payoff = (punished.payoff - 14) print("Punished Payoff After ",punished.payoff) elif p.level == 8: # punished = self.get_player_by_role('punished') # p.payoff = (Constants.endowment - p.contribution) + self.individual_share p.payoff = (p.payoff - 8) punished.payoff = (punished.payoff - 16) print("Punished Payoff After ",punished.payoff) elif p.level == 9: # punished = self.get_player_by_role('punished') # p.payoff = (Constants.endowment - p.contribution) + self.individual_share p.payoff = (p.payoff - 9) punished.payoff = (punished.payoff -18) print("Punished Payoff After ",punished.payoff) elif p.level == 10: # punished = self.get_player_by_role('punished') # p.payoff = (Constants.endowment - p.contribution) + self.individual_share p.payoff = (p.payoff - 10) punished.payoff = (punished.payoff - 20) print("Punished Payoff After ",punished.payoff) else: p.payoff = (Constants.endowment - p.contribution) + self.individual_share class Player(BasePlayer): contribution = models.CurrencyField( min=0, max=Constants.endowment, doc="""The amount contributed by the player""", ) # is_punish = models.BooleanField() level = models.IntegerField(choices=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], #level = models.IntegerField(choices=[0, 1, 2, 4, 6, 9, 12, 16, 20, 25, 30 ], widget=widgets.RadioSelectHorizontal) def role(self): print("Player with Min contribution in Player: ",self.group.min_player) # for member in self.group.l1: # print("-------------------------") # print(member) if self.id_in_group == self.group.min_player: return 'punished' else: return 'punisher'