from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) import random author = 'Claudia Marangon' doc = """ Your app description """ class Constants(BaseConstants): name_in_url = 'main_game' players_per_group = 10 num_rounds = 30 # SET TO 30 FOR FULL GAME or SET TO 3 FOR SHORT TEST table_payoffs = 'main_game/table_payoffs.html' table_payoffs_one_conn = 'main_game/table_payoffs_one_conn.html' end = 3.5 earning_a = 10 earning_i = 0 norm_cost = 3.5 red_cost = 0 class Subsession(BaseSubsession): def creating_session(self): if self.round_number == 1: for p in self.get_players(): p.participant.vars['active'] = 1 p.participant.vars['rounds_1_10'] = [] p.participant.vars['rounds_11_20'] = [] p.participant.vars['rounds_21_30'] = [] for g in self.get_groups(): conn = [1, 1, 1, 1, 1, 3, 3, 3, 3, 3] g.red_cost = 3 #Set number of connection with reduced cost (either 1 or 3) for p in g.get_players(): p.connections = random.choice(conn) conn.remove(p.connections) if p.connections==1: p.prob = random.randint(1,2) else: p.prob = random.randint(1,20) # here p.prob is assigned a random integer from 1 to 20 pass class Group(BaseGroup): red_cost = models.IntegerField() no_net = models.StringField() def set_payoff(self): if self.round_number==1: for p in self.get_players(): p.participant.vars['main_pay']=0 conn_3 = [p for p in self.get_players() if p.connections == 3 and p.participant.vars['active'] == 1] conn_1 = [p for p in self.get_players() if p.connections == 1 and p.participant.vars['active'] == 1] prob_1 = [p.prob for p in conn_1] prob_3 = [p.prob for p in conn_3] if 1 in prob_1 and len(conn_1)<2: conn_1_1_lim=1 else: conn_1_1_lim = 0 if 2 in prob_1 and len(conn_3)<1: conn_1_2_lim = 1 else: conn_1_2_lim=0 if 1 in prob_3 and len(conn_1)<3: conn_3_1_lim=1 else: conn_3_1_lim = 0 if (2 in prob_3 or 3 in prob_3 or 4 in prob_3) and (len(conn_1)<2 or len(conn_3)<2): conn_3_2_lim = 1 else: conn_3_2_lim = 0 if (5 in prob_3 or 6 in prob_3 or 7 in prob_3) and (len(conn_1)<1 or len(conn_3)<3): conn_3_3_lim = 1 else: conn_3_3_lim = 0 if 8 in prob_3 and len(conn_3)<4: conn_3_4_lim = 1 else: conn_3_4_lim=0 if conn_1_1_lim==1 or conn_1_2_lim==1 or conn_3_1_lim==1 or conn_3_2_lim==1 or conn_3_3_lim==1 or conn_3_4_lim==1: self.no_net='True' for p in self.get_players(): p.payoff=-9 print(p.participant.vars['active']) else: for p in self.get_players(): if p not in conn_1 and p not in conn_3: p.payoff=-9 else: if self.round_number > Constants.num_rounds/3 and self.round_number <= Constants.num_rounds*2/3 and self.red_cost==1: if p in conn_1: p.cost=Constants.red_cost else: p.cost=Constants.norm_cost elif self.round_number > Constants.num_rounds/3 and self.round_number <= Constants.num_rounds*2/3 and self.red_cost==3: if p in conn_3: p.cost=Constants.red_cost else: p.cost=Constants.norm_cost else: p.cost=Constants.norm_cost if p in conn_1: p.prob = random.randint(1, 2) conn_1.remove(p) if p.prob == 1: p_partner = [random.choice(conn_1)] else: p_partner = [random.choice(conn_3)] par = p_partner[0] if p.choice=='active': if par.choice == 'active': p.earning=Constants.earning_a p.active_conn = 1 p.inactive_conn = 0 else: p.earning = Constants.earning_i p.inactive_conn = 1 p.active_conn = 0 p.payoff = p.earning + Constants.end - p.cost else: p.cost=0 if par.choice == 'active': p.active_conn = 1 p.inactive_conn = 0 else: p.active_conn = 0 p.inactive_conn = 1 p.payoff = Constants.earning_i + Constants.end conn_1.append(p) else: conn_3.remove(p) if p.prob == 1: p_partner = random.sample(conn_1, 3) elif p.prob > 1 and p.prob < 11: # p.prob in [2,10], i.e. takes 9 possible values p_partner = random.sample(conn_1, 2) p_partner.append(random.choice(conn_3)) elif p.prob > 10 and p.prob < 20: # p.prob in [11,19], i.e. takes 9 possible values p_partner = random.sample(conn_3, 2) p_partner.append(random.choice(conn_1)) else: # i.e. p.prob == 20 p_partner = random.sample(conn_3, 3) part_choice = [par.choice for par in p_partner] n = 0 for c in part_choice: if c == 'inactive': n += 1 p.active_conn = 3 - n p.inactive_conn = n if p.choice == 'active': if 'inactive' in part_choice: p.earning = Constants.earning_i else: p.earning = Constants.earning_a p.payoff = p.earning + Constants.end - p.cost else: p.cost=0 p.payoff = Constants.earning_i + Constants.end conn_3.append(p) partners = ['Player '+str(player.id_in_group)+' ' for player in p_partner] p.partners = "".join(partners) for p in self.get_players(): if self.round_number<11: #SET TO 11 FOR FULL GAME or SET TO 2 FOR SHORT TEST p.participant.vars['rounds_1_10'].append(p.payoff) elif self.round_number in range(11, 21): #SET TO (11, 21) FOR FULL GAME or SET TO (2, 3) FOR SHORT TEST p.participant.vars['rounds_11_20'].append(p.payoff) else: p.participant.vars['rounds_21_30'].append(p.payoff) pass class Player(BasePlayer): earning=models.FloatField() cost = models.FloatField() partners = models.LongStringField() connections = models.IntegerField() prob = models.IntegerField() act = models.IntegerField() choice = models.StringField( choices=['active', 'inactive', '-9'], widget=widgets.RadioSelect ) active_conn = models.IntegerField() inactive_conn = models.IntegerField() pass