from otree.api import * import random, time doc = """ This is a standard 2-player trust game where the amount sent by player 1 gets tripled. The trust game was first proposed by Berg, Dickhaut, and McCabe (1995) . """ class C(BaseConstants): NAME_IN_URL = 'CG' PLAYERS_PER_GROUP = 2 NUM_ROUNDS = 1 NUM_NODES = 6 INSTRUCTIONS_TEMPLATE = 'trust/instructions.html' GRAPH_TEMPLATE = 'graph_testing/graph.html' large_pile = 12 small_pile = 3 base = 2 large_piles = [] small_piles = [] for node in range(NUM_NODES + 1): large_piles.append(large_pile * base ** node) # formula for payoff evolution small_piles.append(small_pile * base ** node) # Merge the two Piles alternating elements payoff_red = large_piles.copy() for i in range(len(large_piles)): if i % 2 != 0: payoff_red[i] = small_piles[i] # Merge the two Piles alternating elements payoff_blue = small_piles.copy() for i in range(len(payoff_blue)): if i % 2 != 0: payoff_blue[i] = large_piles[i] # constant-sum payoff (Results.html should also be changed) # payoff_red = [48,36,69,20,81,11,88] # payoff_blue = [48,60,27,76,15,85,8] class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): #role_color_color = models.StringField() payoffs = models.IntegerField(initial=0) total_payoff = models.IntegerField(initial=50) node = models.IntegerField(initial=0) take = models.BooleanField(initial = False) decide_too_long = models.BooleanField(initial = False) wait_too_long = models.BooleanField(initial = False) time_stamp_0 = models.FloatField() time_stamp_1 = models.FloatField() time_stamp_2 = models.FloatField() time_stamp_3 = models.FloatField() # FUNCTIONS #def sent_back_amount_max(group: Group): # return group.sent_amount * C.MULTIPLIER def set_payoffs(group: Group): p1 = group.get_player_by_id(1) p2 = group.get_player_by_id(2) if p1.take == 0 and p2.take == 0: p1.payoffs = C.payoff_red[-1] p2.payoffs = C.payoff_blue[-1] else: if p2.take == 1 and p1.node == 0 and p2.node == 0: # blue player 在introduction斷線 p1.payoffs = 12 p2.payoffs = 0 elif p1.take == 1: p1.payoffs = C.payoff_red[2 * p2.node] p2.payoffs = C.payoff_blue[2 * p2.node] else: p1.payoffs = C.payoff_red[2 * p2.node - 1] p2.payoffs = C.payoff_blue[2 * p2.node - 1] if p1.decide_too_long == True: p1.total_payoff = 0 else: p1.total_payoff = p1.payoffs + 50 if p2.decide_too_long == True: p2.total_payoff = 0 else: p2.total_payoff = p2.payoffs + 50 # if condition == 'wo social': # exchange_rate = random.randint(0, 1) # p1 = group.get_player_by_id(1) # p2 = group.get_player_by_id(2) # if p1.take == 1: # p1.payoff = C.payoff_red[2 * p2.node] * exchange_rate # p2.payoff = C.payoff_blue[2 * p2.node] * (1-exchange_rate) # else: # p1.payoff = C.payoff_red[2 * p2.node - 1] * exchange_rate # p2.payoff = C.payoff_blue[2 * p2.node - 1] * (1-exchange_rate) # else: # p1 = group.get_player_by_id(1) # p2 = group.get_player_by_id(2) # if p1.take == 1: # p1.payoff = C.payoff_red[2 * p2.node] # p2.payoff = C.payoff_blue[2 * p2.node] # else: # p1.payoff = C.payoff_red[2 * p2.node - 1] # p2.payoff = C.payoff_blue[2 * p2.node - 1] # PAGES def graph_parameters(node): return dict( cont_rect_x = 45 + (node - 1) * 100, cont_text_x = 59 + (node - 1) * 100, stop_rect_x = 1 + (node - 1) * 100, stop_text_x = 15 + (node - 1) * 100, color_hover = 'LightPink' if node % 2 == 1 else 'LightSkyBlue', color_active = 'PaleVioletRed' if node % 2 == 1 else 'RoyalBlue', ) # note: this function goes at the module level, not inside the WaitPage. # def group_by_arrival_time_method(subsession, waiting_players): # wait_players = [p for p in waiting_players] # # red_players = [p for p in waiting_players if p.participant.id_in_group == 1] # # blue_players = [p for p in waiting_players if p.participant.id_in_group == 2] # if len(wait_players) >= 2: # # print('about to create a group') # return [wait_players[0], wait_players[1]] class wait_page_group(WaitPage): group_by_arrival_time = True title_text = "敬請稍待" body_text = "系統正在為你配對" class Introduction(Page): #title_text = "系統已經幫你完成配對" #body_text = "請按下一頁,開始正式實驗,請謹慎做出你的決定" timeout_seconds = 60*10 #@staticmethod #def is_displayed(player:Player): # return player.id_in_group == 1 timer_text = '剩餘時間:' @staticmethod def before_next_page(player, timeout_happened): #player.node += 1 player.time_stamp_0 = time.time() if timeout_happened: player.take = True player.decide_too_long = True player.get_others_in_group()[0].wait_too_long = True class WaitPage_initial(WaitPage): title_text = "敬請稍待" body_text = "正在等待你的對手確認開始正式實驗,如果你的對手在10分鐘內未確認,系統將視同棄權,你仍舊能獲得相對應的報酬。" def is_displayed(player:Player): return player.decide_too_long == False #player.id_in_group == 1 and class Red_one(Page): form_model = 'player' form_fields = ['take'] timeout_seconds = 60*10 # refer https://otree.readthedocs.io/en/latest/timeouts.html for more timer details timer_text = '剩餘時間:' @staticmethod def before_next_page(player, timeout_happened): player.node += 1 player.time_stamp_1 = time.time() if timeout_happened: player.take = True player.decide_too_long = True player.get_others_in_group()[0].wait_too_long = True @staticmethod def is_displayed(player:Player): return player.id_in_group == 1 and player.take == False and player.get_others_in_group()[0].take == False @staticmethod def vars_for_template(player): return graph_parameters(node=1) # class WaitPage1_red(WaitPage): # title_text = "敬請稍待" # body_text = "你的對手正在做決定,如果你的對手在10分鐘內未做出決定,系統將視同棄權,你仍舊能獲得相對應的報酬。" # def is_displayed(player:Player): # return player.id_in_group == 1 and player.take == False and player.get_others_in_group()[0].take == False class WaitPage1_blue(WaitPage): title_text = "敬請稍待" body_text = "你的對手正在做決定,如果你的對手在10分鐘內未做出決定,系統將視同棄權,你仍舊能獲得相對應的報酬。" def is_displayed(player:Player): return player.take == False and player.get_others_in_group()[0].take == False class Blue_one(Page): #body_text = "輪到你做決定了,請謹慎做出你的選擇" form_model = 'player' form_fields = ['take'] timeout_seconds = 60*10 # refer https://otree.readthedocs.io/en/latest/timeouts.html for more timer details timer_text = '剩餘時間:' @staticmethod def before_next_page(player, timeout_happened): player.node += 1 player.time_stamp_1 = time.time() if timeout_happened: player.take = True player.decide_too_long = True @staticmethod def is_displayed(player:Player): return player.id_in_group == 2 and player.take == False and player.get_others_in_group()[0].take == False @staticmethod def vars_for_template(player): return graph_parameters(node=2) class WaitPage1_red(WaitPage): title_text = "敬請稍待" body_text = "你的對手正在做決定,如果你的對手在10分鐘內未做出決定,系統將視同棄權,你仍舊能獲得相對應的報酬。" def is_displayed(player:Player): return player.take == False and player.get_others_in_group()[0].take == False class Red_two(Page): form_model = 'player' form_fields = ['take'] timeout_seconds = 60*10 # refer https://otree.readthedocs.io/en/latest/timeouts.html for more timer details timer_text = '剩餘時間:' @staticmethod def before_next_page(player, timeout_happened): player.node += 1 player.time_stamp_2 = time.time() if timeout_happened: player.take = True player.decide_too_long = True @staticmethod def is_displayed(player:Player): return player.id_in_group == 1 and player.take == False and player.get_others_in_group()[0].take == False @staticmethod def vars_for_template(player): return graph_parameters(node=3) class WaitPage2_blue(WaitPage): title_text = "敬請稍待" body_text = "你的對手正在做決定,如果你的對手在10分鐘內未做出決定,系統將視同棄權,你仍舊能獲得相對應的報酬。" def is_displayed(player:Player): return player.take == False and player.get_others_in_group()[0].take == False class Blue_two(Page): form_model = 'player' form_fields = ['take'] timeout_seconds = 60*10 # refer https://otree.readthedocs.io/en/latest/timeouts.html for more timer details timer_text = '剩餘時間:' @staticmethod def before_next_page(player, timeout_happened): player.node += 1 player.time_stamp_2 = time.time() if timeout_happened: player.take = True player.decide_too_long = True @staticmethod def is_displayed(player:Player): return player.id_in_group == 2 and player.take == False and player.get_others_in_group()[0].take == False @staticmethod def vars_for_template(player): return graph_parameters(node=4) class WaitPage2_red(WaitPage): title_text = "敬請稍待" body_text = "你的對手正在做決定,如果你的對手在10分鐘內未做出決定,系統將視同棄權,你仍舊能獲得相對應的報酬。" def is_displayed(player:Player): return player.take == False and player.get_others_in_group()[0].take == False class Red_three(Page): form_model = 'player' form_fields = ['take'] timeout_seconds = 60*10 # refer https://otree.readthedocs.io/en/latest/timeouts.html for more timer details timer_text = '剩餘時間:' @staticmethod def before_next_page(player, timeout_happened): player.node += 1 player.time_stamp_3 = time.time() if timeout_happened: player.take = True player.decide_too_long = True @staticmethod def is_displayed(player:Player): return player.id_in_group == 1 and player.take == False and player.get_others_in_group()[0].take == False @staticmethod def vars_for_template(player): return graph_parameters(node=5) class WaitPage3_blue(WaitPage): title_text = "敬請稍待" body_text = "你的對手正在做決定,如果你的對手在10分鐘內未做出決定,系統將視同棄權,你仍舊能獲得相對應的報酬。" def is_displayed(player:Player): return player.take == False and player.get_others_in_group()[0].take == False class Blue_three(Page): form_model = 'player' form_fields = ['take'] timeout_seconds = 60*10 # refer https://otree.readthedocs.io/en/latest/timeouts.html for more timer details timer_text = '剩餘時間:' @staticmethod def before_next_page(player, timeout_happened): player.node += 1 player.time_stamp_3 = time.time() if timeout_happened: player.take = True player.decide_too_long = True @staticmethod def is_displayed(player:Player): return player.id_in_group == 2 and player.take == False and player.get_others_in_group()[0].take == False @staticmethod def vars_for_template(player): return graph_parameters(node=6) class WaitPage3_red(WaitPage): title_text = "敬請稍待" body_text = "你的對手正在做決定,如果你的對手在10分鐘內未做出決定,系統將視同棄權,你仍舊能獲得相對應的報酬。" after_all_players_arrive = set_payoffs class Results(Page): """This page displays the earnings of each player""" pass #@staticmethod #def vars_for_template(player: Player): # group = player.group # # return dict(tripled_amount=group.sent_amount * C.MULTIPLIER) page_sequence = [ wait_page_group, Introduction, WaitPage_initial, Red_one, WaitPage1_blue, Blue_one, WaitPage1_red, Red_two, WaitPage2_blue, Blue_two, WaitPage2_red, Red_three, WaitPage3_blue, Blue_three, WaitPage3_red, Results, ] # The below are all done. # WaitPage1_red is not used; rename WaitPage2 as WaitPage1_red; rename WaitPage3 as WaitPage2_blue; rename WaitPage4 as WaitPage2_red; rename WaitPage5 as WaitPage3_blue; rename ResultsWaitPage as WaitPage3_red_result; # In waitpage, player.id_in_group == x should all be deleted.