from otree.api import * c = Currency # old name for currency; you can delete this. doc = """ this app contains the game """ class Constants(BaseConstants): name_in_url = 'tradegamegroups' players_per_group = 10 num_rounds = 1 endowment = 10 max_income = 12 min_income = 6 class Subsession(BaseSubsession): pass class Group(BaseGroup): tax = models.CurrencyField(initial=0) benefit = models.CurrencyField(initial=0) for_votes = models.CurrencyField(initial=0) against_votes = models.CurrencyField(initial=0) for_votes_treatment = models.CurrencyField(initial=0) against_votes_treatment = models.CurrencyField(initial=0) treatment_tax = models.BooleanField() class Player(BasePlayer): winner = models.BooleanField(initial=True) give = models.CurrencyField(label="I want to put into the common pot:", min=0, max=Constants.max_income, initial=0) vote_for = models.CurrencyField(label='I want to invest for the game allocation:', min=0, initial=0) vote_against = models.CurrencyField(label='I want to invest against the game allocation:', min=0, initial=0) vote_for_treatment = models.CurrencyField(label='I want to invest for the game allocation:', min=0, initial=0) vote_against_treatment = models.CurrencyField(label='I want to invest against the game allocation:', min=0, initial=0) treatment_tax_p = models.BooleanField() # FUNCTIONS def creating_session(subsession): # creates two treatment groups (with or without reimbursement for losers) import itertools pressures = itertools.cycle([True, False]) for group in subsession.get_groups(): group.treatment_tax = next(pressures) def treatment(group: Group): # maps the treatment value of the group to the player, easier to use later if group.treatment_tax: for p in group.get_players(): p.treatment_tax_p = True else: for p in group.get_players(): p.treatment_tax_p = False def globalisation(group: Group): # 2 players are the large losers, the rest are the small winners for p in group.get_players(): if p.id_in_group < 3: p.winner = False for p in group.get_players(): if p.winner: p.payoff = Constants.max_income else: p.payoff = Constants.min_income def payoffs(group: Group): # payoffs after the winners reimburse losers (only in treatment) for p in group.get_players(): group.tax += p.give group.benefit = group.tax / 2 if group.treatment_tax: for p in group.get_players(): if p.winner: p.payoff = p.payoff - p.give else: p.payoff = p.payoff + group.benefit else: for p in group.get_players(): p.payoff = p.payoff def vote_payoffs_treatment(group: Group): # payoffs after players vote for or against the game (fct for treatment) for p in group.get_players(): group.for_votes_treatment += p.vote_for_treatment group.against_votes_treatment += p.vote_against_treatment for p in group.get_players(): if group.for_votes_treatment > group.against_votes_treatment: p.payoff = p.payoff - p.vote_for_treatment - p.vote_against_treatment else: p.payoff = Constants.endowment - p.vote_for_treatment - p.vote_against_treatment def vote_payoffs(group: Group): # payoffs after players vote for or against the game for p in group.get_players(): group.for_votes += p.vote_for group.against_votes += p.vote_against for p in group.get_players(): if group.for_votes > group.against_votes: p.payoff = p.payoff - p.vote_for - p.vote_against else: p.payoff = Constants.endowment - p.vote_for - p.vote_against # PAGES class Intro(Page): pass class IntroWaitPage(WaitPage): after_all_players_arrive = globalisation class TreatmentWaitpage(WaitPage): after_all_players_arrive = treatment class Globalisation(Page): pass class Redistribution(Page): # following three pages are only for the treatment group form_model = 'player' form_fields = ['give'] @staticmethod def is_displayed(player: Player): return player.treatment_tax_p and player.winner class ResultsWaitPage(WaitPage): after_all_players_arrive = payoffs @staticmethod def is_displayed(player: Player): return player.treatment_tax_p class Results(Page): @staticmethod def is_displayed(player: Player): return player.treatment_tax_p class Vote(Page): # every page each for treatment and non treatment from here on form_model = 'player' form_fields = ['vote_for', 'vote_against'] @staticmethod def error_message(player: Player, values): print('values is', values) if values['vote_for'] + values['vote_against'] > Constants.endowment: return 'Your total investment can not be larger than 10' @staticmethod def is_displayed(player: Player): return not player.treatment_tax_p class Vote_treatment(Page): form_model = 'player' form_fields = ['vote_for_treatment', 'vote_against_treatment'] @staticmethod def error_message(player: Player, values): print('values is', values) if values['vote_for_treatment'] + values['vote_against_treatment'] > Constants.endowment: return 'Your total investment can not be larger than 10' @staticmethod def is_displayed(player: Player): return player.treatment_tax_p class VoteWaitpage_treatment(WaitPage): after_all_players_arrive = vote_payoffs_treatment @staticmethod def is_displayed(player: Player): return player.treatment_tax_p class VoteWaitpage(WaitPage): after_all_players_arrive = vote_payoffs @staticmethod def is_displayed(player: Player): return not player.treatment_tax_p class VoteResults_treatment(Page): @staticmethod def is_displayed(player: Player): return player.treatment_tax_p class VoteResults(Page): @staticmethod def is_displayed(player: Player): return not player.treatment_tax_p page_sequence = [Intro, IntroWaitPage, TreatmentWaitpage, Globalisation, Redistribution, ResultsWaitPage, Results, Vote, Vote_treatment, VoteWaitpage_treatment, VoteWaitpage, VoteResults_treatment, VoteResults]