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 = 'supplychain_2' 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) #included from QUIZ price = c(15) noagreement = c(0) sample_price = c(16) participation_fee = c(0.50) payoff_if_rejected = c(0) offer_increment = c(1) instructions_template = 'negotiation_2/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): # 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.001 p2.payoff = p2.points * 0.001 p3.payoff = p3.points * 0.001 class Player(BasePlayer): points = models.CurrencyField() strategy_accept = models.CurrencyField( choices=currency_range(Constants.production_cost, Constants.market_price, Constants.offer_increment), ) #included from QUIZ know_strategy = models.BooleanField() different_price = models.BooleanField() vintner_revenue = models.CurrencyField( choices=[ [1, '1500'], [2, '1100'], [3, '22'], [4, '0'], ] ) vintner_payoff = models.CurrencyField( choices=[ [1, '1,000'], [2, '10'], [3, '1'], [4, '0'], ] ) all_correct = models.BooleanField( initial=0 ) # checks if all answers have been answered correctly. def check_answers(self): if ((not self.know_strategy) and (self.different_price) and (self.vintner_revenue == 2) and (self.vintner_payoff == 3)): self.all_correct = True else: self.all_correct = False