from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range, Page, WaitPage, ) import random doc = """ This is a first and second price sealed-bid auction game. Author: Anugna Reddy Gondi Date: 11/23/2021 """ class Constants(BaseConstants): name_in_url = 'auction_game' players_per_group = None # number of simulated bidders nbr_sim_bidders = 9 val_max = 100 val_min = 0 num_rounds_FPSB = 15 num_rounds_SPSB = 15 num_rounds = num_rounds_FPSB + num_rounds_SPSB class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): value = models.IntegerField() comp_values = models.StringField() bid = models.IntegerField() is_round_winner = models.BooleanField() # FUNCTIONS def creating_session(subsession): import itertools types = itertools.cycle(['FPSB', 'SPSB']) if subsession.round_number == 1: for player in subsession.get_players(): participant = player.participant participant.first_auction = next(types) def auction_results(player): # Get the computerized bids from their values list comp_values_list = [int(s) for s in player.comp_values.split(" ")] n = Constants.nbr_sim_bidders + 1 comp_bids = [x * ((n - 1) / n) for x in comp_values_list] # temp_comp_bids = set(comp_values_list) # temp_comp_bids.remove(max(comp_values_list)) if (((player.participant.first_auction == 'FPSB') & (player.round_number < Constants.num_rounds_FPSB + 1)) | ( (player.participant.first_auction == 'SPSB') & (player.round_number > Constants.num_rounds_SPSB))): if player.bid > max(comp_bids): player.payoff = player.value - player.bid player.is_round_winner = 1 else: player.payoff = 0 player.is_round_winner = 0 else: if player.bid > max(comp_values_list): player.payoff = player.value - max(comp_values_list) player.is_round_winner = 1 else: player.payoff = 0 player.is_round_winner = 0 # PAGES class Introduction(Page): @staticmethod def is_displayed(player): return player.round_number == 1 class InstructionsFPSB(Page): @staticmethod def is_displayed(player): participant = player.participant return ((participant.first_auction == 'FPSB') & (player.round_number == 1)) | ( (participant.first_auction == 'SPSB') & (player.round_number == Constants.num_rounds_SPSB + 1)) class InstructionsSPSB(Page): @staticmethod def is_displayed(player): return ((player.participant.first_auction == 'SPSB') & (player.round_number == 1)) | ( (player.participant.first_auction == 'FPSB') & (player.round_number == Constants.num_rounds_FPSB + 1)) class RoundData(Page): form_model = 'player' # to get the form field you want from the player model form_fields = ['value', 'comp_values', 'bid', 'is_round_winner'] @staticmethod def before_next_page(player, timeout_happened): auction_results(player) @staticmethod def vars_for_template(player): private_value = random.randrange(Constants.val_min, Constants.val_max) comp_value_list = random.choices(range(Constants.val_min, Constants.val_max + 1), k=9) return {'private_value': private_value, 'comp_value_list': comp_value_list, 'num_rounds_FPSB': Constants.num_rounds_FPSB, 'num_rounds_SPSB': Constants.num_rounds_SPSB} class ResultsWaitPage(WaitPage): pass class Results(Page): @staticmethod def vars_for_template(player): comp_values_list = [int(s) for s in player.comp_values.split(" ")] n = Constants.nbr_sim_bidders + 1 comp_bids = [x * ((n - 1) / n) for x in comp_values_list] temp_comp_bids = set(comp_values_list + [player.bid]) temp_comp_bids.remove(max(temp_comp_bids)) return {'highest_bid': max(player.bid, max(comp_bids)) , 'is_FPSB': 1} if ( ((player.participant.first_auction == 'FPSB') & ( player.round_number < Constants.num_rounds_FPSB + 1)) | ( (player.participant.first_auction == 'SPSB') & ( player.round_number > Constants.num_rounds_SPSB))) else { 'highest_bid': max(player.bid, max(comp_values_list)), 'second_highest_bid': max(temp_comp_bids), 'first_auction': player.participant.first_auction, 'is_FPSB': ((player.participant.first_auction == 'FPSB') & ( player.round_number < Constants.num_rounds_FPSB + 1)) | ( (player.participant.first_auction == 'SPSB') & ( player.round_number > Constants.num_rounds_SPSB))} page_sequence = [Introduction, InstructionsFPSB, InstructionsSPSB, RoundData, Results]