from otree.api import Currency as c, currency_range from ._builtin import Page, WaitPage from .models import Constants import random import time class Ready(Page): def is_displayed(self): return self.round_number == 1 def before_next_page(self): # タスク移動用 self.participant.vars['task_interval'] = time.time() + Constants.task_interval * 60 # タイマーをラウンドまたいで使うために必要なコード1 self.participant.vars['expiry'] = time.time() + Constants.t * 60 # タスクをこなしている時間カウント開始 self.participant.vars['task_time'] = time.time() class Encryption(Page): # タイマー用のテキスト timer_text = '残り時間:' # タイマーをラウンドまたいで使うために必要なコード2 def get_timeout_seconds(self): return self.participant.vars['expiry'] - time.time() # 前のラウンドの残り時間が少ないとき次のラウンドをスキップする def is_displayed(self): # スキップしないために必要な前のラウンドの残り時間 pre_time = Constants.pre_time ''' ※重要 pre_timeが例えば2秒だとすると、残り時間が2秒以下の時に次のラウンドに進もうとすると強制的に終了になる。 これは、残り2秒しかないのなら、次のラウンドの問題を読む時間も答える時間もないから進むだけ無駄ということでそういう仕様。 Constantsでpre_timeを定義しているのは、Choiceページ以降でis_displayed関数を正確に動かすためには同じpre_timeにする必要があるから。 ここの関数内でpre_timeを定義すると他のページで使えない。 ''' return self.participant.vars['expiry'] - time.time() > pre_time # テンプレートファイルに変数を渡す関数 def vars_for_template(self): # アルファベットの表示順シャッフル shuffled_letter = random.sample(Constants.letter, len(Constants.letter)) # アルファベットに対応してる数字のシャッフル numbers = [ random.randint(100, 999) for i in range(len(Constants.letter)) ] # 問題用のアルファベットを3つもってくる problem = random.sample(Constants.letter, 3) # アルファベットと数字を関連つける dict_letter = dict(zip(shuffled_letter, numbers)) # 正しい答えをデータベースに保存しておく self.player.corr_ans1 = dict_letter[ problem[0] ] self.player.corr_ans2 = dict_letter[ problem[1] ] self.player.corr_ans3 = dict_letter[ problem[2] ] return dict( chars = shuffled_letter, codes = numbers, period = self.round_number, prob = problem, ) form_model = 'player' form_fields = ['ans1', 'ans2', 'ans3', 'will_play'] # 次のページに行く前に利得の計算用関数を実行 def before_next_page(self): self.player.score_calc() # これしないと利得が消える self.player.in_round(self.round_number+1).total_payoff = self.player.total_payoff # さぼった時間カウント開始 self.participant.vars['wasted_time'] = time.time() # タスクに使った時間を保存&リセット self.player.task_time = time.time() - self.participant.vars['task_time'] if self.round_number == 1: self.player.total_task_time = self.player.task_time else: self.player.total_task_time = self.player.in_round(self.round_number - 1).total_task_time + self.player.task_time self.participant.vars['task_time'] = time.time() # total_wasted_timeを次のラウンドに持ち越す self.player.in_round(self.round_number + 1).total_wasted_time = self.player.total_wasted_time class Result(Page): def is_displayed(self): return self.participant.vars['expiry'] - time.time() < 0 class Thanks(Page): def is_displayed(self): return self.participant.vars['expiry'] - time.time() < 0 class Game(Page): # タイマー用のテキスト timer_text = '残り時間:' # タイマーをラウンドまたいで使うために必要なコード4 def get_timeout_seconds(self): return self.participant.vars['expiry'] - time.time() # 時間切れ且つ最終回でない時だけ表示 def is_displayed(self): if self.participant.vars['expiry'] - time.time() < 0: return False if self.player.will_play == 'しない': return False return True def before_next_page(self): # これしないと利得が消える self.player.in_round(self.round_number+1).total_payoff = self.player.total_payoff # さぼった時間計算と保存 self.player.wasted_time = time.time() - self.participant.vars['wasted_time'] if self.round_number == 1: self.player.total_wasted_time = self.player.wasted_time self.player.game_num = 1 else: self.player.total_wasted_time = self.player.in_round(self.round_number - 1).total_wasted_time + self.player.wasted_time self.player.game_num = self.player.in_round(self.round_number - 1).game_num + 1 # タスクに使った時間カウント開始 self.participant.vars['task_time'] = time.time() # total_wasted_timeを次のラウンドに持ち越す self.player.in_round(self.round_number + 1).total_wasted_time = self.player.total_wasted_time '''以下〇×ゲーム用''' live_method = "handle_message" def js_vars(self): vars = {} vars['player_symbol'] = self.player.symbol if self.player.ai_class: vars['ai_symbol'] = self.player.ai_plays return vars page_sequence = [Ready, Encryption, Result, Thanks, Game, ]