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 = 'Cournot3' players_per_group = 2 num_rounds = 10 max_quality_high = 6. min_quality_high = 3.1 max_quality_low = 3. min_quality_low = 0.01 max_price_high = 12. min_price_high = 0.1 max_price_low = 12. min_price_low = 0.1 theta_upper = 5. theta_lower = 4. c = 1. pay = 0.47 close_q_high = 0.6 close_q_low = 0.11 close_p_high = 1.6 close_p_low = 0.2 # Parameters of uncertainty kh = 1. kl = 1. #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): 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 = (Constants.theta_upper - (play_high.ph-play_low.pl)/(Constants.kh*play_high.vh - Constants.kl*play_low.vl))/(Constants.theta_upper - Constants.theta_lower) Dl = ((play_high.ph-play_low.pl)/(Constants.kh*play_high.vh - Constants.kl*play_low.vl) - (play_low.pl)/(Constants.kl*play_low.vl))/(Constants.theta_upper - Constants.theta_lower) if Dh>1: #Overwrite Dh Dh=Dh elif Dh<0: # Overwrite Dh Dh=0 else: Dh=Dh if Dl>1: #Overwrite Dl Dl=Dl elif Dl<0: # Overwrite Dl 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 - (play_high.vh ** Constants.alpha) / Constants.alpha ) #play_low.payoff = Constants.r*(play_low.pl * Dl - (play_low.vl ** Constants.alpha) / Constants.alpha) if ((abs(play_high.vl_guess_1 - play_low.vl) < Constants.close_q_low) and (abs(play_high.pl - play_low.pl) < Constants.close_p_low)): play_high.payoff = (play_high.ph * Dh - (play_high.vh ** Constants.alpha) / Constants.alpha) - (Constants.c*play_high.vh*Dh) + Constants.pay + Constants.pay elif ((abs(play_high.vl_guess_1 - play_low.vl) < Constants.close_q_low) and (abs(play_high.pl - play_low.pl) > Constants.close_p_low)): play_high.payoff = (play_high.ph * Dh - (play_high.vh ** Constants.alpha) / Constants.alpha) - (Constants.c*play_high.vh*Dh) + Constants.pay elif ((abs(play_high.vl_guess_1 - play_low.vl) > Constants.close_q_low) and (abs(play_high.pl - play_low.pl) < Constants.close_p_low)): play_high.payoff = (play_high.ph * Dh - (play_high.vh ** Constants.alpha) / Constants.alpha) - (Constants.c*play_high.vh*Dh) + Constants.pay else: play_high.payoff = (play_high.ph * Dh - (play_high.vh ** Constants.alpha) / Constants.alpha) - (Constants.c*play_high.vh*Dh) if ((abs(play_low.vh_guess_1 - play_high.vh) < Constants.close_q_high) and (abs(play_low.ph - play_high.ph) < Constants.close_p_high)): play_low.payoff = Constants.r * ( play_low.pl * Dl - (play_low.vl ** Constants.alpha) / Constants.alpha) + Constants.pay + Constants.pay - (Constants.c*play_low.vl*Dl) elif ((abs(play_low.vh_guess_1 - play_high.vh) < Constants.close_q_high) and (abs(play_low.ph - play_high.ph) > Constants.close_p_high)): play_low.payoff = Constants.r * (play_low.pl * Dl - (play_low.vl ** Constants.alpha) / Constants.alpha) - (Constants.c*play_low.vl*Dl) + Constants.pay elif ((abs(play_low.vh_guess_1 - play_high.vh) > Constants.close_q_high) and (abs(play_low.ph - play_high.ph) < Constants.close_p_high)): play_low.payoff = Constants.r * (play_low.pl * Dl - (play_low.vl ** Constants.alpha) / Constants.alpha) - (Constants.c*play_low.vl*Dl) + Constants.pay else: play_low.payoff = Constants.r * (play_low.pl * Dl - (play_low.vl ** Constants.alpha) / Constants.alpha) - (Constants.c*play_low.vl*Dl) # 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' # Quality page 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?") vh_guess_1 = 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 = models.FloatField(min=Constants.min_quality_low, max=Constants.max_quality_low, # widget=widgets.SliderInput(), label="What is the quality label of your product?") vl_guess_1 = 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_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?") ph_guess_2 = 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_2 = models.FloatField(min=Constants.min_price_low, max=Constants.max_price_low, label="Guess how much you think your competitor will set prices?") #### Price page 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?")