from otree.api import * import random import math import time import json import datetime c = cu doc = """ This is edited based on the project on clock auction and jump bidding written by Xiao Hanyu """ #MODELS class C(BaseConstants): NAME_IN_URL = 'Clock_Auction_ed' PLAYERS_PER_GROUP = 4 NUM_ROUNDS = 10 MU = 50 BID_INCREMENT = 1 MAX_ALLOWABLE_BID = 10 MAX_AUCTION_VALUE = 15 class Subsession(BaseSubsession): start_price = models.FloatField(initial=20) def creating_session(subsession): session = subsession.session subsession.start_price = session.config['starting_price'] for p in subsession.get_players(): if subsession.round_number== 1: p.participant.vars['payment_round'] = random.randint(1, 10) while True: item_value = random.gauss(C.MU, math.sqrt(session.config['variance'])) if 0 <= item_value <= 100: break p.value = int(item_value) class Group(BaseGroup): entry_time = models.FloatField(initial=-1) bids = models.LongStringField() statuses = models.LongStringField() class Player(BasePlayer): value= models.IntegerField() is_active = models.BooleanField(initial=True) #FUNCTIONS def live_Quit(player, data): player.is_active = False response = {'opt-outer': player.id_in_group} return {0: response} def live_updateBidders(player, data): # group = player.group t = data['type'] if t == 'continue': # now = datetime.datetime.now() response = {'action': t, 'actor': player.id_in_group, 'live_price': data['value_before_jump']} # , 'minute': now.minute, 'second': now.second} return { 0: response} elif t == 'start_over': now_time = datetime.datetime.now() response = {'action': t, 'live_price': data['value_before_jump'], 'hour': now_time.hour, 'minute': now_time.minute, 'second': now_time.second} return {0: response} elif t == 'opt_out': # group.remaining_players -= 1 player.is_active = False response = {'action': t, 'live_price': data['value_before_jump'], 'actor': player.id_in_group} # , 'remaining_players': group.remaining_players} return {0: response} elif t == 'jump': response = {'action': t, 'actor': player.id_in_group, 'live_price': data['value_before_jump'], 'jump_amount': data['value']} return {0: response} # PAGES class Introduction(Page): form_model = 'player' live_method = 'live_Quit' @staticmethod def js_vars(player: Player): group = player.group player_A = group.get_player_by_id(1) player_B = group.get_player_by_id(2) player_C = group.get_player_by_id(3) player_D = group.get_player_by_id(4) return dict( player_id=player.id_in_group, P1_payround=(player_A.participant.payment_round == player.round_number), P2_payround=(player_B.participant.payment_round == player.round_number), P3_payround=(player_C.participant.payment_round == player.round_number), P4_payround=(player_D.participant.payment_round == player.round_number), P1_status = player_A.is_active, P2_status=player_B.is_active, P3_status=player_C.is_active, P4_status=player_D.is_active ) class BidWaitPage(WaitPage): @staticmethod def after_all_players_arrive(group: Group): group.entry_time = time.time() class Bid(Page): form_model = 'player' live_method = 'live_updateBidders' @staticmethod def is_displayed(player): players = player.group.get_players() continues = False for p in players: if p.is_active: continues = p.is_active return continues @staticmethod def js_vars(player): group = player.group player_A = group.get_player_by_id(1) player_B = group.get_player_by_id(2) player_C = group.get_player_by_id(3) player_D = group.get_player_by_id(4) '''sp = max(group.start_price, group.highest_bid) if player.refreshed: sp = sp + 2''' # now = datetime.datetime.now() return dict( entry_time = group.entry_time, player_id=player.id_in_group, remaining_players=4, starting_price=player.subsession.start_price, player_value=player.value, P1_payround=(player_A.participant.payment_round == player.round_number), P2_payround=(player_B.participant.payment_round == player.round_number), P3_payround=(player_C.participant.payment_round == player.round_number), P4_payround=(player_D.participant.payment_round == player.round_number), P1_status=player_A.is_active, P2_status=player_B.is_active, P3_status=player_C.is_active, P4_status=player_D.is_active ) class ResultsWaitPage(WaitPage): pass class Results(Page): pass page_sequence = [Introduction, BidWaitPage, Bid, Results] def custom_export(players): # header row yield ['session', 'participant_code', 'round_number', 'id_in_group', 'payoff', 'payment_round'] for p in players: participant = p.participant session = p.session yield [session.code, participant.code, p.round_number, p.id_in_group, p.payoff, participant.payment_round]