from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) import random import itertools doc = """ This is a standard 2-player endoo game where the amount sent by player 1 gets tripled. The endo game was first proposed by Berg, Dickhaut, and McCabe (1995) . """ class Constants(BaseConstants): name_in_url = 'endo' players_per_group = None num_rounds = 10 instructions_template = 'endo/instructions.html' table_template = 'endo/table.html' # Initial amount allocated to players endowment_Decider = c(9) endowment_Receiver = c(1) multiplier = 1 class Subsession(BaseSubsession): def creating_session(self): if self.round_number == 1: colors = itertools.cycle(['BLUE', 'RED']) for p in self.get_players(): p.color = next(colors) else: for p in self.get_players(): p.color = p.in_round(self.round_number - 1).color self.group_randomly() def assign_sequence(self): blue_players = [p for p in self.get_players() if p.color == 'BLUE'] blue_players.sort(key=lambda x: x.WTP, reverse=True) red_players = [p for p in self.get_players() if p.color == 'RED'] red_players.sort(key=lambda x: x.WTP, reverse=True) rand_num = random.randint(0, 10) if blue_players[0].WTP >= red_players[0].WTP: pl = blue_players.pop(0) else: pl = red_players.pop(0) pl.sequence = 1 pl.session_random_number = rand_num print("player:{0} set to sequence 1".format(pl.participant.id_in_session)) for index in range(2, 8): # self.session.config['num_demo_participants'] pl.session_random_number = rand_num print("searching for player:{0} color :{1}".format(pl.participant.id_in_session, pl.color)) print("WTP is : {}, random number is : {}".format(pl.WTP, rand_num)) if pl.WTP > rand_num: print("player:{} won".format(pl.participant.id_in_session)) if pl.color == 'RED': if len(red_players) > 0: next_pl = red_players.pop(0) else: next_pl = blue_players.pop(-1) elif pl.color == 'BLUE': if len(blue_players) > 0: next_pl = blue_players.pop(0) else: next_pl = red_players.pop(-1) else: print("player:{} lost".format(pl.participant.id_in_session)) if pl.color == 'RED': if len(blue_players) > 0: next_pl = blue_players.pop(-1) else: next_pl = red_players.pop(0) elif pl.color == 'BLUE': if len(red_players) > 0: next_pl = red_players.pop(-1) else: next_pl = blue_players.pop(0) print("next player:{0} color :{1}".format(next_pl.participant.id_in_session, next_pl.color)) next_pl.sequence = index print("player:{0} set to sequence {1}".format(next_pl.participant.id_in_session, index)) pl = next_pl for pl in blue_players + red_players: pl.sequence = self.session.config['num_demo_participants'] pl.session_random_number = rand_num print("player:{0} set to sequence {1}".format(pl.participant.id_in_session, pl.sequence)) class Group(BaseGroup): sent_2 = models.CurrencyField( min=0, max=Constants.endowment_Decider - 2, doc="""Amount sent by P2""", ) sent_3 = models.CurrencyField( min=0, max=Constants.endowment_Decider - 2, doc="""Amount sent by P3""", ) sent_4 = models.CurrencyField( min=0, max=Constants.endowment_Decider - 2, doc="""Amount sent by P4""", ) sent_5 = models.CurrencyField( min=0, max=Constants.endowment_Decider - 2, doc="""Amount sent by P5""", ) sent_6 = models.CurrencyField( min=0, max=Constants.endowment_Decider - 2, doc="""Amount sent by P6""", ) sent_7 = models.CurrencyField( min=0, max=Constants.endowment_Decider - 2, doc="""Amount sent by P7""", ) sent_8 = models.CurrencyField( min=0, max=Constants.endowment_Decider - 2, doc="""Amount sent by P8""", ) def set_payoffs(self): p1 = self.get_player_by_id(1) p2 = self.get_player_by_id(2) p3 = self.get_player_by_id(3) p4 = self.get_player_by_id(4) p5 = self.get_player_by_id(5) p6 = self.get_player_by_id(6) p7 = self.get_player_by_id(7) p8 = self.get_player_by_id(8) p1.payoff = 2 * (Constants.endowment_Receiver + self.sent_2) p2.payoff = (Constants.endowment_Decider - self.sent_2) * (Constants.endowment_Receiver + self.sent_3) p3.payoff = (Constants.endowment_Decider - self.sent_3) * (Constants.endowment_Receiver + self.sent_4) p4.payoff = (Constants.endowment_Decider - self.sent_4) * (Constants.endowment_Receiver + self.sent_5) p5.payoff = (Constants.endowment_Decider - self.sent_5) * (Constants.endowment_Receiver + self.sent_6) p6.payoff = (Constants.endowment_Decider - self.sent_6) * (Constants.endowment_Receiver + self.sent_7) p7.payoff = (Constants.endowment_Decider - self.sent_7) * (Constants.endowment_Receiver + self.sent_8) p8.payoff = (Constants.endowment_Decider - self.sent_8) * ( self.sent_2 + self.sent_3 + self.sent_4 + self.sent_5 + self.sent_6 + self.sent_7 + self.sent_8) / 7 class Player(BasePlayer): color = models.StringField() WTP = models.CurrencyField(initial=0) overall_payoff = models.CurrencyField(initial=0) session_random_number = models.IntegerField(initial=10) sequence = models.IntegerField(initial=0) department = models.StringField() age = models.StringField(choices=['<24', '25-34', '35-44', '45-54', '>55'], widget=widgets.RadioSelect) gender = models.StringField(choices=['Female', 'Male'], widget=widgets.RadioSelect) average_monthly_income = models.StringField(widget = widgets.RadioSelect) def average_monthly_income_choices(self): choices = [ '500-1000','1000-2000','2000-3000','3000-4000','4000-5000','5000+'] return choices Choice_of_investment_options = models.StringField(widget=widgets.RadioSelect) def Choice_of_investment_options_choices(self): choices = ['8₺ with probability %10 , 6,4₺ with probability %90', '15,4₺ with probability %10 , 0,4₺ with probability %90'] return choices Choice_of_investment_options2 = models.StringField(widget=widgets.RadioSelect) def Choice_of_investment_options2_choices(self): choices = ['8₺ with probability %20 , 6,4₺ with probability %80', '15,4₺ with probability %20 , 0,4₺ with probability %80'] return choices Choice_of_investment_options3 = models.StringField(widget=widgets.RadioSelect) def Choice_of_investment_options3_choices(self): choices = ['8₺ with probability %30 , 6,4₺ with probability %70', '15,4₺ with probability %30 , 0,4₺ with probability %70'] return choices Choice_of_investment_options4 = models.StringField(widget=widgets.RadioSelect) def Choice_of_investment_options4_choices(self): choices = ['8₺ with probability %40 , 6,4₺ with probability %60', '15,4₺ with probability %40 , 0,4₺ with probability %60'] return choices Choice_of_investment_options5 = models.StringField(widget=widgets.RadioSelect) def Choice_of_investment_options5_choices(self): choices = ['8₺ with probability %50 , 6,4₺ with probability %50', '15,4₺ with probability %50 , 0,4₺ with probability %50'] return choices Choice_of_investment_options6 = models.StringField(widget=widgets.RadioSelect) def Choice_of_investment_options6_choices(self): choices = ['8₺ with probability %60 , 6,4₺ with probability %40', '15,4₺ with probability %60 , 0,4₺ with probability %40'] return choices Choice_of_investment_options7 = models.StringField(widget=widgets.RadioSelect) def Choice_of_investment_options7_choices(self): choices = ['8₺ with probability %70 , 6,4₺ with probability %30', '15,4₺ with probability %70 , 0,4₺ with probability %30'] return choices Choice_of_investment_options8 = models.StringField(widget=widgets.RadioSelect) def Choice_of_investment_options8_choices(self): choices = ['8₺ with probability %80 , 6,4₺ with probability %20', '15,4₺ with probability %80 , 0,4₺ with probability %20'] return choices Choice_of_investment_options9 = models.StringField(widget=widgets.RadioSelect) def Choice_of_investment_options9_choices(self): choices = ['8₺ with probability %90 , 6,4₺ with probability %10', '15,4₺ with probability %90 , 0,4₺ with probability %10'] return choices Choice_of_investment_options10 = models.StringField(widget=widgets.RadioSelect) def Choice_of_investment_options10_choices(self): choices = ['8₺ with probability %100 , 6,4₺ with probability %0', '15,4₺ with probability %100 , 0,4₺ with probability %0'] return choices