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_allowable_bid = 0
max_allowable_bid = 10
bid_decrement = 0.1
timer_mode = 3
animation_color = '#BAA382'
display_opponents_results = True
def creating_session(subsession):
session = subsession.session
subsession.group_randomly()
for p in subsession.get_players():
import random
item_value = random.uniform(
Constants.min_allowable_bid, Constants.max_allowable_bid
)
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):
# import random
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
]
# set winner to be random if nobody clicks bid
# if timeout_happened = True,
# players_with_highest_bid.random().is_winner = True
# No player bids, winner set randomly
# if (group.highest_bid == 0):
# random_winner = random.randint(0,2)
# players[random_winner].is_winner = True
# players[random_winner].is_timeout_winner = True
# 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()])
def bid_waiting(group):
pass
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
# No bids and player is randomly chosen as winner
# elif player.is_winner and player.is_timeout_winner:
# player.payoff = player.item_value_actual
# 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
#This method sends a response to all players, and JS code changes bid value for other players
# my_id = player.id_in_group
# response = dict(bidder_id=my_id)
# return {0: response}
# 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 get_countdown_timer(player):
pass
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_allowable_bid / 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]