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 = 'tough' players_per_group = 5 num_rounds = 4 instructions_template = 'tough/instructions.html' # """Amount allocated to each player""" endowment = c(100) multiplier = 2 class Subsession(BaseSubsession): def vars_for_admin_report(self): contributions = [ p.contribution for p in self.get_players() if p.contribution != None ] if contributions: return dict( avg_contribution=sum(contributions) / len(contributions), min_contribution=min(contributions), max_contribution=max(contributions), ) else: return dict( avg_contribution='(no data)', min_contribution='(no data)', max_contribution='(no data)', ) class Group(BaseGroup): total_contribution = models.CurrencyField() individual_share = models.CurrencyField() def set_payoffs(self): players = self.get_players() contributions = [p.contribution for p in players] self.total_contribution = sum(contributions) self.individual_share = self.total_contribution * Constants.multiplier / Constants.players_per_group for p in players: p.payoff = p.endowment - p.contribution + self.individual_share def set_endowment(self): for p in self.get_players(): p.set_endowment() def set_punishment(self): punished = { 0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0 } for p in self.get_players(): punished[p.punishment] = punished[p.punishment] +1 print(punished) player_max = 0 max = punished[0] for player, nb in punished.items(): if nb > max: player_max = player max = nb print(player_max) if player_max != 0 and max > len(self.get_players()) //2: self.punished_player = player_max player_max = self.get_player_by_id(player_max) earnings = (player_max.payoff - c(player_max.endowment - player_max.contribution)) / (Constants.players_per_group - 1) player_max.payoff = c(player_max.endowment - player_max.contribution) #for p in self.get_players(): #if p != player_max: #p.payoff = p.payoff + earnings #Redistribution (ligne 88,90,91) punished_player = models.IntegerField(initial=0) class Player(BasePlayer): contribution = models.CurrencyField( min=0, doc="""The amount contributed by the player""" ) def contribution_max(self): return self.endowment endowment = models.CurrencyField(initial=c(100)) def set_endowment(self): if self.in_previous_rounds() != []: self.endowment = self.in_previous_rounds()[-1].payoff punishment = models.IntegerField( initial=0, choices=[[1, 'Joueur 1'], [2, 'Joueur 2'], [3, 'Joueur 3'], [4, 'Joueur 4'], [5, 'Joueur 5'], [0, 'Personne']], label="Qui souhaitez-vous pénaliser ? Cette pénalité ne s'applique que si le joueur désigné reçoit au moins 3 voix sur 5. Ce vote est anonyme.", widget=widgets.RadioSelect, )