#1 by txb000
Please see the code below, I am trying to distinguish 0 investment with someone who made no investment but the timer runs out, that actually affects the payoffs. Can someone guide? from otree.api import models, BaseConstants, BasePlayer, BaseSubsession, BaseGroup, Page, WaitPage import random class Constants(BaseConstants): name_in_url = 'contest_game' players_per_group = 2 num_rounds = 1 WINNER_PAYOFF = 240 LOSER_PAYOFF = 120 class Player(BasePlayer): endowment = models.IntegerField(initial=120) cost = models.FloatField() investment = models.IntegerField(min=0, max=120) payoff_new = models.CurrencyField() class Subsession(BaseSubsession): def creating_session(self): self.group_randomly(fixed_id_in_group=True) for group in self.get_groups(): players = group.get_players() # Set cost for each player for player in players: player.cost = random.choice([0.6, 0.7, 0.8, 0.9, 1, 1.1, 1.2, 1.3, 1.4, 1.5]) class Group(BaseGroup): investment_p1 = models.IntegerField() investment_p2 = models.IntegerField() def calculate_payoffs(self): p1, p2 = self.get_players() # Check if investments are None (e.g., due to a timeout) if self.investment_p1 is None or self.investment_p2 is None: p1.payoff_new = 0 p2.payoff_new = 0 return total_investment = self.investment_p1 + self.investment_p2 if total_investment > 0: p1_likelihood = self.investment_p1 / total_investment p2_likelihood = self.investment_p2 / total_investment winner = p1 if p1_likelihood > p2_likelihood else p2 else: winner = random.choice([p1, p2]) if winner == p1: p1.payoff_new = Constants.WINNER_PAYOFF - p1.cost * p1.investment p2.payoff_new = Constants.LOSER_PAYOFF - p2.cost * p2.investment else: p1.payoff_new = Constants.LOSER_PAYOFF - p1.cost * p1.investment p2.payoff_new = Constants.WINNER_PAYOFF - p2.cost * p2.investment # Adjust payoff for timeout if self.investment_p1 is None: p1.payoff_new = 0 if self.investment_p2 is None: p2.payoff_new = 0 class Results(Page): @staticmethod def vars_for_template(player): return { 'player_payoff': player.payoff_new, # 'opponent_payoff': player.get_others_in_group()[0].payoff_new, } # timeout_seconds = 20 # Set the desired timeout duration class InvestmentDecision(Page): form_model = 'player' form_fields = ['investment'] @staticmethod def vars_for_template(player): # Set cost for the player before displaying the page player.cost = random.choice([0.6, 0.7, 0.8, 0.9, 1, 1.1, 1.2, 1.3, 1.4, 1.5]) return { 'player_cost': player.cost, } @staticmethod def before_next_page(player, timeout_happened): group = player.group if player.investment is None: # Handle the case of no investment (timed out) player.payoff_new = 0 elif player.id_in_group == 1: group.investment_p1 = player.investment elif player.id_in_group == 2: group.investment_p2 = player.investment timeout_seconds = 30 # Set the desired timeout duration class WaitForSecondParticipant(WaitPage): @staticmethod def after_all_players_arrive(group): group.calculate_payoffs() body_text = "Waiting for the other participant to make their decision." timeout_seconds = 5 # Set the desired timeout duration page_sequence = [InvestmentDecision, WaitForSecondParticipant, Results]
#2 by Fanist
Hey, just a quick thought, how about setting default value of Player.investment as -99? then you can compare -99 and 0 as no investment.