#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.