# from ast import Try # from asyncio import constants # from logging import PlaceHolder # from pickle import TRUE # from tkinter.tix import Tree # from turtle import circle from otree.api import * # from sqlalchemy import false, true c = Currency doc = """ Your app description """ class Constants(BaseConstants): name_in_url = 'TTCC_b' instructions_template = 'TTCC_b/instructions.html' players_per_group = 7 num_rounds = 2 w = 0 # 文字列 Num を作成 for i in range(1,Constants.players_per_group+1): if i==1: Num="1" else : Num= Num+","+str(i) class Subsession(BaseSubsession): pass class Group(BaseGroup): kideny = models.LongStringField(initial=Num) # 残っている腎臓(選択肢) patient = models.LongStringField(initial=Num) # 残っている患者 applyed = models.LongStringField(initial="") # 提出済みの腎臓 paths = models.LongStringField(initial="") # 組合せ start_algo_frag=models.BooleanField(initial=False) # 集計 end_frag=models.BooleanField(initial=False) # ラウンド終了フラグ #auction_timeout = models.FloatField() pass class Player(BasePlayer): seaquence = models.LongStringField(initial="") # 意思決定の情報 applyed_frag=models.BooleanField(initial=False) # 提出情報 current_value = models.LongStringField(initial="") # 希望番号 out_frag = models.BooleanField(initial=False) # 退出フラグ result = models.LongStringField(initial="") # 結果 pass # functions def make_list(player: Player,listname): group = player.group tmp = eval("group."+listname) tmp = tmp.split(",") tmp = [ int(i) for i in tmp if i!="" ] return tmp def update_db(player: Player,listname,new): group = player.group tmp = eval("group."+listname) tmp = tmp+","+new # 初めの一回目に空白が含まれる tmp = tmp.split(",") tmp = [ i for i in tmp if i!="" ] # 空白の削除 return ",".join(tmp) # 全腎臓の提出後処理(リスト化) def get_direction(group: Group): tmp=group.paths.split("|") tmp=[i for i in tmp if i!="" ] direction=[i.split(",") for i in tmp ] return direction def get_state(player: Player): group = player.group return dict( players_per_group=Constants.players_per_group, # 個人の情報 my_id=player.id_in_group, applyed_frag=player.applyed_frag, current_value=player.current_value, result=player.result, status=player.out_frag, # グループの情報 kideny = group.kideny.split(","), patient = group.patient.split(","), start_algo_frag=group.start_algo_frag, end_frag=group.end_frag ) # Chain B アルゴリズム def Algo(group:Group,Kindeny_Remaining,Patient_Remaining): group.start_algo_frag==False kindeny_Remaining=Kindeny_Remaining patient_Remaining=Patient_Remaining tmp=group.paths.split("|") tmp=[i for i in tmp if i!="" ] patient_list=[i[0] for i in tmp] # 候補の患者リスト kideny_list=[i[2] for i in tmp] # 候補の腎臓リスト direction=[i.split(",") for i in tmp ] patient_dict=dict(zip(patient_list,direction)) print(patient_dict) # substep_a Chains=[] substep_b_frag = True for patient_int in patient_list: Conti_frag=True Chain = [patient_int] Pointed = patient_dict[patient_int][1] #腎臓 while Conti_frag: if Pointed in Chain: # substep_a に分岐 substep_b_frag = False if Pointed==patient_int: # サークルの処理 for patient_id in Chain: # Chainを作成 patient = group.get_player_by_id(patient_id) kideny_id = patient_dict[patient_id][1] # 確定腎臓ID # player クラスに保存 if patient.out_frag==False: patient.result=kideny_id patient.out_frag=True # group クラスを更新 # 分配が確定した腎臓(Chain)を kindeny_Remaining から取り除く kindeny_Remaining = [ i for i in kindeny_Remaining if i not in Chain ] group.kideny=",".join(kindeny_Remaining) # 確定者(Chain)をpatient_list から取り除く、以外を残す patient_Remaining = [ i for i in patient_Remaining if i not in Chain ] group.patient = ",".join(patient_Remaining) group.paths="" break elif Pointed== Constants.w: # 優先権 Chains.append(Chain) break elif Pointed not in patient_list: # 退出者 Chains.append(Chain) break Chain.append(Pointed) Pointed = patient_dict[Pointed][1] # 腎臓の更新 print("サブステップB",substep_b_frag) # マッチング終了 判定 if group.patient =="": group.end_frag=True # substep_b 分岐 if substep_b_frag: # 最後尾が未割り当てか判定 first_patient_chains=[ i for i in Chains if i[0] in patient_Remaining] # 選択チェーン候補者の最後尾一覧 length_list=list(map(len,first_patient_chains)) # if len(length_list)!=1: max_length=max(length_list) candidate_chains=[ i for i in first_patient_chains if len(i)== max_length] arrive_set=[] for candidate_chain in candidate_chains: # other_chains=[i for i in candidate_chains if i!=candidate_chain] unique_set=set(candidate_chain) for other_chain in other_chains: unique_set=unique_set.difference(set(other_chain)) if unique_set==set(): tmp=Constants.players_per_group+1 else: tmp= list(map(int,unique_set) ) arrive_set.append(tmp) min_patients=list(map(min,arrive_set)) min_patient=min(min_patients) win_chain = [ i ==min_patient for i in min_patients] for i,j in zip(win_chain,candidate_chains): if i: chain=j # 選択チェーンの処理 for patient_id in chain: if patient_id==Constants.w: # 最前列に到達 break patient = group.get_player_by_id(patient_id) kideny_id = patient_dict[patient_id][1] # 確定腎臓ID # player クラスに保存 if patient.out_frag==False: patient.result=kideny_id patient.out_frag=True # group クラスを更新 # 分配が確定した腎臓(Chain)を kindeny_Remaining から取り除く tmp = [ i for i in kindeny_Remaining if i not in chain[1:] ] # 最後尾の患者を除く group.kideny=",".join(tmp) # 確定者(Chain)をpatient_list から取り除く、以外を残す tmp = [ i for i in patient_Remaining if i not in chain ] group.patient = ",".join(tmp) # 最後尾の患者に対する処理 group.paths = chain[0]+"," +str(Constants.w)+ "|" # 優先権を指す。 # マッチング終了 判定 if group.patient =="": group.end_frag=True #アルゴリズム終了時の処理 if group.end_frag==False: for patient_id in group.patient.split(","): patient = group.get_player_by_id(patient_id) patient.applyed_frag=False class Intro(Page): pass class WaitToStart(WaitPage): # @staticmethod # def after_all_players_arrive(group: Group): # import time # group.auction_timeout = time.time() + 60 pass # PAGES class Bid(Page): # @staticmethod # def get_timeout_seconds(player: Player): # import time # group = player.group # return group.auction_timeout - time.time() @staticmethod def js_vars(player: Player): return get_state(player) # HTMLからのデータ受け取り時の処理 @staticmethod def live_method(player: Player, bid): print("受信データ",bid) group = player.group my_id = player.id_in_group if not player.applyed_frag and bid["clicked"]: player.applyed_frag=True player.current_value = bid["value"] # seaquence の更新 tmp = player.seaquence+","+bid["value"] # 初めの一回目に空白が含まれる tmp = tmp.split(",") tmp = [ i for i in tmp if i!="" ] player.seaquence = ",".join(tmp) # 提出済み(applyed)情報を更新 update_db(player,"applyed","1") tmp = group.applyed+","+bid["value"] tmp = tmp.split(",") tmp = [ i for i in tmp if i!="" ] patient_applyed = tmp group.applyed = ",".join(tmp) # paths を文字列で保存 tmp = group.paths + str(my_id) + "," +bid["value"]+ "|" # 「|」で区切り tmp = tmp.split(",") tmp= [ i for i in tmp if i!=""] group.paths = ",".join(tmp) patient_Remaining = group.patient.split(",") kindeny_Remaining = group.kideny.split(",") #全腎臓の提出後処理 アルゴリズムスタート if len(patient_applyed)==len(patient_Remaining): group.start_algo_frag=True Direction = get_direction(group) Algo(group,kindeny_Remaining,patient_Remaining) group.start_algo_frag=False group.applyed="" # 提出情報をクリア # return {0: dict( get_state(player), algo= True, direction = Direction) } ID = list(range(1,Constants.players_per_group+1)) Info = list() for patient_id in ID: patient=group.get_player_by_id(patient_id) Info =Info + [dict(get_state(patient),algo=True,direction=Direction)] tmp = dict(zip(ID,Info)) return tmp else: return {my_id : get_state(player)} else: return {my_id : get_state(player)} class ResultsWaitPage(WaitPage): # @staticmethod # def after_all_players_arrive(group: Group): # if group.top_bidder > 0: # top_bidder = group.get_player_by_id(group.top_bidder) # top_bidder.payoff = Constants.jackpot - group.top_bid # top_bidder.is_top_bidder = True # if group.second_bidder > 0: # second_bidder = group.get_player_by_id(group.second_bidder) # second_bidder.payoff = -group.second_bid # second_bidder.is_second_bidder = True pass class Results(Page): pass page_sequence = [Intro, WaitToStart, Bid, ResultsWaitPage, Results]