from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) import random author = 'Francisco' doc = """ This game is a modification of the duopoly version of Musa-Rosen. See Scott and Sesmero (2020) for more details. """ # Constants are the parameters of the game shared by everyone class Constants(BaseConstants): name_in_url = 'my_quality_game_bench_kl_065_discrete_choice' players_per_group = 2 num_rounds = 10 max_quality_high = 50. min_quality_high = 16. max_quality_low = 15. min_quality_low = 2. max_price_high = 2700. min_price_high = 590. max_price_low = 150. min_price_low = 50. # Parameters of uncertainty kh = 1.0 kl = 0.65 #instructions_template = 'my_quality/instructions.html' # ratio of optimal qualities under kh r = 1 # Cost parameters alpha = 2 class Subsession(BaseSubsession): def creating_session(self): if self.round_number == 1: #list_num_round = list(range(1, Constants.num_rounds+1)) #print(list_num_round) paying_round = random.sample(range(1,Constants.num_rounds+1),4) self.session.vars['paying_round'] = paying_round print('set the paying round to', paying_round) if self.round_number != 10000: self.group_randomly() print(self.get_group_matrix()) class Group(BaseGroup): # STILL HAVE TO ADD A BUTTON TO OPT OUT OF THE ROUND # We can use the main field here since it is a sequential game; if simultaneous, set this in player #### PAGE 1, leader vh = models.FloatField(min=Constants.min_quality_high, max=Constants.max_quality_high, #widget = widgets.Slider, label="What is the quality label of your product?") vl_guess_1 = models.FloatField(min=Constants.min_quality_low, max=Constants.max_quality_low, label="Guess how much you think your competitior will set his quality?") ph_guess_1 = models.FloatField(min=Constants.min_price_high, max=Constants.max_price_high, label="Given quality choices, how much you will set your prices?") pl_guess_1 = models.FloatField(min=Constants.min_price_low, max=Constants.max_price_low, label="Guess how much you think your competitor will set prices?") #### PAGE 1, follower vl = models.FloatField(min=Constants.min_quality_low, max=Constants.max_quality_low, # widget=widgets.SliderInput(), label="What is the quality label of your product?") ph_guess_2 = models.FloatField(min=Constants.min_price_high, max=Constants.max_price_high, label="Guess how much you think your competitor will set prices") pl_guess_2 = models.FloatField(min=Constants.min_price_low, max=Constants.max_price_low, label="Given quality choices, how much you will set your prices?") def set_payoffs(self): play_high = self.get_player_by_role('Leader') play_low = self.get_player_by_role('Follower') print("#### Choices ####") print(type(self.vh)) print(type(self.vl)) print(type(play_high.ph)) print(type(play_low.pl)) print(type(Constants.kh)) # These are the demand formulas Dh = (100 - (play_high.ph-play_low.pl)/(Constants.kh*self.vh - Constants.kl*self.vl))/(100 - 0) Dl = ((play_high.ph-play_low.pl)/(Constants.kh*self.vh - Constants.kl*self.vl) - (play_low.pl)/(Constants.kl*self.vl))/(100-0) if Dh>1: #Overwrite Dh Dh=1 elif Dh<0: # Overwrite Dh Dh=0 else: Dh=Dh if Dl>1: #Overwrite Dh Dl=1 elif Dl<0: # Overwrite Dh Dl=0 else: Dl=Dl # Calculate the payment #print(self.subsession.round_number) print(type(self.session.vars['paying_round'])) if (self.subsession.round_number in self.session.vars['paying_round']): play_high.payoff = (play_high.ph * Dh - (self.vh ** Constants.alpha) / Constants.alpha) play_low.payoff = Constants.r * (play_low.pl * Dl - (self.vl ** Constants.alpha) / Constants.alpha) # if play_high.ph * Dh - (self.vh ** Constants.alpha) / Constants.alpha >0.0: # play_high.payoff = (play_high.ph * Dh - (self.vh ** Constants.alpha) / Constants.alpha ) # else: # play_high.payoff = 0 # if play_low.pl * Dl - (self.vl ** Constants.alpha) / Constants.alpha >0 : # play_low.payoff = Constants.r*(play_low.pl * Dl - (self.vl ** Constants.alpha) / Constants.alpha) # else: # play_low.payoff = 0 print(play_high.payoff) print(play_low.payoff) #if self.subsession.round_number == self.session.vars['paying_round']: class Player(BasePlayer): def role(self): if self.id_in_group % 2 == 0: return 'Leader' if self.id_in_group % 2 != 0: return 'Follower' #### PAGE 3, leader's prices ph = models.FloatField(min=Constants.min_price_high, max=Constants.max_price_high, label="Given quality choices, how much you will set your prices?") # pl_guess_3 = models.FloatField(min=Constants.min_price_low, # max=Constants.max_price_low, # label="Guess how much you think your competitor will set prices?") ##### PAGE 4, follower's price # ph_guess_3 = models.FloatField(min=Constants.min_price_high, # max=Constants.max_price_high, # label="Guess how much you think your competitor will set prices") pl = models.FloatField(min=Constants.min_price_low, max=Constants.max_price_low, label="Given quality choices, how much you will set your prices?")