from typing import List, Any from otree.api import * from random import choice import random class C(BaseConstants): NAME_IN_URL = 'U_seq_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') 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() #事先抽好 30 回合 draw_round1 = models.IntegerField(initial=0) draw_round2 = models.IntegerField(initial=0) draw_round3 = models.IntegerField(initial=0) draw_round4 = models.IntegerField(initial=0) draw_round5 = models.IntegerField(initial=0) draw_round6 = models.IntegerField(initial=0) draw_round7 = models.IntegerField(initial=0) draw_round8 = models.IntegerField(initial=0) draw_round9 = models.IntegerField(initial=0) draw_round10 = models.IntegerField(initial=0) draw_round11 = models.IntegerField(initial=0) draw_round12 = models.IntegerField(initial=0) draw_round13 = models.IntegerField(initial=0) draw_round14 = models.IntegerField(initial=0) draw_round15 = models.IntegerField(initial=0) draw_round16 = models.IntegerField(initial=0) draw_round17 = models.IntegerField(initial=0) draw_round18 = models.IntegerField(initial=0) draw_round19 = models.IntegerField(initial=0) draw_round20 = models.IntegerField(initial=0) draw_round21 = models.IntegerField(initial=0) draw_round22 = models.IntegerField(initial=0) draw_round23 = models.IntegerField(initial=0) draw_round24 = models.IntegerField(initial=0) draw_round25 = models.IntegerField(initial=0) draw_round26 = models.IntegerField(initial=0) draw_round27 = models.IntegerField(initial=0) draw_round28 = models.IntegerField(initial=0) draw_round29 = models.IntegerField(initial=0) draw_round30 = models.IntegerField(initial=0) # FUNCTIONS **(一個function只能做一件事)** #抽三種環境 def random_tables(group:Group): group.random_table = random.randint(1, 3) #抽大、中、小組 def grouping(player: Player): # 要分兩種抽法: # 第一種事先排好分法 24 種 # 第二種隨機抽 6 種 # 作法: # 1. 先 list(range(1, 31)),然後隨機抽 1-30, pool = list(range(1, 31)) # pool_arranged = list(range(1, 25)) # 1-24 代表事先排好 # pool_random = list(range(25, 31)) # 25-30 代表隨機抽 draw = random.sample(pool, 30) print(draw) # 抽出那回合要用甚麼分法 #排好 30 回合要用的分法 # player.draw_round1 = draw[0] # player.draw_round2 = draw[1] # player.draw_round3 = draw[2] # player.draw_round4 = draw[3] # player.draw_round5 = draw[4] # player.draw_round6 = draw[5] # player.draw_round7 = draw[6] # player.draw_round8 = draw[7] # player.draw_round9 = draw[8] # player.draw_round10 = draw[9] # group.draw_round11 = draw[10] # group.draw_round12 = draw[11] # group.draw_round13 = draw[12] # group.draw_round14 = draw[13] # group.draw_round15 = draw[14] # group.draw_round16 = draw[15] # group.draw_round17 = draw[16] # group.draw_round18 = draw[17] # group.draw_round19 = draw[18] # group.draw_round20 = draw[19] # group.draw_round21 = draw[20] # group.draw_round22 = draw[21] # group.draw_round23 = draw[22] # group.draw_round24 = draw[23] # group.draw_round25 = draw[24] # group.draw_round26 = draw[25] # group.draw_round27 = draw[26] # group.draw_round28 = draw[27] # group.draw_round29 = draw[28] # group.draw_round30 = draw[29] # # # 因為要跨 app 所以丟到 participate # participant = player.participant # participant.SV_U_draw_round1 = group.draw_round1 # participant.SV_U_draw_round2 = group.draw_round2 # participant.SV_U_draw_round3 = group.draw_round3 # participant.SV_U_draw_round4 = group.draw_round4 # participant.SV_U_draw_round5 = group.draw_round5 # participant.SV_U_draw_round6 = group.draw_round6 # participant.SV_U_draw_round7 = group.draw_round7 # participant.SV_U_draw_round8 = group.draw_round8 # participant.SV_U_draw_round9 = group.draw_round9 # participant.SV_U_draw_round10 = group.draw_round10 # participant.SV_U_draw_round11 = group.draw_round11 # participant.SV_U_draw_round12 = group.draw_round12 # participant.SV_U_draw_round13 = group.draw_round13 # participant.SV_U_draw_round14 = group.draw_round14 # participant.SV_U_draw_round15 = group.draw_round15 # participant.SV_U_draw_round16 = group.draw_round16 # participant.SV_U_draw_round17 = group.draw_round17 # participant.SV_U_draw_round18 = group.draw_round18 # participant.SV_U_draw_round19 = group.draw_round19 # participant.SV_U_draw_round20 = group.draw_round20 # participant.SV_U_draw_round21 = group.draw_round21 # participant.SV_U_draw_round22 = group.draw_round22 # participant.SV_U_draw_round23 = group.draw_round23 # participant.SV_U_draw_round24 = group.draw_round24 # participant.SV_U_draw_round25 = group.draw_round25 # participant.SV_U_draw_round26 = group.draw_round26 # participant.SV_U_draw_round27 = group.draw_round27 # participant.SV_U_draw_round28 = group.draw_round28 # participant.SV_U_draw_round29 = group.draw_round29 # participant.SV_U_draw_round30 = group.draw_round30 # group.draw_round = draw[i] # if group.draw_round <= 15: # print(group.draw_round) # # if 抽到 1-24 就用事先排好 # if draw <= [24]: # 事先排好的 # # 在從 1-24 隨機抽 # pool_arranged = set(pool_arranged) - set(draw) # print(pool_arranged) # # 接開始分組 5/4/3 # # # if 抽到 25-30 就用隨機抽 # elif draw >= [25]: # 用隨機抽 # pool_random = set(pool_random) - set(draw) # print(pool_random) # 這個 pool_random 要蓋掉 line_98 的 pool_random (讓 Pool_random 遞減) # # 是不是要把 (pool_arranged) 設定成 group 變數 ? # 事先排好 # 隨機抽 #接在 elif draw >= [25]:下面 # 從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人 body_text = "等待所有實驗參與者開始實驗..." 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)