from otree.api import * author = 'Corey Scheinfeld' doc = """ Common Pool Rescource Game """ class Constants(BaseConstants): name_in_url = 'pool' players_per_group = 8 num_rounds = 5 endowment = cu(20) instructions_template = 'pool/instructions.html' class Subsession(BaseSubsession): pass class Group(BaseGroup): total_contribution = models.CurrencyField() total_payoff = models.CurrencyField() class Player(BasePlayer): ratio = models.FloatField() individual_share = models.CurrencyField() sent_tokens = models.CurrencyField( min=0, max=Constants.endowment, label="Pool Tokens" ) private_tokens = models.CurrencyField( min=0, max=Constants.endowment, label="Private Tokens" ) # FUNCTIONS def set_payoffs(group: Group): players = group.get_players() contributions = [p.sent_tokens for p in players] group.total_payoff = sum(contributions) x = group.total_payoff group.total_contribution = 11 * x - (1 / 16) * (x ** 2) for p in players: p.ratio = float(p.sent_tokens / sum(contributions)) p.individual_share = p.ratio * group.total_contribution p.payoff = p.private_tokens * 2 + p.individual_share p.ratio = round((p.ratio * 100), 2) # PAGES class Introduction(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 class Main(Page): form_model = 'player' form_fields = ['private_tokens', 'sent_tokens'] @staticmethod def error_message(player: Player, values): print('value is', values) if (values['sent_tokens'] + values['private_tokens']) != 20: return "Total currency distibution must equal 20" class ResultsWaitPage(WaitPage): after_all_players_arrive = set_payoffs class Results(Page): pass page_sequence = [Introduction, Main, ResultsWaitPage, Results]