from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) import random import pandas as pd import itertools import numpy as np from sklearn.utils import shuffle doc = """ This is my rendition of the ultimatum game, hopefully it works """ # This is the function I use to determine if offer was accepted or not def response(p): return True if random.random() < p else False class Constants(BaseConstants): name_in_url = 'my_ultimatum_3cond_block' players_per_group = None # num_rounds must be divisible by the number of opponents num_rounds = 240 instructions_template = 'my_ultimatum_3cond_block/Instructions.html' endowment = c(20) payoff_if_rejected = c(0) offer_increment = c(1) offer_choices = currency_range(0, endowment, offer_increment) offer_choices_count = len(offer_choices) keep_give_amounts = [] for offer in offer_choices: keep_give_amounts.append((offer, endowment - offer)) # opponent = "triangle", "circle", "square" # opponentb1 = list(opponent*(int((num_rounds/len(opponent))/2 ))) # opponentb2 = list(opponent * (int((num_rounds / len(opponent)) / 2))) # random.shuffle((opponentb1)) # random.shuffle((opponentb2)) # opponent_all = opponentb1+opponentb2 # these probabilities are directly from behavioral data of responders opponent_dict = dict(triangle = [0.0707, 0.1032, 0.1482, 0.2083, 0.2846, 0.3757, 0.4764, 0.5791, 0.6754, 0.7589, 0.8264, 0.8780, 0.9159, 0.9427, 0.9614, 0.9741, 0.9827, 0.9885, 0.9924, 0.9949, 0.9967], circle = [0.2844, 0.3839, 0.4942, 0.6051, 0.7061, 0.7902, 0.8552, 0.9026, 0.9356, 0.9579, 0.9728, 0.9825, 0.9887, 0.9928, 0.9954, 0.9971, 0.9981, 0.9988, 0.9992, 0.9995, 0.9997], square = [0.8268, 0.8855, 0.9261, 0.9530, 0.9705, 0.9816, 0.9885, 0.9929, 0.9956, 0.9973, 0.9983, 0.9990, 0.9994, 0.9996, 0.9998, 0.9998, 0.9999, 0.9999, 1.0000, 1.0000, 1.0000]) opponent = "triangle", "circle", "square" opponentb1 = list(opponent*(int((Constants.num_rounds/len(opponent))/2 ))) opponentb2 = list(opponent * (int((Constants.num_rounds / len(opponent)) / 2))) random.shuffle((opponentb1)) random.shuffle((opponentb2)) opponent_all = opponentb1+opponentb2 class Subsession(BaseSubsession): pass class Group(BaseGroup): amount_offered = models.CurrencyField(widget=widgets.RadioSelect(), choices=Constants.offer_choices) current_opponent = models.CharField() payout = models.IntegerField() soc_or_no = models.CharField() def set_responder_identity(self): self.current_opponent = opponent_all[self.round_number-1] offer_accepted = models.BooleanField() def set_payoffs(self): self.offer_accepted = response(Constants.opponent_dict[self.current_opponent][int(self.amount_offered)]) if self.offer_accepted: Player.payoff = Constants.endowment - self.amount_offered self.payout = Constants.endowment - self.amount_offered else: Player.payoff = Constants.payoff_if_rejected self.payout = Constants.payoff_if_rejected class Player(BasePlayer): final_payout = models.CurrencyField() trial_to_pay = models.IntegerField() amount_earned_on_priors_nonsocial = models.IntegerField() amount_earned_total = models.IntegerField() def round_to_pay(self): self.round_list = range(1, self.round_number + 1) self.payout_chosen_trial = shuffle(self.round_list) # self.participant.vars['payout_chosen_trial'] = self.payout_chosen_trial[0] self.participant.vars['payout_chosen_trial'] = random.choice(range(1, self.round_number + 1)) self.trial_to_pay = self.participant.vars['payout_chosen_trial'] self.participant.vars['payout_UG'] = self.group.in_round(self.trial_to_pay).payout self.amount_earned_on_priors_nonsocial = self.participant.vars['payout_UG'] # self.amount_earned_total = self.participant.vars['payout_UG'] + self.participant.vars[ # 'payout_social_priors'] def calculate_final_payout(self): self.final_payout = 0.125 * (self.participant.vars['payout_UG'] + self.participant.vars['risk_payout'] + self.participant.vars['payout_dictator'] + self.participant.vars['payout_social_priors']) # this is commented out because I'm not sure if I should pay them for both prior estimation sessions or just 1 # + self.participant.vars['payout_nonsocial_priors'] test_question_1 = models.CharField( choices=('TRUE', 'FALSE'), widget=widgets.RadioSelect() ) test_question_2 = models.CharField( choices=('TRUE', 'FALSE'), widget=widgets.RadioSelect() ) test_question_3 = models.CharField( choices=('TRUE', 'FALSE'), widget=widgets.RadioSelect() ) test_question_4 = models.CharField( choices=('TRUE', 'FALSE'), widget=widgets.RadioSelect() )