from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range, ) from .Stage3Game import Stage3Game import random author = 'Your name here' doc = """ Your app description """ class Constants(BaseConstants): name_in_url = 'stage3_T5' players_per_group = 4 num_rounds = 20 num_games = 10 class Subsession(BaseSubsession): def update_grouping(self): all_subessions = self.in_rounds(1, Constants.num_rounds) for idx, subsession in enumerate(all_subessions): players = subsession.get_players() for player in players: player.slider_value = player.participant.vars['slider_value'] players.sort(key=lambda player: player.slider_value) yellowGroup = players[:Constants.players_per_group] redGroup = players[Constants.players_per_group:] subsession.set_group_matrix([yellowGroup, redGroup]) #init Stage3Game instance game = Stage3Game(self) self.session.vars['Stage3Game'] = game print('stage 3: ', self.session.vars) for idx, subsession in enumerate(all_subessions): for group in subsession.get_groups(): for player in group.get_players(): pairing = game.participant_game_sequence_dict[player.participant][idx] group = player.group.id_in_subsession if group == 1: player.cooparticipant_group = group if pairing.is_in_group == True else 2 else: player.cooparticipant_group = group if pairing.is_in_group == True else 1 player.is_in_group = pairing.is_in_group def get_other_player(self, is_first_mover, pairing_uuid): players = Player.objects.filter(pairing_uuid=pairing_uuid) for player in players: if not is_first_mover == player.is_first_mover: return player return None def assign_stage3_earning(self, game_number, is_in_group): players = Player.objects.filter(game_number=game_number).filter(is_in_group=is_in_group).filter(session=self.session) print(len(players)) for player in players: player.participant.vars['Stage3Earning']= { 'Earning': player.game_payoff, 'Round': player.round_number, 'Game_number': game_number } def update_payoff(self): game = self.session.vars['Stage3Game'] all_subsessions = self.in_rounds(1, Constants.num_rounds) for index, subsession in enumerate(all_subsessions): for player in subsession.get_players(): other_player = self.get_other_player(player.is_first_mover, player.pairing_uuid) first_mover_player = player if player.is_first_mover else other_player second_mover_player = other_player if player.is_first_mover else player print('is unique id equal: ', player.pairing_uuid == other_player.pairing_uuid) player.game_payoff = game.get_payoff( first_mover_player, second_mover_player, player.is_first_mover ) self.assign_stage3_earning(game.chosen_game_number, game.chosen_in_out_group) # if index == Constants.num_rounds-1: # random_round = random.randint(1, Constants.num_rounds) # player.participant.vars['Stage3Earning'] = { # 'Earning': player.in_round(random_round).game_payoff, # 'Round': random_round # } class Group(BaseGroup): pass class Player(BasePlayer): slider_value = models.IntegerField() # True for first mover, False for second mover is_first_mover = models.BooleanField() # pairing uuid. this is to track the pairing for the game played pairing_uuid = models.StringField() # whether game is in group or out group is_in_group = models.BooleanField() # game number. this is to track the game number which the player played game_number = models.IntegerField() # game payoff. this is to track the payoff of the player for this game, # will be assigned at the end of stage 3 game_payoff = models.IntegerField() # decision choice (for first movers): 1 for A, 2 for B choice = models.IntegerField() # decision choice (for second movers) choice_if_A = models.IntegerField() choice_if_B = models.IntegerField() cooparticipant_group = models.IntegerField() # control questionnaire 2 question1 = models.IntegerField(widget=widgets.RadioSelect, choices=[ [1, 'a. True'], [2, 'b. False'] ]) question1_wrong_count = models.IntegerField(initial=0) question2 = models.IntegerField(widget=widgets.RadioSelect, choices=[ [1, 'a. Choose between A or B'], [2, 'b. Choose between A or B when second mover has chosen A'], [3, 'c. Choose between A or B when second mover has chosen B'], [4, 'd. Both b and c are correct'], ]) question2_wrong_count = models.IntegerField(initial=0) question3 = models.IntegerField(widget=widgets.RadioSelect, choices=[ [1, 'a. Choose between A or B'], [2, 'b. Choose between A or B when second mover has chosen A'], [3, 'c. Choose between A or B when second mover has chosen B'], [4, 'd. Both b and c are correct'], ]) question3_wrong_count = models.IntegerField(initial=0) question4 = models.IntegerField(widget=widgets.RadioSelect, choices=[ [1, 'a. 1'], [2, 'b. 2'], [3, 'c. 3'], [4, 'd. 4'], ]) question4_wrong_count = models.IntegerField(initial=0) question5 = models.IntegerField(widget=widgets.RadioSelect, choices=[ [1, 'a. 4'], [2, 'b. 5'], [3, 'c. 6'], [4, 'd. 7'], ]) question5_wrong_count = models.IntegerField(initial=0) question6 = models.IntegerField(widget=widgets.RadioSelect, choices=[ [1, 'a. I will be paid for the points I earn in every round'], [2, 'b. I will be paid for the points I earn in one round'], [3, 'c. I will not know which round I will be paid for until the end of the experiment'], [4, 'd. This round is randomly determined by the computer'], [5, 'e. The coparticipant I am matched with is randomly determined in each round '] ]) question6_wrong_count = models.IntegerField(initial=0) question7 = models.IntegerField(widget=widgets.RadioSelect, choices=[ [1, 'a. S$10'], [2, 'b. S$20'], [3, 'c. S$30'], [4, 'd. S$40'] ]) question7_wrong_count = models.IntegerField(initial=0) def question1_error_message(self, value): if value != 1: self.question1_wrong_count += 1 return 'Wrong choice' def question2_error_message(self, value): if value != 1: self.question2_wrong_count += 1 return 'Wrong choice' def question3_error_message(self, value): if value != 4: self.question3_wrong_count += 1 return 'Wrong choice' def question4_error_message(self, value): if value != 3: self.question4_wrong_count += 1 return 'Wrong choice' def question5_error_message(self, value): if value != 1: self.question5_wrong_count += 1 return 'Wrong choice' def question6_error_message(self, value): if value != 1: self.question6_wrong_count += 1 return 'Wrong choice' def question7_error_message(self, value): if value != 2: self.question7_wrong_count += 1 return 'Wrong choice' def custom_export(players): # header row yield ['session', 'participant_code', 'participant_id', 'round_number', 'group_number', 'role', 'q1 wrong count', 'q2 wrong count', 'q3 wrong count', 'q4 wrong count', 'q5 wrong count', 'q6 wrong count', 'q7 wrong count', 'pairing uuid', 'game number', 'first player choice', 'second player choice if A', 'second player choice if B', 'game payoff', 'cooparticipant group'] for p in players: role = 'first mover' if p.is_first_mover == True else 'second mover' if p.is_first_mover: role = 'first mover' first_mover_choice = 'A' if p.choice == 1 else 'B' second_mover_choice_ifA = None second_mover_choice_ifB = None else: role = 'second mover' first_mover_choice = None second_mover_choice_ifA = 'A' if p.choice_if_A == 1 else 'B' second_mover_choice_ifB = 'A' if p.choice_if_B == 1 else 'B' yield [p.session.code, p.participant.code, p.participant.id_in_session, p.round_number, p.group.id_in_subsession, role, p.question1_wrong_count, p.question2_wrong_count, p.question3_wrong_count, p.question4_wrong_count, p.question5_wrong_count, p.question6_wrong_count, p.question7_wrong_count, p.pairing_uuid, p.game_number, first_mover_choice, second_mover_choice_ifA, second_mover_choice_ifB, p.game_payoff, p.cooparticipant_group]