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_mgsc406' players_per_group = 4 num_rounds = 30 class Subsession(BaseSubsession): pass class Group(BaseGroup): participants = models.IntegerField( initial = 4 ) sum_bids = models.IntegerField( initial=0, ) #prob_list = models.StringField( # initial="" #) #bid_list = models.StringField( # initial="" #) #winner_id = models.IntegerField( # initial=0 #) rnd = models.FloatField( initial=0.0, ) 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, ) prize = models.IntegerField( initial=120, ) prob_winner = models.FloatField( initial=0.0, ) is_winner = models.BooleanField( initial=0, ) 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() group.rnd = random.random() # Count players that paid the fee and gather the bids for p in players: group.sum_bids = round(group.sum_bids + p.bid, 2) # Random number to decide the winner randomly rnd = group.rnd # Key to remember if we already found a winner found_winner = 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_bids > 0: p.prob_winner = round(p.bid / group.sum_bids, 4) # If all the bids are 0 we avoid /0 if group.sum_bids == 0: p.prob_winner = round(1 / group.participants, 4) if found_winner == 0: # If rnd is lower than prob_winner we found a winner if rnd <= p.prob_winner: p.is_winner = 1 found_winner = 1 #group.winner_id = p.id_in_group # Else we remove his prob_winning from the rnd and proceed with the next player else: rnd = rnd - p.prob_winner # Collect the list of probabs and bids to display at the feedback screen 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_winner: # If player is winner we add the prize p.earnings_round = p.earnings_round + p.prize 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 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'] 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 Part2_end(Page): def is_displayed(player: Player): return player.round_number == Constants.num_rounds page_sequence = [Welcome, Contest, ResultsWaitPage, Results, Part2_end, Survey, Endgame]