from otree.api import * class C(BaseConstants): NAME_IN_URL = 'ex_auction_2_3' PLAYERS_PER_GROUP = 2 NUM_ROUNDS = 1 INSTRUCTIONS_TEMPLATE = 'ex_auction_2_3/instructions.html' PAYOFF_TEMPLATE='ex_auction_2_3/payoff_instructions.html' BID_MIN = cu(0) BID_MAX = cu(100) COST=cu(3) TIME=[None,None,None,None,None,None] #OP、イントロ、情報、入札、結果、ED SECOND_TIME=[30,30,30,30,30,30] THIRD_TIME=[30,30,30,30,30,30] class Subsession(BaseSubsession): highest_gain=models.CurrencyField() class Group(BaseGroup): highest_bid = models.CurrencyField() second_highest_bid = models.CurrencyField() tie_true=models.BooleanField( initial=False, doc="""Trueならば同点""" ) class Player(BasePlayer): item_value = models.CurrencyField( doc="""評価値を格納""" ) #bid_amount = models.CurrencyField( # min=C.BID_MIN, # max=C.BID_MAX, # doc="""入札額の入力""", # label="入札額", #) bid_amount = models.IntegerField( min=C.BID_MIN, max=C.BID_MAX, doc="""入札額の入力""", label="入札額", ) is_winner = models.BooleanField( initial=False, doc="""Trueならば落札""" ) is_highest_valuer = models.BooleanField( initial=False, doc="""Trueならば最高評価値をもつ入札者""" ) acquisition=models.BooleanField( initial=True, doc="""情報を取得するかどうか。したらTrue""", #label="商品の評価値を取得しますか?", #choices=[[True,"a"],[False,"b"]], #widget=widgets.RadioSelectHorizontal ) information_cost=models.CurrencyField( doc="""情報を取得したらコストの値、しなかったらゼロ""" ) time_out=models.BooleanField( initial=False, doc="""Trueならばタイムアウト(データから除外する)""" ) total_payoff = models.CurrencyField( doc="""評価値を格納""" ) # FUNCTIONS def creating_session(subsession: Subsession): #subsession.group_randomly() pass def set_winner(group: Group): import random players = group.get_players() bid_list=sorted([p.bid_amount for p in players],reverse=True) group.highest_bid = bid_list[0] group.second_highest_bid = bid_list[1] players_with_highest_bid = [p for p in players if p.bid_amount == group.highest_bid] players_with_second_highest_bid = [p for p in players if p.bid_amount == group.second_highest_bid] winner = random.choice( players_with_highest_bid ) # if tie, winner is chosen at random if len(players_with_highest_bid)>=2: group.tie_true=True #同点の場合 winner.is_winner = True #効率性の導出のため、最も高い評価値を持つ人を識別 group_highest_value=max([p.item_value for p in players]) players_with_highest_value = [p for p in players if p.item_value == group_highest_value] for p in players_with_highest_value: p.is_highest_valuer=True for p in players: set_payoff(p) def generate_value(group: Group): import random value = random.randint(C.BID_MIN, C.BID_MAX) return value def information_cost(player: Player): cost=0 if player.acquisition==True: cost =C.COST return cost def set_payoff(player: Player): group = player.group if player.is_winner: player.payoff = player.item_value - group.second_highest_bid - player.information_cost else: player.payoff = - player.information_cost #ゲームの最後にランキング表示 def payoff_rank(player: Player): subsession = player.subsession players = subsession.get_players() rank_dict={} for p in players: p_id=p.id_in_subsession p.total_payoff=total_payoff_gen(p) rank_dict[p_id]=p.total_payoff rank_dict=dict(rank_dict) payoff_rank_list=sorted([p.total_payoff for p in players],reverse=True) rank_dict=sorted(rank_dict.items(), key=lambda x:x[1], reverse=True) rank_dict=dict(rank_dict) subsession.highest_gain=payoff_rank_list[0] rank_number_list=list(range(1,len(players)+1)) rank_values=list(rank_dict.values()) rank_keys=list(rank_dict.keys()) #参加者の順位の抽出 your_id=player.id_in_subsession your_rank_def=0 your_rank_flag=True while your_rank_flag: your_rank_def+=1 if your_id==rank_keys[your_rank_def-1]: your_rank=your_rank_def your_rank_flag=False #五位まで表示 if len(rank_number_list)>5: rank_number_list=rank_number_list[0:5] rank_values=rank_values[0:5] rank_keys=rank_keys[0:5] return rank_values,rank_keys,rank_number_list,your_rank def total_payoff_gen(player: Player): player_in_all_rounds = player.in_all_rounds() return sum([p.payoff for p in player_in_all_rounds]) # PAGES class IntroductionWaitPage(WaitPage): group_by_arrival_time = True template_name = 'MyWaitPage.html' class Opening(Page): timeout_seconds = C.TIME[0] @staticmethod def is_displayed(player: Player): return player.round_number == 1 class Introduction(Page): @staticmethod def get_timeout_seconds(player): if player.round_number == 1: return C.TIME[1] elif player.round_number == 2: return C.SECOND_TIME[1] else: return C.THIRD_TIME[1] @staticmethod def before_next_page(player: Player, timeout_happened): group = player.group player.item_value = generate_value(group) if timeout_happened: player.time_out = True class Acquisition(Page): @staticmethod def get_timeout_seconds(player): if player.round_number == 1: return C.TIME[2] elif player.round_number == 2: return C.SECOND_TIME[2] else: return C.THIRD_TIME[2] form_model = 'player' form_fields = ['acquisition'] @staticmethod def before_next_page(player: Player, timeout_happened): player.information_cost=information_cost(player) if timeout_happened: player.time_out = True class Bid(Page): @staticmethod def get_timeout_seconds(player): if player.round_number == 1: return C.TIME[3] elif player.round_number == 2: return C.SECOND_TIME[3] else: return C.THIRD_TIME[3] form_model = 'player' form_fields = ['bid_amount'] @staticmethod def before_next_page(player: Player, timeout_happened): if timeout_happened: player.time_out = True class ResultsWaitPage(WaitPage): after_all_players_arrive = set_winner template_name = 'MyWaitPage.html' class Results(Page): @staticmethod def get_timeout_seconds(player): if player.round_number == 1: return C.TIME[4] elif player.round_number == 2: return C.SECOND_TIME[4] else: return C.THIRD_TIME[4] def vars_for_template(player: Player): player_in_all_rounds = player.in_all_rounds() return dict( total_payoff=sum([p.payoff for p in player_in_all_rounds]), player_in_all_rounds=player_in_all_rounds, ) class ResultsSummary(Page): timeout_seconds = C.TIME[5] @staticmethod def is_displayed(player: Player): return player.round_number == C.NUM_ROUNDS @staticmethod def vars_for_template(player: Player): session = player.session subsession = player.subsession player_in_all_rounds = player.in_all_rounds() after_all_players_arrive=payoff_rank(player) return dict( total_payoff=sum([p.payoff for p in player_in_all_rounds]), player_in_all_rounds=player_in_all_rounds, rank_value=payoff_rank(player)[0], rank_key=payoff_rank(player)[1], rank_number=payoff_rank(player)[2], your_rank=payoff_rank(player)[3], ) page_sequence = [IntroductionWaitPage,Introduction,Acquisition, Bid, ResultsWaitPage, Results,]