from otree.api import *
c = cu
doc = 'In this game (otherwise known as the Dutch Auction), players simultaneously bid on the item being\nauctioned.
\nPrior to bidding, they are given an estimate of the actual value of the item.\nThis actual value is revealed after the bidding.
\nYou are facing a clock displaying the price at which you can buy the item. The price continues to\nincrease until one bidder is left.
\nThe bidder who is left, gets the item and pays the price at which the clock stopped. The other bidders pay nothing and earn nothing.
'
class Constants(BaseConstants):
name_in_url = 'Descending_Price_Auction'
players_per_group = 3
num_rounds = 3
estimate_error_margin = cu(1)
style_background_color = '#F0F0F0'
style_text_color = '#1F297E'
min_item_value = 0
max_item_value = 10
bid_decrement = 0.1
timer_mode = 3
animation_color = '#BAA382'
display_opponents_results = True
def creating_session(subsession):
session = subsession.session
import random
subsession.group_randomly()
for p in subsession.get_players():
item_value = random.uniform(
Constants.min_item_value, Constants.max_item_value
)
p.item_value_actual = round(item_value, 2)
p.number_of_opponents = Constants.players_per_group - 1
class Subsession(BaseSubsession):
pass
def set_winner(group):
players = group.get_players()
group.highest_bid = max([p.bid_amount for p in players])
players_with_highest_bid = [
p for p in players if p.bid_amount == group.highest_bid
]
# Same bid from two players
if (len(players_with_highest_bid) > 1):
# if tied, payout divided between winners
for p in players_with_highest_bid:
p.is_tied = True;
p.number_of_players_tied = len(players_with_highest_bid)
# No tie, only one winner
else:
players_with_highest_bid[0].is_winner = True
for p in players:
set_payoff(p)
for p in players:
p.total_earnings= sum([round.payoff for round in p.in_all_rounds()])
class Group(BaseGroup):
highest_bid = models.CurrencyField()
total_earnings = models.CurrencyField()
num_messages = models.IntegerField()
game_finished = models.BooleanField(initial=False)
def set_payoff(player):
# Submits highest bid
# if player.is_winner and not player.is_timeout_winner:
if player.is_winner:
player.payoff = player.item_value_actual - player.bid_amount
# Players submit tied bids
elif player.is_tied:
player.payoff = (player.item_value_actual - player.bid_amount)/ player.number_of_players_tied
else:
player.payoff = 0
def live_endBid(player, data):
group = player.group
# Send a response only to the other players =
other_players = player.get_others_in_group()
response = {}
for p in other_players:
id = p.id_in_group
response[id] = True
return response
def otherPlayersValues(player):
group = player.group
playerList = player.get_others_in_group()
valueList = []
for player in playerList:
valueList.append(player.item_value_actual)
return valueList
def other_player(player):
group = player.group
return player.get_others_in_group()[0]
class Player(BasePlayer):
item_value = models.CurrencyField()
bid_amount = models.CurrencyField(label='Bid amount')
is_winner = models.BooleanField(initial=False)
is_tied = models.BooleanField(initial=False)
number_of_players_tied = models.IntegerField()
item_value_actual = models.CurrencyField()
total_earnings = models.CurrencyField()
number_of_opponents = models.IntegerField()
is_timeout_winner = models.BooleanField(initial=False)
class Introduction(Page):
form_model = 'player'
class BidWaitPage(WaitPage):
pass
class Bid(Page):
form_model = 'player'
form_fields = ['bid_amount']
live_method = 'live_endBid'
@staticmethod
def js_vars(player):
group = player.group
return dict(
player_id = player.id_in_group,
others_values = otherPlayersValues(player),
display_opponents_results = Constants.display_opponents_results
)
@staticmethod
def before_next_page(player, timeout_happened):
if timeout_happened:
player.bid_amount = 0
@staticmethod
def get_timeout_seconds(player):
bid_seconds = (Constants.max_item_value / Constants.bid_decrement) + 4
return bid_seconds
class ResultsWaitPage(WaitPage):
after_all_players_arrive = 'set_winner'
class Results(Page):
form_model = 'player'
page_sequence = [Introduction, BidWaitPage, Bid, ResultsWaitPage, Results]