from otree.api import * import random import time doc = """ Your app description """ class C(BaseConstants): NAME_IN_URL = 'StrategyTables_Control' PLAYERS_PER_GROUP = 2 NUM_ROUNDS = 3 # N_size = 10 # this is the sample size P_yellow = [0.60, 0.40] # yellow and green box respectively p_yellow_Yellow = int(P_yellow[0] * 100) p_yellow_Green = int(P_yellow[1] * 100) # priors conditions = [(20, 20), (50, 50), (90, 90)] Payoff_task = 1.5 class Subsession(BaseSubsession): pass def make_field(label): return models.IntegerField( choices=list(range(100, -1, -1)), label=label, ) class Group(BaseGroup): pass class Player(BasePlayer): condition_prior = models.IntegerField() condition_prior_other = models.IntegerField() strategy_0 = make_field('Your Strategy:') other_strategy_0 = make_field('Expected Strategy for Participant 2:') strategy_1 = make_field('Your Strategy:') other_strategy_1 = make_field('Expected Strategy for Participant 2:') strategy_2 = make_field('Your Strategy:') other_strategy_2 = make_field('Expected Strategy for Participant 2:') strategy_3 = make_field('Your Strategy:') other_strategy_3 = make_field('Expected Strategy for Participant 2:') strategy_4 = make_field('Your Strategy:') other_strategy_4 = make_field('Expected Strategy for Participant 2:') # times time_instructions = models.IntegerField() time_answer = models.IntegerField() time_waiting = models.IntegerField() # FUNCTIONS def creating_session(subsession): import random for group in subsession.get_groups(): conditions_rounds = list(C.conditions) random.shuffle(conditions_rounds) # Shuffle the order of conditions for i, player in enumerate(group.get_players()): player.participant.conditions_rounds = conditions_rounds # Assign conditions to players def set_payoffs(group): p1 = group.get_player_by_id(1) p2 = group.get_player_by_id(2) prior_Yellow_p1 = p1.condition_prior / 100 prior_Yellow_p2 = p2.condition_prior / 100 # Participant 1-------------------------------------------------------------------------- p1_strategies = [ group.get_player_by_id(1).strategy_0, group.get_player_by_id(1).strategy_1, group.get_player_by_id(1).strategy_2, group.get_player_by_id(1).strategy_3, group.get_player_by_id(1).strategy_4, ] p1_other_strategies = [ group.get_player_by_id(1).other_strategy_0, group.get_player_by_id(1).other_strategy_1, group.get_player_by_id(1).other_strategy_2, group.get_player_by_id(1).other_strategy_3, group.get_player_by_id(1).other_strategy_4, ] # Random process: box selected and sample rand_box = random.choices(C.P_yellow, k=1, weights=[prior_Yellow_p1, 1 - prior_Yellow_p1])[0] # This is the sample that must be matched to the decision made marble_sample = random.choices([0, 1], k=group.session.config['N_size'], weights=[1 - rand_box, rand_box]) yellow_n = sum(marble_sample) # Match with decision made report = p1_strategies[yellow_n] report_other = p1_other_strategies[yellow_n] # store realization and correct guess for section 2 if p1.condition_prior == 50: if report == 50: report = rand_box # nice application of biconditional equivalences: p1.participant.correct_guess_50 = (report > 50)*(rand_box == 60) + (report < 50)*(rand_box == 40) # this variable stores if the participant had chosen correctly # Participant 2 ------------------------------------------------------------------- # all the strategies p2_strategies = [ group.get_player_by_id(2).strategy_0, group.get_player_by_id(2).strategy_1, group.get_player_by_id(2).strategy_2, group.get_player_by_id(2).strategy_3, group.get_player_by_id(2).strategy_4, ] p2_other_strategies = [ group.get_player_by_id(2).other_strategy_0, group.get_player_by_id(2).other_strategy_1, group.get_player_by_id(2).other_strategy_2, group.get_player_by_id(2).other_strategy_3, group.get_player_by_id(2).other_strategy_4, ] # Random process: box selected and sample rand_box_P2 = random.choices(C.P_yellow, k=1, weights=[prior_Yellow_p2, 1 - prior_Yellow_p2])[0] marble_sample_P2 = random.choices([0, 1], k=group.session.config['N_size'], weights=[1 - rand_box_P2, rand_box_P2]) yellow_n_P2 = sum(marble_sample_P2) # Match with decision made report_P2 = p2_strategies[yellow_n_P2] report_other_P2 = p2_other_strategies[yellow_n_P2] # store realization and correct guess for section 2 if p2.condition_prior == 50: if report == 50: report = rand_box # nice application of biconditional equivalences: p2.participant.correct_guess_50 = (report > 50)*(rand_box == 60) + (report < 50)*(rand_box == 40) # this variable stores if the participant had chosen correctly # Assign payment randomly for both participants ------------------------------------------------------- ## P1 --------------------------------- expected_diff = (report_other / 100) - (report_P2 / 100) # Assign payment prob_win = (rand_box == C.P_yellow[0]) * (1 - (1 - report / 100) ** 2) \ + (rand_box == C.P_yellow[1]) * (1 - (report / 100) ** 2) bet_result = random.choices([C.Payoff_task, 0], weights=[prob_win, 1 - prob_win], k=1)[0] bet_other_result = random.choices([C.Payoff_task, 0], k=1, weights=[1 - expected_diff ** 2, expected_diff ** 2])[0] print(yellow_n, rand_box, prob_win, expected_diff) p1.payoff = bet_result + bet_other_result # P2 ------------------------------------------ expected_diff_P2 = (report_other_P2 / 100) - (report / 100) # Assign payment prob_win_P2 = (rand_box_P2 == C.P_yellow[0]) * (1 - (1 - report_P2 / 100) ** 2) \ + (rand_box_P2 == C.P_yellow[1]) * (1 - (report_P2 / 100) ** 2) bet_result_P2 = random.choices([C.Payoff_task, 0], weights=[prob_win_P2, 1 - prob_win_P2], k=1)[0] bet_other_result_P2 = random.choices([C.Payoff_task, 0], k=1, weights=[1 - expected_diff_P2 ** 2, expected_diff_P2 ** 2])[0] print(yellow_n_P2, rand_box_P2, prob_win_P2, expected_diff_P2) p2.payoff = bet_result_P2 + bet_other_result_P2 # PAGES class PriorTest(Page): @staticmethod def vars_for_template(player): condition_prior = player.participant.conditions_rounds[player.round_number - 1][player.id_in_group - 1] condition_prior_other = player.participant.conditions_rounds[player.round_number - 1][2 - player.id_in_group] return dict( condition_prior=condition_prior, condition_prior_other=condition_prior_other, ) @staticmethod def before_next_page(player: Player, timeout_happened): player.condition_prior = player.participant.conditions_rounds[player.round_number - 1][player.id_in_group - 1] player.condition_prior_other = player.participant.conditions_rounds[player.round_number - 1][ 2 - player.id_in_group] player.time_instructions = int(time.time()) class StrategyTable(Page): form_model = 'player' form_fields = ['strategy_0', 'strategy_1', 'strategy_2', 'strategy_3', 'strategy_4', 'other_strategy_0', 'other_strategy_1', 'other_strategy_2', 'other_strategy_3', 'other_strategy_4', ] @staticmethod def is_displayed(player): return player.id_in_group == 1 @staticmethod def before_next_page(player: Player, timeout_happened): player.time_answer = int(time.time()) class StrategyTable_Other(Page): form_model = 'player' form_fields = ['strategy_0', 'strategy_1', 'strategy_2', 'strategy_3', 'strategy_4', 'other_strategy_0', 'other_strategy_1', 'other_strategy_2', 'other_strategy_3', 'other_strategy_4', ] @staticmethod def is_displayed(player): return player.id_in_group == 2 @staticmethod def before_next_page(player: Player, timeout_happened): player.time_answer = int(time.time()) class ResultsWaitPage(WaitPage): after_all_players_arrive = 'set_payoffs' @staticmethod def before_next_page(player: Player, timeout_happened): player.time_waiting = int(time.time()) page_sequence = [PriorTest, StrategyTable, StrategyTable_Other, ResultsWaitPage]