from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) from numpy import random,round doc = """ This is a normal games with 3x3 strategies. One player in the role of the online store and one player in the role of the customer. Both players are asked separately with which strategy they want to react to the scenario presented at the beginning of each round. Their decisions directly determine the payouts. """ class Constants(BaseConstants): name_in_url = 'shopping_game_3x3' players_per_group = 2 num_rounds = 12 instructions_template = 'shopping_game_3x3/Instructions.html' payoffmatrix_template = 'shopping_game_3x3/Payoffmatrix.html' class Subsession(BaseSubsession): def creating_session(self): strategies_P1 = [self.session.config['P1_strategy_1'], self.session.config['P1_strategy_2'], self.session.config['P1_strategy_3']] strategies_P2 = [self.session.config['P2_strategy_1'], self.session.config['P2_strategy_2'], self.session.config['P2_strategy_3']] strategies = [strategies_P1, strategies_P2] set_custom_random = self.session.config['Custom Random Payoffs'] user_distribution = self.session.config['Distribution'] user_center = self.session.config['Center of distribution'] user_width= self.session.config['Width of distribution'] def create_random_payoffs(distribution, center, width): if distribution == "Normal": random_payoffs = random.normal(center, width, size=[2,3,3]) #8 is the number of payoffs for 2 players game ,2x2 startgies if distribution == "Uniform": random_payoffs = random.uniform(center-width, center+width, size=[2,3,3]) return(round(random_payoffs,0))#rounding otherwise otree just cut the decimal part #to be improved if (set_custom_random == 'True') * (user_distribution != 'False') * (user_width > 0): payoffs = create_random_payoffs(user_distribution, user_center, user_width) if (set_custom_random == 'False') * (user_distribution == 'False') * (user_width == 0) *(user_center == 0): payoffs_P1 = [[self.session.config['P1_payoff_P1S1_P2S1'], self.session.config['P1_payoff_P1S1_P2S2'], self.session.config['P1_payoff_P1S1_P2S3']], [self.session.config['P1_payoff_P1S2_P2S1'], self.session.config['P1_payoff_P1S2_P2S2'], self.session.config['P1_payoff_P1S2_P2S3']], [self.session.config['P1_payoff_P1S3_P2S1'], self.session.config['P1_payoff_P1S3_P2S2'], self.session.config['P1_payoff_P1S3_P2S3']]] payoffs_P2 = [[self.session.config['P2_payoff_P2S1_P1S1'], self.session.config['P2_payoff_P2S1_P1S2'], self.session.config['P2_payoff_P2S1_P1S3']], [self.session.config['P2_payoff_P2S2_P1S1'], self.session.config['P2_payoff_P2S2_P1S2'], self.session.config['P2_payoff_P2S2_P1S3']], [self.session.config['P2_payoff_P2S3_P1S1'], self.session.config['P2_payoff_P2S3_P1S2'], self.session.config['P2_payoff_P2S3_P1S3']]] payoffs = [payoffs_P1, payoffs_P2] players = self.get_players() i = 0 for p in players: # first player gets first strategy, second player gets second strategy j = i%2 p.strategy_1 = strategies[j][0] p.strategy_2 = strategies[j][1] p.strategy_3 = strategies[j][2] p.payoff_selfS1_otherS1 = payoffs[j][0][0] p.payoff_selfS1_otherS2 = payoffs[j][0][1] p.payoff_selfS1_otherS3 = payoffs[j][0][2] p.payoff_selfS2_otherS1 = payoffs[j][1][0] p.payoff_selfS2_otherS2 = payoffs[j][1][1] p.payoff_selfS2_otherS3 = payoffs[j][1][2] p.payoff_selfS3_otherS1 = payoffs[j][2][0] p.payoff_selfS3_otherS2 = payoffs[j][2][1] p.payoff_selfS3_otherS3 = payoffs[j][2][2] i = i + 1 class Group(BaseGroup): pass class Player(BasePlayer): #demographic information residence = models.StringField( label="In which city do you live?") age = models.IntegerField( widget=widgets.RadioSelect, choices=[[1,'≤24'],[2,'25-34'],[3,'35-44'],[4,'45-54'],[5,'≥55']], label="What is your age?") gender = models.IntegerField( widget=widgets.RadioSelectHorizontal, choices=[[1,'female'],[2,'male'],[3,'other']], label="What is your gender?") #Define player role def role(self): if self.id_in_group == 1: return 'customer' else: return 'online store' strategy_1 = models.StringField() strategy_2 = models.StringField() strategy_3 = models.StringField() payoff_selfS1_otherS1 = models.IntegerField() payoff_selfS1_otherS2 = models.IntegerField() payoff_selfS1_otherS3 = models.IntegerField() payoff_selfS2_otherS1 = models.IntegerField() payoff_selfS2_otherS2 = models.IntegerField() payoff_selfS2_otherS3 = models.IntegerField() payoff_selfS3_otherS1 = models.IntegerField() payoff_selfS3_otherS2 = models.IntegerField() payoff_selfS3_otherS3 = models.IntegerField() decision = models.StringField( doc="""This player's decision""", widget=widgets.RadioSelect ) def decision_choices(self): choices = [self.strategy_1, self.strategy_2, self.strategy_3] return choices def other_player(self): return self.get_others_in_group()[0] ##continue here: add payoffs to matrix def set_payoff(self): payoff_matrix = { self.strategy_1: { self.other_player().strategy_1: self.payoff_selfS1_otherS1, self.other_player().strategy_2: self.payoff_selfS1_otherS2, self.other_player().strategy_3: self.payoff_selfS1_otherS3 }, self.strategy_2: { self.other_player().strategy_1: self.payoff_selfS2_otherS1, self.other_player().strategy_2: self.payoff_selfS2_otherS2, self.other_player().strategy_3: self.payoff_selfS2_otherS3 }, self.strategy_3: { self.other_player().strategy_1: self.payoff_selfS3_otherS1, self.other_player().strategy_2: self.payoff_selfS3_otherS2, self.other_player().strategy_3: self.payoff_selfS3_otherS3 } } self.payoff = payoff_matrix[self.decision][self.other_player().decision]