from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range, ) import random author = 'Max Reuning & Stefano Pomponio' doc = """ This is the second part of a series of experiments designed to examine the perceived negotiation power between suppliers and retailers. The experiment is based on an ultimatum game between one supplier and two retailers. The use of points has to be enabled in settings.py. To make revenue look more realistic, you might want to change points to "€" in the settings.py. """ class Constants(BaseConstants): name_in_url = 'negotiation_3' players_per_group = 3 num_rounds = 1 # These variables do not store any value. The templates refer to them. # In case that the roles or the name of the product have to be changed, they do not have to be changed one by one in the templates. good = 'units of some good' p1 = 'vintner' p2 = 'supermarket 1' p3 = 'supermarket 2' ps = 'supermarkets' units = 100 production_cost = c(5) market_price = c(21) payoff_if_rejected = c(0) offer_increment = c(1) instructions_template = 'negotiation_3/Instructions.html' class Subsession(BaseSubsession): # participants keep their role while groups are reshuffled def before_session_starts(self): self.group_randomly(fixed_id_in_group=True) # selecting one round randomly to calculate payoff def creating_session(self): if self.round_number == 1: paying_round = random.randint(1, Constants.num_rounds) self.session.vars['paying_round'] = paying_round class Group(BaseGroup): # agreement is randomly set agreement = models.CurrencyField() def set_agreement(self): self.agreement = random.choice([c(9), c(13), c(17)]) # p1 is asked if he wants to offer the agreement offer_agreement = models.BooleanField( ) # the offer made by p1 to p2 offer1 = models.CurrencyField( choices=currency_range(Constants.production_cost, Constants.market_price, Constants.offer_increment), ) # the offer made by p1 to p3 if p2 rejected offer2 = models.CurrencyField( choices=currency_range(Constants.production_cost, Constants.market_price, Constants.offer_increment), ) # checks if p2 / p3 accepted the offer actual_accept_1 = models.BooleanField() actual_accept_2 = models.BooleanField() def set_payoffs(self): # The player variable "points" is referred to as "revenue" in the experiment. "payoff" sets the real, monetary payoff. p1, p2, p3 = self.get_players() if self.actual_accept_1: p1.points = (Constants.units * self.offer1) - (Constants.units * Constants.production_cost) p2.points = (Constants.market_price * Constants.units) - (Constants.units * self.offer1) p3.points = Constants.payoff_if_rejected elif self.actual_accept_2: p1.points = (Constants.units * self.offer2) - (Constants.units * Constants.production_cost) p2.points = Constants.payoff_if_rejected p3.points = (Constants.market_price * Constants.units) - (Constants.units * self.offer2) else: p1.points = Constants.payoff_if_rejected p2.points = Constants.payoff_if_rejected p3.points = Constants.payoff_if_rejected # The monetary payoff is calculated in the randomly selected round. if (self.round_number == self.session.vars['paying_round']): p1.payoff = p1.points * 0.02 p2.payoff = p2.points * 0.02 p3.payoff = p3.points * 0.02 class Player(BasePlayer): points = models.CurrencyField() strategy_accept = models.CurrencyField( choices=currency_range(Constants.production_cost, Constants.market_price, Constants.offer_increment), )