from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) import random from django.utils import timezone import time from datetime import datetime import json author = 'Jian S' doc = """ fight and flee game """ class Constants(BaseConstants): name_in_url = 'fight_and_flee_20190721' players_per_group = 2 num_rounds = 41 #for real game, that should equal to 41 endowment = c(190) vh = c(100) vl = c(100) cost = c(5) k = c(100) class Subsession(BaseSubsession): def creating_session(self): print('in creating_session') self.group_randomly() if self.round_number == 1: paying_round = random.randint(2, Constants.num_rounds) self.session.vars['paying_round'] = paying_round self.session.vars['lossaversionchosen'] = random.randint(1, 6) #print('set the paying round to', paying_round) for p in self.get_players(): p.ability = random.randint(0, 1000) p.round_chosen = self.session.vars['paying_round'] p.lossaversionchosen = self.session.vars['lossaversionchosen'] class Group(BaseGroup): def set_payoffs(self): #print('in set_payoffs') p1 = self.get_player_by_role('P1') p2 = self.get_player_by_role('P2') if p1.period1_choice =='Flee' or p2.period1_choice == 'Flee': for player in [p1,p2]: player.period1_end = True player.period2_end = False player.period3_end = False elif p1.period2_choice == 'Flee' or p2.period2_choice == 'Flee': for player in [p1,p2]: player.period1_end = False player.period2_end = True player.period3_end = False elif p1.period3_choice == 'Flee' or p1.period3_choice == 'Fight' or p2.period3_choice == 'Flee' or p2.period3_choice == 'Fight': for player in [p1,p2]: player.period1_end = False player.period2_end = False player.period3_end = True else: for player in [p1,p2]: player.period1_end = False player.period2_end = False player.period3_end = False if p1.period1_end: for player in [p1,p2]: player.choice = player.period1_choice player.period = 1 elif p1.period2_end: for player in [p1,p2]: player.choice = player.period2_choice player.period = 2 elif p1.period3_end: for player in [p1,p2]: player.choice = player.period3_choice player.period = 3 if p1.period1_end: for player in [p1,p2]: player.round_result = 'escape' if p1.period1_choice == 'Flee' and p2.period1_choice == 'Flee': p1.round_earning = (Constants.vh + Constants.k)/2 p2.round_earning = (Constants.vh + Constants.k)/2 elif p1.period1_choice =='Flee' and p2.period1_choice != 'Flee': p1.round_earning = c(0) p2.round_earning = Constants.k + Constants.vh else: p1.round_earning = Constants.k + Constants.vh p2.round_earning = c(0) elif p1.period2_end: for player in [p1,p2]: player.round_result = 'escape' if p1.period2_choice == 'Flee' and p2.period2_choice == 'Flee': p1.round_earning = (Constants.vh + Constants.k)/2 - Constants.cost p2.round_earning = (Constants.vh + Constants.k)/2 - Constants.cost elif p1.period2_choice == 'Flee' and p2.period2_choice != 'Flee': p1.round_earning = c(0)-Constants.cost p2.round_earning = Constants.k + Constants.vh - Constants.cost else: p1.round_earning = Constants.k + Constants.vh - Constants.cost p2.round_earning = c(0)-Constants.cost elif p1.period3_end: p = random.random() pp = random.random() if p1.period3_choice == 'Flee' and p2.period3_choice == 'Flee': for player in [p1,p2]: player.round_result = 'escape' p1.round_earning = (Constants.vh + Constants.k)/2 - 2*Constants.cost p2.round_earning = (Constants.vh + Constants.k)/2 - 2*Constants.cost elif p1.period3_choice == 'Flee' and p2.period3_choice == 'Fight': if (p > 0.5): #battle occurs# for player in [p1,p2]: player.round_result = 'battle' if p2.ability > p1.ability: p2.round_earning = Constants.vh - 2*Constants.cost p1.round_earning = c(0)- Constants.vl - 2*Constants.cost elif p2.ability < p1.ability: p2.round_earning = c(0) -Constants.vl - 2*Constants.cost p1.round_earning = Constants.vh - 2*Constants.cost else: if pp>0.5: p1.round_earning = Constants.vh - 2*Constants.cost p2.round_earning = c(0)-Constants.vl - 2*Constants.cost else: p1.round_earning = c(0)-Costants.vl-2*Constants.cost p2.round_earning = Constants.vh - 2*Constants.cost else: #escape occurs# for player in [p1,p2]: player.round_result = 'escape' p1.round_earning = c(0)- 2*Constants.cost p2.round_earning = Constants.k + Constants.vh -2*Constants.cost elif p1.period3_choice == 'Fight' and p2.period3_choice == 'Flee': if (p > 0.5):#battle occurs# for player in [p1,p2]: player.round_result = 'battle' if p2.ability > p1.ability: p2.round_earning = Constants.vh - 2*Constants.cost p1.round_earning = c(0) - Constants.vl - 2*Constants.cost elif p2.ability < p1.ability: p2.round_earning = c(0) - Constants.vl - 2*Constants.cost p1.round_earning = Constants.vh - 2*Constants.cost else: if pp > 0.5: p1.round_earning = Constants.vh - 2 * Constants.cost p2.round_earning = c(0) - Constants.vl - 2 * Constants.cost else: p1.round_earning = c(0) - Costants.vl - 2 * Constants.cost p2.round_earning = Constants.vh - 2 * Constants.cost else: #escape occurs# for player in [p1,p2]: player.round_result = 'escape' p1.round_earning = c(0) + Constants.k + Constants.vh - 2*Constants.cost p2.round_earning = c(0) - 2*Constants.cost elif p1.period3_choice == 'Fight' and p2.period3_choice == 'Fight': for player in [p1,p2]: player.round_result = 'battle' if p2.ability > p1.ability: p2.round_earning = Constants.vh - 2 * Constants.cost p1.round_earning = c(0)- Constants.vl - 2 * Constants.cost elif p2.ability < p1.ability: p2.round_earning = c(0) - Constants.vl - 2 * Constants.cost p1.round_earning = c(0) + Constants.vh - 2 * Constants.cost else: if pp > 0.5: p1.round_earning = Constants.vh - 2 * Constants.cost p2.round_earning = c(0) - Constants.vl - 2 * Constants.cost else: p1.round_earning = c(0) - Costants.vl - 2 * Constants.cost p2.round_earning = Constants.vh - 2 * Constants.cost for player in [p1,p2]: player.payoff = player.round_earning + Constants.endowment if player.period == 1: player.cost_waiting = 0 elif player.period == 2: player.cost_waiting = 5 elif player.period == 3: player.cost_waiting = 10 player.part1_currency_payoff = player.payoff.to_real_world_currency(self.session) class Player(BasePlayer): period1_choice = models.StringField( choices=['Flee','Wait'], widget=widgets.RadioSelect, blank = True, initial = 'Wait' ) period2_choice = models.StringField( choices=['Flee','Wait'], widget=widgets.RadioSelect, blank = True, initial = 'Wait' ) period3_choice = models.StringField( choices=['Flee', 'Fight'], widget=widgets.RadioSelect, blank = True, initial = 'Fight' ) choice = models.StringField() ability = models.IntegerField() cost_waiting = models.IntegerField() round_earning = models.CurrencyField() round_result = models.StringField() period1_end = models.BooleanField() period2_end = models.BooleanField() period3_end = models.BooleanField(initial = False) period = models.IntegerField() round_chosen = models.IntegerField() lossaversionchosen = models.IntegerField() part1_currency_payoff = models.CurrencyField() period3_seconds = models.FloatField() LTchoice1 = models.StringField( choices=['Accept', 'Reject'], label='Lottery 1: if the coin turns up head, then you loss $1; if the coin turns up tails, you win $3.', widget=widgets.RadioSelectHorizontal) LTchoice2 = models.StringField( choices=['Accept', 'Reject'], label='Lottery 2: if the coin turns up head, then you loss $1.5; if the coin turns up tails, you win $3.', widget=widgets.RadioSelectHorizontal) LTchoice3 = models.StringField( choices=['Accept', 'Reject'], label='Lottery 3: if the coin turns up head, then you loss $2; if the coin turns up tails, you win $3.', widget=widgets.RadioSelectHorizontal) LTchoice4 = models.StringField( choices=['Accept', 'Reject'], label='Lottery 4: if the coin turns up head, then you loss $2.5; if the coin turns up tails, you win $3.', widget=widgets.RadioSelectHorizontal) LTchoice5 = models.StringField( choices=['Accept', 'Reject'], label='Lottery 5: if the coin turns up head, then you loss $3; if the coin turns up tails, you win $3.', widget=widgets.RadioSelectHorizontal) LTchoice6 = models.StringField( choices=['Accept', 'Reject'], label='Lottery 6: if the coin turns up head, then you loss $3.5; if the coin turns up tails, you win $3.', widget=widgets.RadioSelectHorizontal) age = models.IntegerField( label='What is your age?', min=18, max=125) gender = models.StringField( choices=['Male', 'Female', 'Other'], label='What is your gender?', widget=widgets.RadioSelect) citizenship = models.StringField( label='Your country of citizenship') major = models.StringField( label='What is your major?') year = models.StringField( choices=['Freshman', 'Sophomore', 'Junior', 'Senior', 'Graduate', 'Other'], label='Which year are you in?', widget=widgets.RadioSelect) risk = models.StringField( choices=['Strongly Disagree', 'Disagree', 'Slightly Disagree', 'Slightly Agree', 'Agree', 'Strongly Agree'], label='You are the person who is fully prepared to take risks.', widget=widgets.RadioSelect) decision = models.TextField(initial=None, verbose_name="How you made your decisions in Part 1?") comments = models.TextField(blank=True, initial=None, verbose_name="Do you have any comment, questions, or complains about today's experiment?") def role(self): if self.id_in_group == 1: return 'P1' if self.id_in_group == 2: return 'P2' def get_partner(self): return self.get_others_in_group()[0]