import random from shared_out import * from otree.api import * """ Sim for "Second Price Auction" game. Small groups of a configurable size are formed to participate in a series of auctions. In each round, each group member will enter a bid for a fictitious item. The person with the highest bid wins and earns their "value" for the item - and they must pay a value equivalent to the second highest bid in the group. Thus, the winner's payoff is equal to their value minus the second highest bid. The payoff for all other players is 0. In each round, the value of the fictitious item for each individual player will be equal to an independently and randomly assigned number ranging from 0 to 100. """ class Constants(BaseConstants): name_in_url = 'secondPrice' players_per_group = None num_rounds = 3 instructions_template = 'secondPrice/instructions.html' class Subsession(BaseSubsession): pass class Group(BaseGroup): highest = models.CurrencyField() second = models.CurrencyField() winner = models.IntegerField() class Player(BasePlayer): value = models.CurrencyField(min=0) bid = models.CurrencyField(min=0, label='Please enter your bid.') isWinner = models.BooleanField(initial=False) # FUNCTIONS def creating_session(subsession: Subsession): set_players_per_group(subsession) def set_winner(group: Group): players = group.get_players() bids = [p.bid for p in players] bids.sort() group.highest = bids[-1] group.second = bids[-2] tied = [p.id_in_group for p in players if p.bid == group.highest] group.winner = random.choice(tied) winner = group.get_player_by_id(group.winner) winner.isWinner = True def set_value(group: Group): players = group.get_players() for p in players: p.value = cu(int(random.uniform(0, 100))) def value_max(player: Player): if player.round_number == 1 or player.round_number == 3: return 99 else: return 31 def set_payoff(player: Player): if player.isWinner: player.payoff = player.value - player.group.second else: player.payoff = cu(0) # PAGES class Introduction(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 class ValueWait(WaitPage): after_all_players_arrive = set_value class Main(Page): form_model = 'player' form_fields = ['bid'] class ResultsWaitPage(WaitPage): @staticmethod def after_all_players_arrive(group: Group): set_winner(group) for p in group.get_players(): set_payoff(p) class Results(Page): @staticmethod def vars_for_template(player: Player): group = player.group winner = group.get_player_by_id(group.winner) return {'winnerPayoff': winner.payoff, 'winnerVal': winner.value} class Final(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 3 @staticmethod def vars_for_template(player: Player): p = [p for p in player.in_all_rounds()] w = [g.get_player_by_id(g.winner).payoff for g in player.group.in_all_rounds()] return {'p': p, 'w': w} page_sequence = [Introduction, ValueWait, Main, ResultsWaitPage, Results, Final]