from otree.api import Currency as c, currency_range from ._builtin import Page, WaitPage from .models import Constants import random import time class P1ToP2(WaitPage): # transition from Part 1 to Part 2 title_text = "Please Wait!" body_text = "Part 2 will start once other participants have finished reading the Part 2 instructions." def is_displayed(self): return self.subsession.round_number ==1 class TreatmentType(WaitPage): # use this waitpage to determine treatment type title_text = "Please Wait!" body_text = "Please wait for your counterpart to proceed." def after_all_players_arrive(self): for p in self.group.get_players(): p.matchround_num() # execute the matchround_num() function p.complex_treatment() # execute the complex_treatment() function def is_displayed(self): return self.subsession.round_number not in Constants.lastrounds_plus1 class EndMatchTreatmentType(WaitPage): # use this waitpage to determine treatment type title_text = "Please Wait!" body_text = "You will be randomly matched with a new person." def after_all_players_arrive(self): for p in self.group.get_players(): p.matchround_num() # execute the matchround_num() function p.complex_treatment() # execute the complex_treatment() function def is_displayed(self): return self.subsession.round_number in Constants.lastrounds_plus1 # Part 2: New Payment Table and Rule Options class Instructions_5(Page): #show this page when payment table changes def vars_for_template(self): return { 'complex_treatment': self.player.complex, 'no_computation': 1-self.session.config['computation'], 'computation': self.session.config['computation'], 'implementation': self.session.config['implementation'], 'salience': self.session.config['salience'], } def is_displayed(self): return self.player.match==Constants.num_matches/2+1 and self.player.round_in_match==1 class Rule(Page): form_model = 'player' form_fields = ['strategy'] def vars_for_template(self): me = self.player return{ 'complex_treatment': me.complex, 'computation': self.session.config['computation'], 'salience': self.session.config['salience'], } def is_displayed(self): return self.subsession.round_number in Constants.first_rounds class RuleWait(WaitPage): title_text = "Please Wait!" body_text = "Please wait for your counterpart to proceed." def after_all_players_arrive(self): for p in self.group.get_players(): p.chosen_rule() # execute the chosen_rule() function p.correct_action() # execute the correct_action() function class Decision(Page): form_model = 'player' form_fields = ['decision'] def vars_for_template(self): me = self.player if me.round_in_match >1: start = Constants.first_rounds[me.match - 1] end = me.round_number-1 mylist = me.in_rounds(start, end) return { 'player_in_previous_rounds_reverse': mylist[::-1], 'chosen_strategy': me.chosenrule=="S1", 'show_history': 1, 'complex_treatment': me.complex, 'salience': self.session.config['salience'], } else: return { 'chosen_strategy': me.chosenrule == "S1", 'show_history': 0,#not show history at the 1st round of a match 'complex_treatment': me.complex, 'salience': self.session.config['salience'], } def is_displayed(self): return self.session.config['implementation']==1 class NoImplementWait(WaitPage): title_text = "Please Wait!" body_text = "Please wait for your counterpart to proceed." def after_all_players_arrive(self): for p in self.group.get_players(): p.no_implementation() def is_displayed(self): return self.session.config['implementation']==0 class NoImplementDecision(Page): timeout_seconds = 3 def vars_for_template(self): me = self.player if me.round_in_match>1: start = Constants.first_rounds[me.match - 1] end = me.round_number-1 mylist=me.in_rounds(start,end) return { 'player_in_previous_rounds_reverse': mylist[::-1], 'chosen_strategy': me.chosenrule=="S1", 'show_history': 1, 'complex_treatment': me.complex, 'action_A': me.decision=='A', 'salience': self.session.config['salience'], } else: return { 'chosen_strategy': me.chosenrule == "S1", 'show_history': 0,#not show history at the 1st round of a match 'complex_treatment': me.complex, 'action_A': me.decision == 'A', 'salience': self.session.config['salience'], } def is_displayed(self): return self.session.config['implementation']==0 class ActionCheckPage(WaitPage): title_text = "Please Wait!" body_text = "Please wait for your counterpart to proceed." def after_all_players_arrive(self): for p in self.group.get_players(): p.check_action()#check if the chosen action follows the chosen rule in the round p.counterpart_decision() # get counterpart's decision class ResultsWaitPage(WaitPage): title_text = "Please Wait!" body_text = "Please wait for your counterpart to proceed." def after_all_players_arrive(self): for p in self.group.get_players(): p.set_payoff() class ResultsWaitpage2(WaitPage):# calculate payoff in a match at the end of a match title_text = "Please Wait!" body_text = "Please wait for your counterpart to proceed." def after_all_players_arrive(self): for p in self.group.get_players(): p.match_payoff() class MistakeAction(Page): # previously named as RoundResults def vars_for_template(self): me = self.player start=Constants.first_rounds[me.match-1] end=me.round_number mylist = me.in_rounds(start, end) return { 'player_up_to_now_reverse': mylist[::-1], 'chosen_strategy': me.chosenrule=="S1", 'complex_treatment': me.complex, 'salience': self.session.config['salience'], } def is_displayed(self): return self.player.checkaction == 0 # show if only making wrong choice in a round class EndRound(Page):# not use in this version, and thus time_limit is not executed timeout_seconds = 100 def vars_for_template(self): continuation_chance = int(round(Constants.delta * 100)) if self.subsession.round_number in Constants.last_rounds:# match is over dieroll = random.randint(continuation_chance+1, 100) else:# match continus dieroll = random.randint(1, continuation_chance) return dict(dieroll=dieroll, continuation_chance=continuation_chance, die_threshold_plus_one=continuation_chance+1,) def after_all_players_arrive(self): elapsed_time = time.time() - self.session.vars['start_time'] if Constants.time_limit == True and elapsed_time > Constants.time_limit_seconds and self.subsession.round_number in Constants.last_rounds: self.session.vars['alive'] = False class EndBlock(Page): def vars_for_template(self): me=self.player #mylist=me.in_rounds(me.round_number-Constants.num_in_block+1, me.round_number) #if only show history of the current block start = Constants.first_rounds[me.match - 1] end = me.round_number mylist = me.in_rounds(start, end) return{ #'player_in_block_reverse': mylist[::-1], 'player_up_to_now_reverse': mylist[::-1], 'num_block': me.round_in_match // Constants.num_in_block, # since we only show the block # at the last round of a match, the calculation is quite easy 'end_in_block': me.round_in_match >= Constants.match_duration[me.match-1], 'num_paidround': Constants.match_duration[me.match-1], } def is_displayed(self): return self.subsession.round_number in Constants.last_rounds and self.session.config['implementation']==1 #def is_displayed(self): #return self.player.round_in_match % Constants.num_in_block ==0 and self.session.config['implementation']==1 class NoImplementEndBlock(Page): timeout_seconds = 3 def vars_for_template(self): me=self.player #mylist = me.in_rounds(me.round_number - Constants.num_in_block + 1, me.round_number) #if only show history of the current block start = Constants.first_rounds[me.match - 1] end = me.round_number mylist = me.in_rounds(start, end) return{ #'player_in_block_reverse': mylist[::-1], 'player_up_to_now_reverse': mylist[::-1], 'num_block': me.round_in_match // Constants.num_in_block, 'end_in_block': me.round_in_match >= Constants.match_duration[me.match-1], 'num_paidround': Constants.match_duration[me.match - 1], } def is_displayed(self): return self.subsession.round_number in Constants.last_rounds and self.session.config['implementation']==0 #def is_displayed(self): #return self.player.round_in_match % Constants.num_in_block ==0 and self.session.config['implementation']==0 class EndMatch(Page): def vars_for_template(self): me=self.player start = Constants.first_rounds[me.match - 1] end = start+Constants.match_duration[me.match-1]-1#only show the history of paid rounds at EndMatch mylist=me.in_rounds(start, end) return{ 'no_mistake': me.nummistake==0, 'player_in_match_reverse': mylist[::-1], 'num_paidround': Constants.match_duration[me.match-1], 'mistake_deduct_sum': me.nummistake*20, 'chosen_strategy': me.chosenrule == "S1", 'complex_treatment': me.complex, 'last_match': self.subsession.round_number == Constants.last_round, 'salience': self.session.config['salience'], } def is_displayed(self): return self.subsession.round_number in Constants.last_rounds class End(Page): form_model = 'player' form_fields = ['QandC', 'useddecisionrule'] def vars_for_template(self): return{ 'pay': self.participant.payoff_plus_participation_fee() } def is_displayed(self): return self.session.vars['alive'] == False or self.subsession.round_number == Constants.last_round class FinalPage(Page): def is_displayed(self): return self.session.vars['alive'] == False or self.subsession.round_number == Constants.last_round page_sequence = [ P1ToP2, TreatmentType, EndMatchTreatmentType, Instructions_5, Rule, RuleWait, Decision, NoImplementWait, NoImplementDecision, ActionCheckPage, ResultsWaitPage, ResultsWaitpage2, MistakeAction, EndBlock, NoImplementEndBlock, #EndRound, EndMatch, End, FinalPage ]