from otree.api import Page, cu from .models import Constants as C # C.SEQUENCES_BY_INFOSET and C.OPTION_BY_OUTCOME must exist class Page1(Page): # --- helpers --- def _get_tg(self): tg = self.participant.vars.get('tg') or getattr(self.player, 'tg', None) return int(tg) if tg is not None else None def _get_info_set(self): iset = self.participant.vars.get('info_set') or getattr(self.player, 'info_set', None) if iset is None: raise RuntimeError('participant.vars["info_set"] must be set before this app.') return int(iset) def _get_seq(self, info_set: int): seq = C.SEQUENCES_BY_INFOSET.get(info_set) if seq is None: raise RuntimeError(f'No sequence for info_set={info_set}.') if len(seq) != C.num_rounds: raise RuntimeError(f'Sequence for info_set={info_set} must have {C.num_rounds} items.') return seq def _get_cents(self, seq, round_no: int) -> int: return int(seq[round_no - 1]) # 6, 2, or 0 # --- oTree hooks --- def vars_for_template(self): r = self.subsession.round_number tg = self._get_tg() info_set = self._get_info_set() seq = self._get_seq(info_set) cents = self._get_cents(seq, r) which_option = C.OPTION_BY_OUTCOME.get(cents) # e.g., {6:1, 0:1, 2:2} if which_option is None: raise RuntimeError( f'Unexpected outcome {cents}; expected one of {list(C.OPTION_BY_OUTCOME.keys())}.' ) added = cu(cents / 100) current_total = self.participant.payoff total_after = current_total + added # Build history including current round (round 1 => one item) history = [] if tg == 4: for i in range(r): # 0..r-1 c = int(seq[i]) opt = C.OPTION_BY_OUTCOME.get(c) if opt is None: raise RuntimeError(f'Unexpected outcome {c}') history.append(f"L{opt}: {c}") return dict( round_no=r, tg=tg, info_set=info_set, outcome_cents=cents, which_option=which_option, added=added, current_total=current_total, total_after=total_after, history=history, # always a list (possibly empty if tg != 4, but you only render for tg==4) ) def before_next_page(self, timeout_happened=False): r = self.subsession.round_number tg = self._get_tg() info_set = self._get_info_set() seq = self._get_seq(info_set) cents = self._get_cents(seq, r) if tg == 3 and cents: self.participant.payoff += cu(cents / 100) page_sequence = [Page1]