from otree.api import * import random doc = """ A tullock contest practice for MGSC 406, use the game by Sheremeta (2011) """ class Constants(BaseConstants): name_in_url = 'tullock_contest_twoprizes__mgsc406' players_per_group = 4 num_rounds = 30 class Subsession(BaseSubsession): pass class Group(BaseGroup): participants = models.IntegerField( initial = 4 ) sum_bids1 = models.IntegerField( initial=0, ) # first sum of bids sum_bids2 = models.IntegerField( initial=0, ) # second sum of bids #prob_list = models.StringField( # initial="" #) #bid_list = models.StringField( # initial="" #) #winner_id = models.IntegerField( # initial=0 #) rnd1 = models.FloatField( initial=0.0, ) # first random generator rnd2 = models.FloatField( initial=0.0, ) # second random generator class Player(BasePlayer): bid = models.IntegerField( min=0, max=60, label="Please enter how much do you want to bid:", ) endowment = models.IntegerField( initial=60, ) prize1 = models.IntegerField( initial=90, ) prize2 = models.IntegerField( initial=30, ) prob_winner1 = models.FloatField( initial=0.0, ) # the prob of winning for first prize prob_winner2 = models.FloatField( initial=0.0, ) # the prob of winning for second prize is_winner1 = models.BooleanField( initial=0, ) #find the first winner is_winner2 = models.BooleanField( initial=0, ) #find the second winner earnings_final = models.FloatField( initial=0, ) earnings_round = models.FloatField( initial=0, ) # survey define age = models.IntegerField( label='What is your age?', min=18, max=100) gender = models.StringField( choices=['Male', 'Female', 'Other'], label='What is your gender?', widget=widgets.RadioSelect) citizenship = models.StringField( label='What is your country(s) of citizenship?') major = models.StringField( label='What is your major?') year = models.StringField( choices=['Freshman', 'Sophomore', 'Junior', 'Senior', 'Graduate', 'Other'], label='Which year are you in?', widget=widgets.RadioSelect) risk = models.StringField( choices=['Strongly Disagree', 'Disagree', 'Slightly Disagree', 'Slightly Agree', 'Agree', 'Strongly Agree'], label='You are a person who is fully prepared to take risks.', widget=widgets.RadioSelect) # FUNCTIONS def creating_session(subsession: Subsession): # print('in creating_session') session = subsession.session subsession.group_randomly() #no need to randomly rematched in each group if subsession.round_number == 1: # randomly select 5 out of 30 rounds for payment paying_round1 = random.randint(1, 5) # change those values to [2,21] later paying_round2 = random.randint(6, 10) paying_round3 = random.randint(11, 15) paying_round4 = random.randint(16, 20) paying_round5 = random.randint(21, 30) # change those values to [22,41] later session.vars['paying_round1'] = paying_round1 session.vars['paying_round2'] = paying_round2 session.vars['paying_round3'] = paying_round3 session.vars['paying_round4'] = paying_round4 session.vars['paying_round5'] = paying_round5 #session.vars['endowment'] = subsession.endowment for p in subsession.get_players(): p.round_chosen1 = session.vars['paying_round1'] p.round_chosen2 = session.vars['paying_round2'] p.round_chosen3 = session.vars['paying_round3'] p.round_chosen4 = session.vars['paying_round4'] p.round_chosen5 = session.vars['paying_round5'] #stimuli = read_csv() #for stim in stimuli: # Trial.create(player=p, **stim) def find_winner(group: Group): players = group.get_players() #find the 1st prize winner group.rnd1 = random.random() # Count players that paid the fee and gather the bids for p in players: group.sum_bids1 = round(group.sum_bids1 + p.bid, 2) # Random number to decide the winner randomly rnd1 = group.rnd1 # Key to remember if we already found a winner found_winner1 = 0 # Iterate the players and look for the winner for p in players: # If the sum of bids are greater than 0 if group.sum_bids1 > 0: p.prob_winner1 = round(p.bid / group.sum_bids1, 4) # If all the bids are 0 we avoid /0 if group.sum_bids1 == 0: p.prob_winner1 = round(1 / group.participants, 4) if found_winner1 == 0: # If rnd is lower than prob_winner we found a winner if rnd1 <= p.prob_winner1: p.is_winner1 = 1 found_winner1 = 1 #group.winner_id = p.id_in_group # Else we remove his prob_winning from the rnd and proceed with the next player else: rnd1 = rnd1 - p.prob_winner1 # find the second prize winner group.rnd2 = random.random() rnd2 = group.rnd2 found_winner2 = 0 for p in players: if p.is_winner1 != 1: group.sum_bids2 = round(group.sum_bids2 + p.bid, 2) # If the sum of bids are greater than 0 if group.sum_bids2 > 0: p.prob_winner2 = round(p.bid / group.sum_bids2, 4) # If all the bids are 0 we avoid /0 if group.sum_bids2 == 0: p.prob_winner2 = round(1 / (group.participants-1), 4) if found_winner2 == 0: # If rnd is lower than prob_winner we found a winner if rnd2 <= p.prob_winner2: p.is_winner2 = 1 found_winner2 = 1 # Else we remove his prob_winning from the rnd and proceed with the next player else: rnd2 = rnd2 - p.prob_winner2 elif p.is_winner1 == 1: p.is_winner2 = 0 def get_earnings(group: Group): players = group.get_players() for p in players: # By default endowment + round fee p.earnings_round = p.endowment - p.bid if p.is_winner1: # If player is winner we add the prize p.earnings_round = p.earnings_round + p.prize1 elif p.is_winner2: p.earnings_round = p.earnings_round + p.prize2 p.earnings_round = round(p.earnings_round, 2) # Store the earnings of this round at the total #if p.round_number == p.round_to_pay: # p.earnings_final = p.earnings_round # p.earnings_money = round(p.earnings_final * p.session.config['real_world_currency_per_point'], 1) # p.money_to_pay = cu(p.earnings_money) + p.session.config['participation_fee'] # p.participant.money_to_pay = p.money_to_pay # p.payoff = cu(p.earnings_money) #else: # if p.round_number > 1: # last_p = p.in_round(p.round_number - 1) # p.earnings_final = last_p.earnings_final # p.earnings_money = last_p.earnings_money # p.money_to_pay = last_p.money_to_pay def close_round(group: Group): find_winner(group) get_earnings(group) # PAGES class Welcome (Page): def is_displayed(self): return self.round_number == 1 after_all_players_arrive = creating_session class Contest(Page): form_model = 'player' form_fields = ['bid'] @staticmethod def vars_for_template(player: Player): endowment = player.endowment return dict( endowment=endowment, round_shown=player.round_number, total_shown=Constants.num_rounds ) class ResultsWaitPage(WaitPage): after_all_players_arrive = close_round class Results(Page): @staticmethod def vars_for_template(player: Player): return dict( round_shown=player.round_number, total_shown=Constants.num_rounds ) class Endgame(Page): @staticmethod def is_displayed(player: Player): return player.round_number == Constants.num_rounds @staticmethod def vars_for_template(player: Player): session = player.session player_in_round1 = player.in_round(session.vars['paying_round1']) player_in_round2 = player.in_round(session.vars['paying_round2']) player_in_round3 = player.in_round(session.vars['paying_round3']) player_in_round4 = player.in_round(session.vars['paying_round4']) player_in_round5 = player.in_round(session.vars['paying_round5']) return dict( round1_payoff=player_in_round1.earnings_round, round2_payoff=player_in_round2.earnings_round, round3_payoff=player_in_round3.earnings_round, round4_payoff=player_in_round4.earnings_round, round5_payoff=player_in_round5.earnings_round, part1_payoff= player_in_round1.earnings_round + player_in_round2.earnings_round + player_in_round3.earnings_round + player_in_round4.earnings_round + player_in_round5.earnings_round, part1_payoff_currency=(player_in_round1.earnings_round + player_in_round2.earnings_round + player_in_round3.earnings_round + player_in_round4.earnings_round + player_in_round5.earnings_round)/50, paying_round1=session.vars['paying_round1'], paying_round2=session.vars['paying_round2'], paying_round3=session.vars['paying_round3'], paying_round4=session.vars['paying_round4'], paying_round5=session.vars['paying_round5'], ) class Survey (Page): @staticmethod def is_displayed(player: Player): return player.round_number == Constants.num_rounds form_model = 'player' form_fields = [ 'age', 'gender', 'citizenship', 'major', 'year', 'risk'] page_sequence = [Welcome, Contest, ResultsWaitPage, Results, Endgame]