from otree.api import * from otree import currency doc = """ sasha diplomka """ def mock_get_currency_format(c: str, LO: str, CUR: str) -> str: return '# ยค' currency.get_currency_format= mock_get_currency_format def creating_session(subsession): from collections import deque print(f"round no: {subsession.round_number}") print(f"matrix before shuffling: {subsession.get_group_matrix()}") gm = subsession.get_group_matrix() transposed = list(map(list, zip(*gm))) transposed1 = deque(transposed[1]) transposed1.rotate(subsession.round_number) shifted = [transposed[0], transposed1] transposed2 = list(map(list, zip(*shifted))) subsession.set_group_matrix(transposed2) print(f"matrix after shuffling: {subsession.get_group_matrix()}") class C(BaseConstants): NAME_IN_URL = 'advisor' PLAYERS_PER_GROUP = 2 NUM_ROUNDS = 16 ADVISOR_ROLE = "Advisor" CLIENT_ROLE = "Client" GOOD_OFFER = "GOOD" MEDIUM_OFFER = "MEDIUM" BAD_OFFER = "BAD" offers = { MEDIUM_OFFER: [cu(250), cu(180)], GOOD_OFFER: [cu(180), cu(250)], BAD_OFFER: [cu(140), cu(140)] } FEE_REJECTED_PAYOFF = [110, 110] class Group(BaseGroup): sent_offer = models.StringField( choices=([[x[0], ", ".join([f"Advisor: {x[1][0]}", f"Client: {x[1][1]}"])] for x in C.offers.items()]), widget=widgets.RadioSelect, label="Select an option", ) obfuscated_offer = models.StringField() proposed_fee = models.CurrencyField( choices=[0,20,40], initial=cu(0) ) fee_accepted = models.BooleanField(initial=True) assigned_advisor = models.IntegerField() offer_accepted = models.BooleanField() realized_payoffpair = models.StringField() class Subsession(BaseSubsession): pass class Player(BasePlayer): pass # PAGES class Offer(Page): form_model = 'group' form_fields = ['sent_offer'] @staticmethod def is_displayed(player: Player): return player.role == C.ADVISOR_ROLE and player.group.fee_accepted @staticmethod def before_next_page(player, timeout_happened): import random player.group.obfuscated_offer = random.choice("ABC") advisor = player.group.get_player_by_role(C.ADVISOR_ROLE) player.group.assigned_advisor = advisor.participant.id class AcceptOffer(Page): form_model = 'group' form_fields = ['offer_accepted'] @staticmethod def is_displayed(player: Player): return player.role == C.CLIENT_ROLE and player.group.fee_accepted @staticmethod def before_next_page(player, timeout_happened): import random advisor = player.group.get_player_by_role(C.ADVISOR_ROLE) suggested_offer = player.group.sent_offer print(player.group.offer_accepted) print(advisor.id_in_subsession) if player.group.offer_accepted: print("offer accepted") player.group.realized_payoffpair = suggested_offer else: player.group.realized_payoffpair = random.choice(list(set(C.offers.keys()) - {suggested_offer})) class AllPlayersWaitPage(WaitPage): title_text = "Waiting for other players to finish the round" wait_for_all_groups = True class ResultsPage(Page): pass class WaitForOffer(WaitPage): title_text = "Waiting for advisor's proposal" @staticmethod def is_displayed(player: Player): return player.role == C.CLIENT_ROLE and player.group.fee_accepted class WaitForOfferAccept(WaitPage): title_text = "Waiting for client to accept or decline offer" @staticmethod def is_displayed(player: Player): return player.role == C.ADVISOR_ROLE and player.session.config["treatment"] == 3 @staticmethod def after_all_players_arrive(group: Group): client = group.get_player_by_role(C.CLIENT_ROLE) advisor = group.get_player_by_role(C.ADVISOR_ROLE) payof_pair = C.offers[group.realized_payoffpair] if group.fee_accepted: client.payoff = payof_pair[1] - group.proposed_fee advisor.payoff = payof_pair[0] + group.proposed_fee else: client.payoff = payof_pair[1] advisor.payoff = payof_pair[0] @staticmethod def is_displayed(player: Player): return player.role == C.ADVISOR_ROLE and player.group.fee_accepted class WaitForFee(WaitPage): title_text = "Advisor is choosing a FEE" @staticmethod def is_displayed(player: Player): return player.role == C.CLIENT_ROLE and player.session.config["treatment"] == 3 class FeePage(Page): form_model = 'group' form_fields = ['proposed_fee'] @staticmethod def is_displayed(player: Player): return player.role == C.ADVISOR_ROLE and player.session.config["treatment"] == 3 @staticmethod def before_next_page(player, timeout_happened): advisor = player.group.get_player_by_role(C.ADVISOR_ROLE) player.group.assigned_advisor = advisor.participant.id class WaitForAcceptFee(WaitPage): title_text = "Waiting for client to accept FEE" @staticmethod def is_displayed(player: Player): return player.role == C.ADVISOR_ROLE and player.session.config["treatment"] == 3 class AcceptFee(Page): form_model = 'group' form_fields = ['fee_accepted'] @staticmethod def is_displayed(player: Player): return player.role == C.CLIENT_ROLE and player.session.config["treatment"] == 3 and player.group.proposed_fee > 0 @staticmethod def before_next_page(player, timeout_happened): if player.group.fee_accepted: print("fee accepted") else: player.payoff = C.FEE_REJECTED_PAYOFF[1] player.group.get_player_by_role(C.ADVISOR_ROLE).payoff = C.FEE_REJECTED_PAYOFF[0] class RoleInfoPage(Page): @staticmethod def is_displayed(player: Player): print(player.participant.vars) return not player.participant.vars.get("role_info_shown", False) @staticmethod def before_next_page(player, timeout_happened): player.participant.vars["role_info_shown"] = True if player.role == C.ADVISOR_ROLE: player.participant.vars["is_advisor"] = True else: player.participant.vars["is_advisor"] = False page_sequence = [AllPlayersWaitPage, RoleInfoPage, FeePage, WaitForFee, AcceptFee, WaitForAcceptFee, Offer, WaitForOffer, AcceptOffer, WaitForOfferAccept, ResultsPage]