from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) import numpy as np import time doc = """ Buyer determined auction. """ class Constants(BaseConstants): name_in_url = 'bd_auction' players_per_group = 3 conversion_rate = 1/150 # $0.006 for every point scored in Dal Bo and Frechette AER 2011 num_rounds=2 instructions_template = 'bd_auction/instructions.html' time_limit = False time_limit_seconds = 3600 # time limit for session (in seconds) since first round of first match (3600 in Dal Bo and Frechette AER 2011) min_allowable_bid = c(0) max_allowable_bid = c(10) class Subsession(BaseSubsession): def creating_session(self): if self.round_number == 1: self.session.vars['start_time'] = time.time() self.session.vars['alive'] = True self.group_randomly(fixed_id_in_group=True) class Group(BaseGroup): winner_label = models.StringField(choices=['A','B'],widget=widgets.RadioSelect,doc="""Voittaja""",label="Voittaja:") winner_id = models.IntegerField() highest_bid = models.CurrencyField() def winner_label_error_message(self, value): print('Valintasi on', value) if value not in ['A','B']: return 'Voit valita vain joko A:n tai B:n. Toinen on valittava.' def set_winner(self): players=self.get_players() self.winner_id=self.winner_to_id() for p in players: if int(p.id_in_group) == self.winner_id: #winner=p p.is_winner = True self.highest_bid= p.bid_amount break #winner.is_winner = True for p in players: p.set_payoff() def winner_to_id(self): if self.winner_label=='A': winner_id=2 else: winner_id=3 return winner_id def get_group_totals(self): saldos=[0,0] times_won=[0,0] for i in [0,1]: p=self.get_player_by_id(i+2) saldos[i]=p.total times_won[i]=p.wins return saldos, times_won class Player(BasePlayer): bid_amount = models.CurrencyField(choices=[0,1,2,3,4,5,6,7,8,9,10],widget=widgets.RadioSelect,label="""Hintapyyntö:""",) valuation = models.CurrencyField(initial=c(0), doc="""Kustannus""" ) total = models.CurrencyField(initial=c(0), doc="""Revenue""" ) wins = models.IntegerField(initial=0,doc="""number of times won""") is_winner = models.BooleanField( initial=False, doc="""Indicates whether the player is the winner""" ) def set_payoff(self): if self.is_winner: self.payoff = self.bid_amount-self.valuation if self.payoff < 0: self.payoff = 0 else: self.payoff = 0 def generate_valuation(self): import random valuation = random.uniform( Constants.min_allowable_bid, Constants.max_allowable_bid ) return valuation def role(self): if self.id_in_group==1: return 'Ostaja' else: return 'Myyjä' #return {1:"Buyer", 2: 'Seller A', 3: 'Seller B'}[self.id_in_group] def swap_role(self): import random test=random.uniform(0,1) if test==1 and self.id_in_group==2: self.id_in_group=1 opponent=self.get_others_in_group()[0] opponent_id_in_group=2 elif test==1 and self.id_in_group==1: self.id_in_group=2 opponent=self.get_others_in_group()[0] opponent_id_in_group=1 def init_player_total(self): if self.id_in_group>1: if self.round_number==1: output=c(0) else: output=self.in_round(self.round_number - 1).total return output else: return 0 def init_player_wins(self): if self.id_in_group>1: if self.round_number==1: output=0 else: output=self.in_round(self.round_number - 1).wins return output else: return 0 def update_player_total(self): if self.id_in_group>1: output=self.total+self.payoff else: output=0 return output def update_player_wins(self): if self.id_in_group>1 and self.is_winner: output=self.wins+1 else: output=0 return output