from otree.api import * import random import time import numpy as np author = 'Kengo SUZUKI' doc = """ This game is originally designed by Sato K, Toda M, and Yamagishi T (1985). https://doi.org/10.4992/jjpsy.56.277 KS replicated this game as a web application for research and educational use. """ ########## 外生的に決めるパラメータを定義するクラス ########## ########## Class to define externally given variables ########## class Constants(BaseConstants): name_in_url = 'STY1985_TYT2d' # The name of game displayed on URL players_per_group = None # The number of human players per game human_per_group = 1 # The number of human players per game bot_per_group = 2 # The number of bot players per game total_per_group = 3 # The number of human and bot players per game num_rounds = 20 # The number of rounds per game num_trees = 3 # The number of trees per game max_tree_size = 9 # Maximum value of tree size initial_tree_size = 9 # Initial value of tree size thinking_time = 30 # Thinking time per round interval_min = 3 # minimum interval between rounds interval_max = 10 # maximum interval between rounds environment = 2 # 0:competitive, 1:cooperative, 2:neutral ########## サブセッション=セッションを構成する各ゲームの集合のクラス(グループ分け,条件設定等) ########## ########## Class of a set of games consisting a session (group assignment etc) ########## class Subsession(BaseSubsession): def creating_session(self): group_matrix = [] players = self.get_players() ppg = self.session.config['players_per_group'] for i in range(0, len(players), ppg): group_matrix.append(players[i:i+ppg]) self.set_group_matrix(group_matrix) ########## グループ変数を定義するクラス ########## ########## Class to define group valiables ########## class Group(BaseGroup): #### 共有林にある木のサイズ size_tree1 = models.IntegerField( # 1本目の木のサイズ max = Constants.max_tree_size, ) size_tree2 = models.IntegerField( # 2本目の木のサイズ max = Constants.max_tree_size, ) size_tree3 = models.IntegerField( # 3本目の木のサイズ max = Constants.max_tree_size, ) size_tree4 = models.IntegerField( # 4本目の木のサイズ max = Constants.max_tree_size, ) #### bot1の行動 cut_input_bot1 = models.IntegerField( # 伐採を希望する木の番号(0は伐採を希望しないことを意味する) initial = 0, min = 0, max =Constants.num_trees ) cut_modify_bot1 = models.IntegerField( # 実際に伐採した木の番号(0は伐採しなかったことを意味する) initial = 0, min = 0, max =Constants.num_trees ) point_get_bot1 = models.IntegerField( # 獲得点数 initial = 0 ) point_accumulation_bot1 = models.IntegerField( # 累積獲得点数 initial = 0 ) #### bot2の行動 cut_input_bot2 = models.IntegerField( # 伐採を希望する木の番号(0は伐採を希望しないことを意味する) initial = 0, min = 0, max =Constants.num_trees ) cut_modify_bot2 = models.IntegerField( # 実際に伐採した木の番号(0は伐採しなかったことを意味する) initial = 0, min = 0, max =Constants.num_trees ) point_get_bot2 = models.IntegerField( # 獲得点数 initial = 0 ) point_accumulation_bot2 = models.IntegerField( # 累積獲得点数 initial = 0 ) #### 環境の記録 num_cut_trees_inputs = models.IntegerField( # 伐採を希望したプレイヤー数 initial=0, ) num_cut_trees_modify = models.IntegerField( # 実際に伐採できたプレイヤー数 initial=0, ) ave_size_of_cut_trees = models.FloatField( # 伐採された木の平均サイズ initial = 0, ) size_tree_average = models.FloatField( # 共有林にある木の平均サイズ(そのラウンドの伐採後=次ラウンドの伐採前) initial = 0, ) total_point_get = models.IntegerField( # 全プレイヤーの総獲得点数 initial = 0, ) total_point_accumulation = models.IntegerField( # 全プレイヤーの総累積獲得点数 initial = 0, ) ########## プレイヤー変数・メソッドを定義するクラス ########## ########## Class to define player valiables ########## class Player(BasePlayer): cut_input = models.IntegerField( # 伐採を希望する木の番号(0は伐採を希望しないことを意味する) initial = 0, min = 0, max =Constants.num_trees ) cut_modify = models.IntegerField( # 実際に伐採した木の番号(0は伐採しなかったことを意味する) initial = 0, min = 0, max =Constants.num_trees ) point_get = models.IntegerField( # 獲得点数 initial = 0 ) point_accumulation = models.IntegerField( # 累積獲得点数 initial = 0 ) ########## 関数(ResultWaitPageで使用する関数は,クラスの外に書く) ########## ########## Functions(Functions used in ResultWaitPage need to be written outside class) ########## #### 木のサイズを更新する関数 def update(group): if group.round_number == 1: group.size_tree1 = Constants.initial_tree_size group.size_tree2 = Constants.initial_tree_size group.size_tree3 = Constants.initial_tree_size group.size_tree4 = Constants.initial_tree_size else: group.size_tree1 = group.in_round(group.round_number-1).size_tree1 group.size_tree2 = group.in_round(group.round_number-1).size_tree2 group.size_tree3 = group.in_round(group.round_number-1).size_tree3 group.size_tree4 = group.in_round(group.round_number-1).size_tree4 #### 競争的ボットの行動を決める関数 def competitive (size_trees): candidate = 0 max_size = 0 action = 0 for i in range(Constants.num_trees): # 最も大きい木のサイズと番号を取得 if size_trees[i] > max_size: max_size = size_trees[i] candidate = i + 1 if max_size == 1: # 最も大きい木のサイズが1の場合:50%の確率で伐採 if random.random() <= 0.25: action = candidate elif max_size == 2: # 最も大きい木のサイズが2の場合:50%の確率で伐採 if random.random() <= 0.5: action = candidate elif max_size == 3: # 最も大きい木のサイズが3の場合:75%の確率で伐採 if random.random() <= 0.75: action = candidate else: # 最も大きい木のサイズが4以上の場合:100%の確率で伐採 action = candidate return action #### 協調的ボットの行動を決める関数 def cooperative (size_trees): candidate = 0 max_size = 0 action = 0 for i in range(Constants.num_trees): # 最も大きい木のサイズと番号を取得 if size_trees[i] > max_size: max_size = size_trees[i] candidate = i + 1 if max_size == 9: # 最も大きい木のサイズが9の場合:100%の確率で伐採 action = candidate elif max_size == 8: # 最も大きい木のサイズが8の場合:75%の確率で伐採 if random.random() <= 0.75: action = candidate elif max_size == 7: # 最も大きい木のサイズが7の場合:50%の確率で伐採 if random.random() <= 0.50: action = candidate elif max_size == 6: # 最も大きい木のサイズが6の場合:25%の確率で伐採 if random.random() <= 0.25: action = candidate else: # 最も大きい木のサイズが5以下の場合:0%の確率で伐採 action = 0 return action #### 中立ボットの行動を決める関数 def neutral (size_trees): candidate = 0 max_size = 0 action = 0 for i in range(Constants.num_trees): # 最も大きい木のサイズと番号を取得 if size_trees[i] > max_size: max_size = size_trees[i] candidate = i + 1 if max_size == 9: # 最も大きい木のサイズが9の場合:100%の確率で伐採 action = candidate elif max_size == 8: # 最も大きい木のサイズが8の場合:87.5%の確率で伐採 if random.random() <= 0.875: action = candidate elif max_size == 7: # 最も大きい木のサイズが7の場合:75%の確率で伐採 if random.random() <= 0.75: action = candidate elif max_size == 6: # 最も大きい木のサイズが6の場合:62.5%の確率で伐採 if random.random() <= 0.625: action = candidate elif max_size == 5: # 最も大きい木のサイズが5の場合:50%の確率で伐採 if random.random() <= 0.5: action = candidate elif max_size == 4: # 最も大きい木のサイズが4の場合:37.5%の確率で伐採 if random.random() <= 0.375: action = candidate elif max_size == 3: # 最も大きい木のサイズが3の場合:25%の確率で伐採 if random.random() <= 0.25: action = candidate elif max_size == 2: # 最も大きい木のサイズが2の場合:12.5%の確率で伐採 if random.random() <= 0.125: action = candidate else: # 最も大きい木のサイズが1以下の場合:0%の確率で伐採 action = 0 return action def solve(group): players = group.get_players() interval = random.randrange(Constants.interval_min,Constants.interval_max) # 遅延処理用 time.sleep(interval) #### 木のサイズのリストを作成 # list of tree size(木のサイズのリスト) size_trees = [] for i in range(Constants.num_trees): tree_number = i + 1 tree_name = 'group.size_tree' + str(tree_number) size_trees.append(eval(tree_name)) #### botの行動を決めるパート # if Constants.environment == 0: if Constants.environment == 0: group.cut_input_bot1 = competitive(size_trees) group.cut_input_bot2 = competitive(size_trees) elif Constants.environment == 1: group.cut_input_bot1 = cooperative(size_trees) group.cut_input_bot2 = cooperative(size_trees) else: group.cut_input_bot1 = neutral(size_trees) group.cut_input_bot2 = neutral(size_trees) #### 全員の場再行動を処理するパート # list of player's decisions(人間とボットの入力をひとつのリストにまとめる) # cut_inputs = [p.cut_input for p in players] # cut_inputs_human = [p.cut_input for p in players] cut_inputs = [p.cut_input for p in players] cut_inputs.append(group.cut_input_bot1) cut_inputs.append(group.cut_input_bot2) cut_modify = [] for i in range(len(cut_inputs)): cut_modify.append(cut_inputs[i]) # count the number of players who decided to cut each tree(各木の伐採を希望する人数) count_cut = [] for i in range(Constants.num_trees): count_cut.append(cut_modify.count(i+1)) # list of players whose decisions are duplicated(他者と伐採希望が重複するプレイヤーにフラグを立てる) # players_duplicate = [0]*Constants.players_per_group players_duplicate = [0]*Constants.total_per_group for i in range(Constants.total_per_group): for j in range(Constants.total_per_group): if (cut_modify[i] != 0 and cut_modify[i] == cut_modify[j] and i != j): players_duplicate[i] = 1 # modify the decisions of players(他者と伐採希望が重複するプレイヤーの入力を修正する) list_players = [] list_trees = [] while sum(players_duplicate)>0: for i in range(Constants.num_trees): # for each tree if count_cut[i] >1: # if more than one player try to cut the tree for j in range(Constants.total_per_group): # list of players who want to cut the tree if cut_inputs[j] == i+1: list_players.append(j+1) for k in range(Constants.num_trees): # list of trees with the same size as the tree if size_trees[k] == size_trees[i] and count_cut[k] != 1: list_trees.append(k+1) while len(list_trees) < len(list_players): list_trees.append(0) random.shuffle(list_trees) # randomize who can get the tree for l in range(len(list_players)): # modify cut cut_modify[list_players[l]-1] = list_trees[l] for m in range(Constants.total_per_group): # update players_duplicate for n in range(Constants.total_per_group): if (cut_modify[m] != 0 and cut_modify[m] == cut_modify[n] and m != n): players_duplicate[m] = 1 else: players_duplicate[m] = 0 for o in range(Constants.num_trees): # update count_cut count_cut[o] = (cut_modify.count(o + 1)) for i in range(Constants.human_per_group): # update Field cut_modify players[i].cut_modify = cut_modify[0] group.cut_modify_bot1 = cut_modify[1] group.cut_modify_bot2 = cut_modify[2] # cut_modify_check = [p.cut_modify for p in players] # デバッグ用 # increase points of players(各プレイヤーの獲得点数と累積獲得点数を更新する) # 人間プレイヤー for i in range(Constants.human_per_group): if cut_modify[i]>0: players[i].point_get = 2**(size_trees[cut_modify[0]-1]-1) if group.round_number == 1: players[i].point_accumulation = players[i].point_get else: players[i].point_accumulation = players[i].in_round(group.round_number-1).point_accumulation + players[i].point_get # ボット1 if group.cut_modify_bot1>0: group.point_get_bot1 = 2**(size_trees[cut_modify[1]-1]-1) if group.round_number == 1: group.point_accumulation_bot1 = group.point_get_bot1 else: group.point_accumulation_bot1 = group.in_round(group.round_number-1).point_accumulation_bot1 + group.point_get_bot1 # ボット2 if group.cut_modify_bot2>0: group.point_get_bot2 = 2**(size_trees[cut_modify[2]-1]-1) if group.round_number == 1: group.point_accumulation_bot2 = group.point_get_bot2 else: group.point_accumulation_bot2 = group.in_round(group.round_number-1).point_accumulation_bot2 + group.point_get_bot2 point_get_check = [p.point_get for p in players] + [group.point_get_bot1] + [group.point_get_bot2] # デバッグ用 point_accumulation_check = [p.point_accumulation for p in players] + [group.point_accumulation_bot1] + [group.point_accumulation_bot2] # デバッグ用 # record total point(全プレイヤーの総獲得点数と総累積獲得点数を更新する) group.total_point_get = sum(point_get_check) group.total_point_accumulation = sum(point_accumulation_check) # record the number of cut trees(伐採を希望したプレイヤー数と実際に伐採したプレイヤー数を更新する) for i in range(Constants.total_per_group): if cut_inputs[i] > 0: group.num_cut_trees_inputs = group.num_cut_trees_inputs +1 for i in range(Constants.total_per_group): if cut_modify[i] > 0: group.num_cut_trees_modify = group.num_cut_trees_modify +1 # record average size of cut trees(伐採された木の平均サイズを更新する;1本も伐採されなかったらゼロとなる) ave_size_of_cut_trees = [] for i in range(Constants.num_trees): if count_cut[i] != 0: ave_size_of_cut_trees.append(size_trees[i]) if len(ave_size_of_cut_trees)>0: group.ave_size_of_cut_trees = sum(ave_size_of_cut_trees) / len(ave_size_of_cut_trees) else: group.ave_size_of_cut_trees = 0 # reset the size of cut trees(伐採された木のサイズを0にする) size_trees_after = [] for i in range(Constants.num_trees): if count_cut[i]>0: size_trees_after.append(0) else: size_trees_after.append(size_trees[i]) # trees grow(すべての木のサイズを1増やす;最大に達したらそれ以上増えない) for i in range(Constants.num_trees): if size_trees_after[i] < Constants.max_tree_size: size_trees_after[i] = size_trees_after[i]+1 for i in range(Constants.num_trees): # update Field size_treeX tree_number = i + 1 trees_grow = 'group.size_tree' + str(tree_number) + '= size_trees_after[i]' exec(trees_grow) # record average tree size just after cut group.size_tree_average = sum(size_trees_after) / Constants.num_trees print('players is', players) # デバッグ用 print('size_trees is', size_trees) # デバッグ用 print('cut_inputs is', cut_inputs) # デバッグ用 print('count_cut is', count_cut) # デバッグ用 print('players_duplicate is', players_duplicate) # デバッグ用 print('list_players is', list_players) # デバッグ用 print('list_trees is', list_trees) # デバッグ用 print('cut_modify is', cut_modify) # デバッグ用 # print('cut_modify_check is', cut_modify_check) print('point_get_check is', point_get_check) print('point_accumulation_check is', point_accumulation_check) print('total_point_get is', group.total_point_get) print('total_point_accumulation is', group.total_point_accumulation) print('num_cut_trees_inputs is', group.num_cut_trees_inputs) print('num_cut_trees_modify is', group.num_cut_trees_modify) print('ave_size_of_cut_trees is', ave_size_of_cut_trees) print('ave_size_of_cut_trees is', group.ave_size_of_cut_trees) print('size_trees_after is', size_trees_after) print('size_tree_average is', group.size_tree_average) print('size_tree1 is', group.size_tree1) # デバッグ用 print('size_tree2 is', group.size_tree2) # デバッグ用 print('size_tree3 is', group.size_tree3) # デバッグ用 print('size_tree4 is', group.size_tree4) # デバッグ用 ########## ページを定義するクラス ########## ########## Class to define pages ########## class Introduction(Page): @staticmethod def is_displayed(self): return self.round_number == 1 @staticmethod def vars_for_template(self): return dict( # num_rounds=self.session.config['num_rounds'], num_rounds=Constants.num_rounds, ) class ResultsWaitPage1(WaitPage): after_all_players_arrive = 'update' class Input1(Page): form_model = 'player' form_fields = ['cut_input'] @staticmethod def is_displayed(self): return self.round_number == 1 @staticmethod def vars_for_template(self): return dict( num_trees=Constants.num_trees, image_path1 = 'STY1985/tree_{}.jpg'.format(self.group.size_tree1), image_path2 = 'STY1985/tree_{}.jpg'.format(self.group.size_tree2), image_path3 = 'STY1985/tree_{}.jpg'.format(self.group.size_tree3), image_path4 = 'STY1985/tree_{}.jpg'.format(self.group.size_tree4), ) class Input2(Page): form_model = 'player' form_fields = ['cut_input'] timeout_seconds = Constants.thinking_time @staticmethod def is_displayed(self): return self.round_number > 1 @staticmethod def vars_for_template(self): return dict( round_number = self.round_number, num_trees = Constants.num_trees, cut_input_prev = self.in_round(self.round_number-1).cut_input, cut_modify_prev = self.in_round(self.round_number-1).cut_modify, point_get_prev = self.in_round(self.round_number-1).point_get, point_accumulation_prev = self.in_round(self.round_number-1).point_accumulation, cut_input_prev_bot1=self.group.in_round(self.round_number - 1).cut_input_bot1, cut_modify_prev_bot1=self.group.in_round(self.round_number - 1).cut_modify_bot1, point_get_prev_bot1=self.group.in_round(self.round_number - 1).point_get_bot1, point_accumulation_prev_bot1=self.group.in_round(self.round_number - 1).point_accumulation_bot1, cut_input_prev_bot2=self.group.in_round(self.round_number - 1).cut_input_bot2, cut_modify_prev_bot2=self.group.in_round(self.round_number - 1).cut_modify_bot2, point_get_prev_bot2=self.group.in_round(self.round_number - 1).point_get_bot2, point_accumulation_prev_bot2=self.group.in_round(self.round_number - 1).point_accumulation_bot2, image_path1 = 'STY1985/tree_{}.jpg'.format(self.group.size_tree1), image_path2 = 'STY1985/tree_{}.jpg'.format(self.group.size_tree2), image_path3 = 'STY1985/tree_{}.jpg'.format(self.group.size_tree3), image_path4 = 'STY1985/tree_{}.jpg'.format(self.group.size_tree4), ) @staticmethod def js_vars(self): ## 配列の作成に必要な定数をローカルに作成 round_number = self.round_number # 現在のラウンド数 players = self.group.get_players() # すべてのプレイヤーのリスト # num_players = Constants.total_per_group # プレイヤーの人数 ## point_accumulation を出力する List を作成 List_point_accumulation = [] ## 人間プレイヤーの処理 for p in players: # リストに含まれるプレイヤーについて id = p.id_in_group # id を取得 pname = 'Player' + str(id) # プレイヤー名の文字列 pdata = [] # データ格納用のリスト for j in range(round_number-1): # 1ラウンド目から直前のラウンドまでについて pdata.append(p.in_round(j+1).point_accumulation) # pdata リストに値を追加 pdict = {'name':pname,'data':pdata} # プレイヤー毎のリストを作成 List_point_accumulation.append(pdict) ## ボットの処理 pname = 'Player2' pdata = [] # データ格納用のリスト for j in range(round_number - 1): # 1ラウンド目から直前のラウンドまでについて pdata.append(self.group.in_round(j + 1).point_accumulation_bot1) # pdata リストに値を追加 pdict = {'name': pname, 'data': pdata} # プレイヤー毎のリストを作成 List_point_accumulation.append(pdict) pname = 'Player3' pdata = [] # データ格納用のリスト for j in range(round_number - 1): # 1ラウンド目から直前のラウンドまでについて pdata.append(self.group.in_round(j + 1).point_accumulation_bot2) # pdata リストに値を追加 pdict = {'name': pname, 'data': pdata} # プレイヤー毎のリストを作成 List_point_accumulation.append(pdict) print('List_point_accumulation is', List_point_accumulation) # デバッグ用 return dict( round_number = self.round_number, num_rounds=Constants.num_rounds, List_point_accumulation = List_point_accumulation, ) class ResultsWaitPage2(WaitPage): # time.sleep(5) after_all_players_arrive = 'solve' class GameOver(Page): @staticmethod def is_displayed(self): return self.round_number == Constants.num_rounds # return self.round_number == self.session.config['num_rounds'] @staticmethod def vars_for_template(self): ## 配列の作成に必要な定数をローカルに作成 # round_number = self.round_number # 現在のラウンド数 # players = self.group.get_players() # すべてのプレイヤーのリスト # num_players = Constants.players_per_group # プレイヤーの人数 return dict( round_number = self.round_number, num_trees=Constants.num_trees, cut_input = self.cut_input, cut_modify = self.cut_modify, point_get = self.point_get, point_accumulation = self.point_accumulation, cut_input_bot1=self.group.cut_input_bot1, cut_modify_bot1=self.group.cut_modify_bot1, point_get_bot1=self.group.point_get_bot1, point_accumulation_bot1=self.group.point_accumulation_bot1, cut_input_bot2=self.group.cut_input_bot2, cut_modify_bot2=self.group.cut_modify_bot2, point_get_bot2=self.group.point_get_bot2, point_accumulation_bot2=self.group.point_accumulation_bot2, ) @staticmethod def js_vars(self): ## 配列の作成に必要な定数をローカルに作成 round_number = self.round_number # 現在のラウンド数 players = self.group.get_players() # すべてのプレイヤーのリスト # num_players = Constants.players_per_group # プレイヤーの人数 ## point_accumulation を出力する List を作成 List_point_accumulation = [] ## 人間プレイヤーの処理 for p in players: # リストに含まれるプレイヤーについて id = p.id_in_group # id を取得 pname = 'Player' + str(id) # プレイヤー名の文字列 pdata = [] # データ格納用のリスト for j in range(round_number-1): # 1ラウンド目から直前のラウンドまでについて pdata.append(p.in_round(j+1).point_accumulation) # pdata リストに値を追加 pdata.append(p.point_accumulation) # 最終ラウンドの値を追加 pdict = {'name':pname,'data':pdata} # プレイヤー毎のリストを作成 List_point_accumulation.append(pdict) ## ボットの処理 pname = 'Player2' pdata = [] # データ格納用のリスト for j in range(round_number - 1): # 1ラウンド目から直前のラウンドまでについて pdata.append(self.group.in_round(j + 1).point_accumulation_bot1) # pdata リストに値を追加 pdict = {'name': pname, 'data': pdata} # プレイヤー毎のリストを作成 List_point_accumulation.append(pdict) pname = 'Player3' pdata = [] # データ格納用のリスト for j in range(round_number - 1): # 1ラウンド目から直前のラウンドまでについて pdata.append(self.group.in_round(j + 1).point_accumulation_bot2) # pdata リストに値を追加 pdict = {'name': pname, 'data': pdata} # プレイヤー毎のリストを作成 List_point_accumulation.append(pdict) print('List_point_accumulation is', List_point_accumulation) # デバッグ用 ## num_cut_trees_inputs & _modifyを出力する List を作成 pname1 = '希望' # pdata1 = [] # データ格納用のリスト for j in range(round_number-1): # 1ラウンド目から直前のラウンドまでについて pdata1.append(self.group.in_round(j+1).num_cut_trees_inputs) # pdata リストに値を追加 pdata1.append(self.group.num_cut_trees_inputs) # 最終ラウンドの値を追加 dict1 = {'name':pname1,'data':pdata1} pname2 = '伐採' # pdata2 = [] # データ格納用のリスト for j in range(round_number-1): # 1ラウンド目から直前のラウンドまでについて pdata2.append(self.group.in_round(j+1).num_cut_trees_modify) # pdata リストに値を追加 pdata2.append(self.group.num_cut_trees_modify) # 最終ラウンドの値を追加 dict2 = {'name':pname2,'data':pdata2} List_num_cut_trees = [dict1,dict2] # プレイヤー毎のリストを作成 ## ave_size_of_cut_treesを出力する List を作成 pname1 = 'inputs' # プレイヤー名の文字列 pdata1 = [] # データ格納用のリスト for j in range(round_number-1): # 1ラウンド目から直前のラウンドまでについて pdata1.append(self.group.in_round(j+1).ave_size_of_cut_trees) # pdata リストに値を追加 pdata1.append(self.group.ave_size_of_cut_trees) # 最終ラウンドの値を追加 List_ave_size_of_cut_trees = [{'name':pname1,'data':pdata1}] ## size_tree_averageを出力する List を作成 pname1 = 'inputs' # プレイヤー名の文字列 pdata1 = [] # データ格納用のリスト for j in range(round_number-1): # 1ラウンド目から直前のラウンドまでについて pdata1.append(self.group.in_round(j+1).size_tree_average) # pdata リストに値を追加 pdata1.append(self.group.size_tree_average) # 最終ラウンドの値を追加 List_size_tree_average = [{'name':pname1,'data':pdata1}] print('List_point_accumulation is', List_point_accumulation) # デバッグ用 print('List_num_cut_trees is', List_num_cut_trees) # デバッグ用 print('List_ave_size_of_cut_trees is', List_ave_size_of_cut_trees) # デバッグ用 print('List_size_tree_average is', List_size_tree_average) # デバッグ用 return dict( round_number = self.round_number, # num_rounds = self.session.config['num_rounds'], num_rounds=Constants.num_rounds, List_point_accumulation = List_point_accumulation, List_num_cut_trees = List_num_cut_trees, List_ave_size_of_cut_trees = List_ave_size_of_cut_trees, List_size_tree_average = List_size_tree_average, ) page_sequence = [Introduction, ResultsWaitPage1, Input1, Input2, ResultsWaitPage2, GameOver]