from typing import List, Any from otree.api import * from random import choice import random class C(BaseConstants): NAME_IN_URL = 'K_sim_ready' PLAYERS_PER_GROUP = 12 NUM_ROUNDS = 1 VOTES = cu(1) # 報酬 exchange_rate = 1 #定義:輪、階段數 # num_subsession = 1 # num_cycle = 2 # num_game_round = 15 #定義乘數 MULTIPLIER1 = 12 MULTIPLIER2 = 9 MULTIPLIER3 = 2 class Subsession(BaseSubsession): pass class Group(BaseGroup): #隨機抽三種情形的一種 random_table = models.IntegerField() #計算票數 num_vote_alpha = models.IntegerField(initial=0) num_vote_beta = models.IntegerField(initial=0) num_vote_gamma = models.IntegerField(initial=0) vote_result = models.IntegerField(min=1, max=3, initial=1) vote_result_str = models.StringField(initial='a') #subgroup# 用來紀錄受試者在該回合分到a, b, c哪一組的人數 # subgroup1 = models.IntegerField() # subgroup2 = models.IntegerField() # subgroup3 = models.IntegerField() # # subgroup_result = models.IntegerField(min=1, max=3, initial=1) # subgroup_result_str = models.StringField(initial='a') class Player(BasePlayer): vote = models.IntegerField( choices=[[1, ' α '], [2, ' β '], [3, ' γ ']], widget=widgets.RadioSelectHorizontal, label="您想要選擇哪一個選項?", initial=0, ) # #定義is_winner判斷誰是贏家 # is_winner = models.BooleanField() #定義random_table變數在class Player #能不能指定義一個變數然後用loop跑就好 random_group = models.IntegerField(min=1, max=3) # 判斷玩家在第幾階段, 1:第一階段, 0:第二階段 is_S1 = models.IntegerField(min=0, max=1, initial=0) #定義並記錄每個受試者的type #還是要所有受試者都定義一遍,然後一個一個檢查 Type_subject1 = models.IntegerField(min=1, max=3, initial=1) Type_subject2 = models.IntegerField(min=1, max=3, initial=1) Type_subject3 = models.IntegerField(min=1, max=3, initial=1) #累積報酬 p_payoff = models.FloatField() # FUNCTIONS **(一個function只能做一件事)** #抽三種環境 def random_tables(group:Group): group.random_table = random.randint(1, 3) #抽大、中、小組 def grouping(group: Group): # 從12人中抽5(大)、再4(中)、再3(小) # 產生id: 1-12 p_id0 = list(range(1, 13)) print(p_id0) # 抽5人 random_big = random.sample(p_id0, 5) print(random_big) p_id1 = list(set(p_id0) - set(random_big)) print(p_id1) # 抽4人 random_med = random.sample(p_id1, 4) print(random_med) # 抽3人 random_smol = list(set(p_id1) - set(random_med)) print(random_smol) #抽第一階段4人 S1_big = random.sample(random_big, 2) S1_med = random.sample(random_med, 2) print(S1_big) print(S1_med) S1 = list(S1_big + S1_med) #第二階段8人 S2 = list(set(p_id0) - set(S1)) print(S1) print(S2) #開始分組5/4/3 players = group.get_players() # 定義players for 下行的迴圈 for p in players: # a=5, b=4, c=3 if p.group.random_table == 1: if p.id_in_group in random_big: #如果id = 抽到的5人 p.random_group = 1 elif p.id_in_group in random_med:#如果id = 抽到的4人 p.random_group = 2 elif p.id_in_group in random_smol:#如果id = 抽到的3人 p.random_group = 3 # a=4, b=3, c=5 elif p.group.random_table == 2: if p.id_in_group in random_big: #如果id = 抽到的五人 p.random_group = 3 elif p.id_in_group in random_med:#如果id = 抽到的4人 p.random_group = 1 elif p.id_in_group in random_smol:#如果id = 抽到的3人 p.random_group = 2 # a=3, b=5, c=4 elif p.group.random_table == 3: if p.id_in_group in random_big: #如果id = 抽到的五人 p.random_group = 2 elif p.id_in_group in random_med:#如果id = 抽到的4人 p.random_group = 3 elif p.id_in_group in random_smol:#如果id = 抽到的3人 p.random_group = 1 for p in players: if p.id_in_group in S1: p.is_S1 = 1 elif p.id_in_group in S2: p.is_S1 = 0 def count_votes(group: Group): # 統計總票數 players = group.get_players() # 定義players for 下行的迴圈 votes = [p.vote for p in players] # 定義votes是player這個class下的vote變數,每個受試者跑迴圈紀錄投下的票 group.num_vote_alpha = votes.count(1) # 計算alpha總票數 group.num_vote_beta = votes.count(2) # 計算beta總票數 group.num_vote_gamma = votes.count(3) # 計算gamma總票數 # 判斷誰贏(計算票數) # alpha贏 if group.num_vote_alpha > group.num_vote_beta and group.num_vote_alpha > group.num_vote_gamma: group.vote_result_str = "本回合選項 α 為最多人選擇的選項" group.vote_result = 1 return 'Candidate α wins' # beta贏 elif group.num_vote_beta > group.num_vote_alpha and group.num_vote_beta > group.num_vote_gamma: group.vote_result_str = "本回合選項 β 為最多人選擇的選項" group.vote_result = 2 return 'Candidate β wins' # gamma贏 elif group.num_vote_gamma > group.num_vote_alpha and group.num_vote_gamma > group.num_vote_beta: group.vote_result_str = "本回合選項 γ 為最多人選擇的選項" group.vote_result = 3 return 'Candidate γ wins' # a, b平手 elif group.num_vote_alpha == group.num_vote_beta and group.num_vote_alpha > group.num_vote_gamma: # 隨機抽1,2 group.vote_result = random.randint(1, 2) # 抽到a贏 if group.vote_result == 1: group.vote_result_str = "選項 α 和 選項 β 平手,由電腦隨機抽出的結果是:選項 α 為最多人選擇的選項" return 'tie Candidate α wins' # 抽到b贏 elif group.vote_result == 2: group.vote_result_str = "選項 α 和 選項 β 平手,由電腦隨機抽出的結果是:選項 β 為最多人選擇的選項" return 'tie Candidate β wins' # a, r平手 elif group.num_vote_alpha == group.num_vote_gamma and group.num_vote_alpha > group.num_vote_beta: # 隨機抽1,3 list = [1, 3] group.vote_result = random.choice(list) # 抽到a贏 if group.vote_result == 1: group.vote_result_str = "選項 α 和 選項 γ 平手,由電腦隨機抽出的結果是:選項 α 為最多人選擇的選項" return 'tie Candidate α wins' # 抽到r贏 elif group.vote_result == 3: group.vote_result_str = "選項 α 和 選項 γ 平手,由電腦隨機抽出的結果是:選項 γ 為最多人選擇的選項" return 'tie Candidate γ wins' # b, r平手 elif group.num_vote_gamma == group.num_vote_beta and group.num_vote_beta > group.num_vote_alpha: # 隨機抽2,3 group.vote_result = random.randint(2, 3) # 抽到b贏 if group.vote_result == 2: group.vote_result_str = "選項 β 和 選項 γ 平手,由電腦隨機抽出的結果是:選項 β 為最多人選擇的選項" return 'tie Candidate β wins' # 抽到r贏 elif group.vote_result == 3: group.vote_result_str = "選項 β 和 選項 γ 平手,由電腦隨機抽出的結果是:選項 γ 為最多人選擇的選項" return 'tie Candidate γ wins' # a, b, r三人平手 elif group.num_vote_alpha == group.num_vote_beta and group.num_vote_alpha == group.num_vote_gamma and group.num_vote_beta == group.num_vote_gamma: # 隨機抽1, 2, 3 group.vote_result = random.randint(1, 3) # 抽到a贏 if group.vote_result == 1: group.vote_result_str = "選項 α 、選項 β 、選項 γ 三者平手,由電腦隨機抽出的結果是:選項 α 為最多人選擇的選項" return 'tie Candidate α wins' # 抽到b贏 elif group.vote_result == 2: group.vote_result_str = "選項 α 、選項 β 、選項 γ 三者平手,由電腦隨機抽出的結果是:選項 β 為最多人選擇的選項" return 'tie Candidate β wins' # 抽到r贏 elif group.vote_result == 3: group.vote_result_str = "選項 α 、選項 β 、選項 γ 三者平手,由電腦隨機抽出的結果是:選項 γ 為最多人選擇的選項" return 'tie Candidate γ wins' def set_payoffs(group: Group): players = group.get_players() # 定義players for 下行的迴圈 #計算每人每回合報酬 for p in players: # alpha贏 if p.group.vote_result == 1: #Voter type a if p.random_group == 1: p.p_payoff = 1*C.MULTIPLIER1 #Voter type b elif p.random_group == 2: p.p_payoff = 1*C.MULTIPLIER2 # Voter type c elif p.random_group == 3: p.p_payoff = 1*C.MULTIPLIER3 #beta贏 elif group.vote_result == 2: #Voter type a if p.random_group == 1: p.p_payoff = 1*C.MULTIPLIER3 #Voter type b elif p.random_group == 2: p.p_payoff = 1*C.MULTIPLIER1 # Voter type c elif p.random_group == 3: p.p_payoff = 1*C.MULTIPLIER2 #gamma贏 elif group.vote_result == 3: #Voter type a if p.random_group == 1: p.p_payoff = 1*C.MULTIPLIER2 #Voter type b elif p.random_group == 2: p.p_payoff = 1*C.MULTIPLIER3 # Voter type c elif p.random_group == 3: p.p_payoff = 1*C.MULTIPLIER1 # PAGES class Ready(Page): pass class Game1S1(Page): form_model = 'player' form_fields = ['vote'] # 定義產生的表格是甚麼形式。ex.'vote'是在class Player那邊定義的 @staticmethod def is_displayed(player): return player.is_S1 == 1 class Game1S2(Page): form_model = 'player' form_fields = ['vote'] #定義產生的表格是甚麼形式。ex.'vote'是在class Player那邊定義的 @staticmethod def is_displayed(player): return player.is_S1 == 0 def vars_for_template(player): group = player.group return dict( alpha = group.num_vote_alpha, # 計算alpha總票數 beta = group.num_vote_beta, # 計算beta總票數 gamma = group.num_vote_gamma, # 計算gamma總票數 ) class ResultsWaitPage_Table(WaitPage): after_all_players_arrive = random_tables #抽表格 class ResultsWaitPage_Group(WaitPage): after_all_players_arrive = grouping #分組5/4/3 + S14人 class ResultsWaitPage_Vote(WaitPage): #統計票數 after_all_players_arrive = count_votes class ResultsWaitPage_Payoff(WaitPage): #算報酬 after_all_players_arrive = set_payoffs class Result1(Page): def vars_for_template(player): group = player.group return dict( alpha = group.num_vote_alpha, # 計算alpha總票數 beta = group.num_vote_beta, # 計算beta總票數 gamma = group.num_vote_gamma, # 計算gamma總票數 ) page_sequence = [ Ready, ] #(放payoff_info_result)