from otree.api import Currency as c, currency_range from ._builtin import Page, WaitPage from .models import Constants class Purchase(Page): form_model = 'player' form_fields = ['purchase_num', 'purchase_price'] def is_displayed(self): # ラウンドナンバーが1,4,7...のときは3で割ると余り1になる。 # この性質を使って1, 4, 7...と3ラウンドごとに初期配分を独立させる。 if self.round_number % 3 == 1: flag = True else: return False # 1200枠以上になってたらis_displayedはFalseでページスキップ if self.group.can_haibun: return False return flag def error_message(self, values): # print('values is', values) if values['purchase_num'] * values['purchase_price'] > Constants.shihonkin: message_text = ''' 入札価格と希望購入枠の積が%s以下になるようにしてください ''' % Constants.shihonkin return message_text # 実験説明のラウンド数、ターン数にoTreeのラウンド数を変換する用 def vars_for_template(self): round_num = (self.round_number + 2) // 3 turn_num = self.round_number % 3 if turn_num == 0: turn_num = 3 return dict( round_num = round_num, turn_num = turn_num ) class PurchaseWaitPage(WaitPage): def is_displayed(self): # ラウンドナンバーが1,4,7...のときは3で割ると余り1になる。 # この性質を使って1, 4, 7...と3ラウンドごとに初期配分を独立させる。 if self.round_number % 3 == 1: flag = True else: return False # 1200枠以上になってたらis_displayedはFalseでページスキップ if self.group.can_haibun: return False return flag after_all_players_arrive = 'do_shoki_haibun' class Purchase_result1(Page): def is_displayed(self): # ラウンドナンバーが1,4,7...のときは3で割ると余り1になる。 # この性質を使って1, 4, 7...と3ラウンドごとに初期配分を独立させる。 if self.round_number % 3 == 1: flag = True else: return False # 1200枠以上になってたらis_displayedはFalseでページスキップ if self.group.can_haibun: return False return flag # 実験説明のラウンド数、ターン数にoTreeのラウンド数を変換する用 def vars_for_template(self): round_num = (self.round_number + 2) // 3 turn_num = self.round_number % 3 if turn_num == 0: turn_num = 3 return dict( round_num = round_num, turn_num = turn_num ) class Purchase_result2(Page): def is_displayed(self): # ラウンドナンバーが1,4,7...のときは3で割ると余り1になる。 # この性質を使って1, 4, 7...と3ラウンドごとに初期配分を独立させる。 if self.round_number % 3 == 1: return True else: return False # 実験説明のラウンド数、ターン数にoTreeのラウンド数を変換する用 def vars_for_template(self): round_num = (self.round_number + 2) // 3 turn_num = self.round_number % 3 if turn_num == 0: turn_num = 3 return dict( round_num = round_num, turn_num = turn_num, players = self.group.get_players() ) class Invest(Page): form_model = 'player' form_fields = ['invest'] def is_displayed(self): flag = False if self.group.can_haibun: flag = True if self.player.invest == 'はい': flag = False return flag def before_next_page(self): if self.player.invest == 'はい': self.player.shojikin -= Constants.invest_price # 実験説明のラウンド数、ターン数にoTreeのラウンド数を変換する用 def vars_for_template(self): round_num = (self.round_number + 2) // 3 turn_num = self.round_number % 3 if turn_num == 0: turn_num = 3 return dict( round_num = round_num, turn_num = turn_num ) class Seisan(Page): form_model = 'player' form_fields = ['seisan'] def before_next_page(self): if self.player.invest == 'はい': if self.player.seisan == '拡大': self.player.waku_num -= Constants.expand_need_ticket self.player.shojikin += Constants.expand_profit elif self.player.seisan == '通常': self.player.waku_num -= Constants.normal_need_ticket self.player.shojikin += Constants.normal_profit elif self.player.seisan == '縮小': self.player.waku_num -= Constants.shrink_need_ticket self.player.shojikin += Constants.shrink_profit else: if self.player.seisan == '拡大': self.player.waku_num -= Constants.expand_need self.player.shojikin += Constants.expand_profit elif self.player.seisan == '通常': self.player.waku_num -= Constants.normal_need self.player.shojikin += Constants.normal_profit elif self.player.seisan == '縮小': self.player.waku_num -= Constants.shrink_need self.player.shojikin += Constants.shrink_profit # 実験説明のラウンド数、ターン数にoTreeのラウンド数を変換する用 def vars_for_template(self): round_num = (self.round_number + 2) // 3 turn_num = self.round_number % 3 if turn_num == 0: turn_num = 3 return dict( round_num = round_num, turn_num = turn_num ) class Emission_trade1(Page): form_model = 'player' form_fields = ['emission'] def error_message(self, values): # print('values is', values) if self.player.waku_num <= 0 and values['emission'] == '売る': message_text = ''' 所持枠がないため枠を売ることはできません ''' return message_text def before_next_page(self): # modelsイニシャライズ if self.player.emission == '買う': self.player.sell_price = 0 self.player.sell_num = 0 elif self.player.emission == '売る': self.player.buy_price = 0 self.player.buy_num = 0 else: self.player.sell_price = 0 self.player.sell_num = 0 self.player.buy_price = 0 self.player.buy_num = 0 # 実験説明のラウンド数、ターン数にoTreeのラウンド数を変換する用 def vars_for_template(self): round_num = (self.round_number + 2) // 3 turn_num = self.round_number % 3 if turn_num == 0: turn_num = 3 return dict( round_num = round_num, turn_num = turn_num ) class Emission_wait1(WaitPage): pass class Emission_buy(Page): form_model = 'player' form_fields = ['buy_num','buy_price'] def is_displayed(self): flag = False players = self.group.get_players() emission_lst = [] for player in players: player_choice = player.emission emission_lst.append(player_choice) if '買う' in emission_lst and '売る' in emission_lst: if self.player.emission == '買う': flag = True return flag def error_message(self, values): if values['buy_num'] * values['buy_price'] > self.player.shojikin: message_text = ''' 枠を買う数と枠の価格の積が%s以下になるようにしてください ''' % self.player.shojikin return message_text # 実験説明のラウンド数、ターン数にoTreeのラウンド数を変換する用 def vars_for_template(self): round_num = (self.round_number + 2) // 3 turn_num = self.round_number % 3 if turn_num == 0: turn_num = 3 return dict( round_num = round_num, turn_num = turn_num ) class Emission_sell(Page): form_model = 'player' form_fields = ['sell_num','sell_price'] def is_displayed(self): flag = False players = self.group.get_players() emission_lst = [] for player in players: player_choice = player.emission emission_lst.append(player_choice) if '買う' in emission_lst and '売る' in emission_lst: if self.player.emission == '売る': flag = True return flag def error_message(self, values): if values['sell_num'] > self.player.waku_num: message_text = ''' 売る枠数は%s以下にしてください。 ''' % self.player.waku_num return message_text # 実験説明のラウンド数、ターン数にoTreeのラウンド数を変換する用 def vars_for_template(self): round_num = (self.round_number + 2) // 3 turn_num = self.round_number % 3 if turn_num == 0: turn_num = 3 return dict( round_num = round_num, turn_num = turn_num ) class Emission_wait2(WaitPage): after_all_players_arrive = 'do_emission_trade' class Emission_result(Page): # 実験説明のラウンド数、ターン数にoTreeのラウンド数を変換する用 def vars_for_template(self): round_num = (self.round_number + 2) // 3 turn_num = self.round_number % 3 if turn_num == 0: turn_num = 3 return dict( round_num = round_num, turn_num = turn_num ) # 次のターンへの持ち越し def before_next_page(self): if self.round_number % 3 == 0: if self.player.waku_num < 0: self.player.shojikin += self.player.waku_num * 300 self.player.shisan += self.player.shojikin else: # 均一価格方式にするときは下の処理要注意 self.player.shisan += self.player.shojikin kansan_price = self.group.kinko_price // 2 kansan_okane = kansan_price * self.player.waku_num self.player.shisan += kansan_okane else: if self.player.waku_num < 0: self.player.shojikin += self.player.waku_num * 300 self.player.in_round(self.round_number+1).invest = self.player.invest self.group.in_round(self.round_number+1).can_haibun = self.group.can_haibun self.group.in_round(self.round_number+1).kinko_price = self.group.kinko_price class Turn_result(Page): def is_displayed(self): return self.round_number % 3 > 0 def before_next_page(self): if self.player.waku_num < 0: self.player.in_round(self.round_number+1).waku_num = 0 else: self.player.in_round(self.round_number+1).waku_num = self.player.waku_num self.player.in_round(self.round_number+1).shojikin = self.player.shojikin # 実験説明のラウンド数、ターン数にoTreeのラウンド数を変換する用 def vars_for_template(self): round_num = (self.round_number + 2) // 3 turn_num = self.round_number % 3 if turn_num == 0: turn_num = 3 return dict( round_num = round_num, turn_num = turn_num ) class Round_result(Page): def is_displayed(self): return self.round_number % 3 == 0 # 実験説明のラウンド数、ターン数にoTreeのラウンド数を変換する用 def vars_for_template(self): round_num = (self.round_number + 2) // 3 turn_num = self.round_number % 3 if turn_num == 0: turn_num = 3 return dict( round_num = round_num, turn_num = turn_num ) # かなり無理矢理感あるが、これで1200枠になるまでループさせることができる shoki_lst = [] for _ in range(30): shoki_lst.append(Purchase) shoki_lst.append(PurchaseWaitPage) shoki_lst.append(Purchase_result1) page_sequence = [ *shoki_lst, Purchase_result2, Invest, Seisan, Emission_trade1, Emission_wait1, Emission_buy, Emission_sell, Emission_wait2, Emission_result, Turn_result, Round_result ]