from otree.api import * import random import math def random_pick(type_list, probabilities): x = random.uniform(0, 1) cumulative_probability = 0.0 for item, item_probability in zip(type_list, probabilities): cumulative_probability += item_probability if x < cumulative_probability: break return item type_list = ['L型', 'H型'] probabilities = [0.7, 0.3] seller_list = ['seller_1', 'seller_2'] class C(BaseConstants): NAME_IN_URL = 'projectso' PLAYERS_PER_GROUP = 3 NUM_ROUNDS = 3 INSTRUCTIONS_TEMPLATE = 'projectso/instructions.html' participation_fee = cu(10) price_h = cu(120) cost_h = cu(80) price_l = cu(80) cost_l = cu(60) value = cu(140) search_cost = cu(10) seller_1_ROLE = 'seller_1' seller_2_ROLE = 'seller_2' buyer_ROLE = 'buyer' round_chosen = random.randint(1, NUM_ROUNDS) # understanding answers question1_answer = 60 question2_answer = 20 question3_answer = 0 question4_answer = 50 question5_answer = 0 question6_answer = 20 question7_answer = 10 question8_answer = 0 question9_answer = 40 def creating_session(subsession): subsession.group_randomly(fixed_id_in_group=True) subsession.buyer_type = random_pick(type_list, probabilities) class Subsession(BaseSubsession): buyer_type = models.StringField() num_round_chosen = models.IntegerField() search_cost_value = models.CurrencyField() def understanding(label): return models.IntegerField( min=0, max=999, label=label, ) class Group(BaseGroup): offer_l_1 = models.IntegerField( choices=[ [1, 'A产品'], [2, 'B产品'], ], label='请选择你想要提供的产品', widget=widgets.RadioSelect, initial=99, ) offer_h_1 = models.IntegerField( choices=[ [2, 'B产品'], ], label='请选择你想要提供的产品', widget=widgets.RadioSelect, initial=99, ) offer_h_2 = models.IntegerField( choices=[ [2, 'B产品'], ], label='请选择你想要提供的产品', widget=widgets.RadioSelect, initial=99, ) offer_l_2 = models.IntegerField( choices=[ [1, 'A产品'], [2, 'B产品'], ], label='请选择你想要提供的产品', widget=widgets.RadioSelect, initial=99, ) accept = models.IntegerField( choices=[ [1, '接受'], [0, '不接受'], ], label='请选择你是否接受卖方1提供的产品', widget=widgets.RadioSelect, initial=99, ) def switching_role(group): p1 = group.get_player_by_id(1) p2 = group.get_player_by_id(2) p3 = group.get_player_by_id(3) p1.role_actual = random.choice(seller_list) if p1.role_actual == C.seller_1_ROLE: p2.role_actual = C.seller_2_ROLE p3.role_actual = C.buyer_ROLE else: p2.role_actual = C.seller_1_ROLE p3.role_actual = C.buyer_ROLE class Player(BasePlayer): # understanding questions question1_entered = understanding('若买方的类型为L型,卖方1提供的产品为A产品,买方选择接受,则买方的收益为') question2_entered = understanding('此时卖方1收益为') question3_entered = understanding('此时卖方2收益为') question4_entered = understanding('若买方的类型为L型,卖方1提供的产品为B产品,买方选择不接受,卖方2提供的产品为A产品,则买方的收益为') question5_entered = understanding('此时卖方1收益为') question6_entered = understanding('此时卖方2收益为') question7_entered = understanding('若买方的类型为H型,卖方1提供的产品为B产品,买方选择不接受,卖方2提供的产品为B产品,则买方的收益为') question8_entered = understanding('此时卖方1收益为') question9_entered = understanding('此时卖方2收益为') final_payoff = models.CurrencyField() payoffs = models.CurrencyField() role_actual = models.StringField() def payoff(group: Group): group.subsession.search_cost_value = C.search_cost group.subsession.num_round_chosen = C.round_chosen for p in group.get_players(): if p.role_actual == C.seller_1_ROLE: if group.accept == 1: p.payoffs = C.price_l - C.cost_l if group.offer_l_1 == 1 else C.price_h - C.cost_h else: p.payoffs = cu(0) elif p.role_actual == C.seller_2_ROLE: if group.accept == 1: p.payoffs = cu(0) else: p.payoffs = C.price_l - C.cost_l if group.offer_l_2 == 1 else C.price_h - C.cost_h else: if group.accept == 1: p.payoffs = C.value - C.price_l if group.offer_l_1 == 1 else C.value - C.price_h else: p.payoffs= C.value - C.price_l - C.search_cost if group.offer_l_2 == 1 else C.value - C.price_h - C.search_cost class Introduction(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 class instructions(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 class task(Page): form_model = 'player' form_fields = ['question1_entered', 'question2_entered', 'question3_entered', 'question4_entered', 'question5_entered', 'question6_entered', 'question7_entered', 'question8_entered', 'question9_entered'] @staticmethod def error_message(player, values): if values['question1_entered'] != C.question1_answer: return '计算有误,请仔细检查并更正!' if values['question2_entered'] != C.question2_answer: return '计算有误,请仔细检查并更正!' if values['question3_entered'] != C.question3_answer: return '计算有误,请仔细检查并更正!' if values['question4_entered'] != C.question4_answer: return '计算有误,请仔细检查并更正!' if values['question5_entered'] != C.question5_answer: return '计算有误,请仔细检查并更正!' if values['question6_entered'] != C.question6_answer: return '计算有误,请仔细检查并更正!' if values['question7_entered'] != C.question7_answer: return '计算有误,请仔细检查并更正!' if values['question8_entered'] != C.question8_answer: return '计算有误,请仔细检查并更正!' if values['question9_entered'] != C.question9_answer: return '计算有误,请仔细检查并更正!' @staticmethod def is_displayed(player: Player): return player.round_number == 1 class UnderstandingWait(WaitPage): after_all_players_arrive = 'switching_role' class RoleAssign(Page): @staticmethod def is_displayed(player: Player): return player.round_number <= C.NUM_ROUNDS class Offer_h_1(Page): form_model = 'group' form_fields = ['offer_h_1'] @staticmethod def is_displayed(player: Player): return player.role_actual == C.seller_1_ROLE and player.subsession.buyer_type == 'H型' class Offer_l_1(Page): form_model = 'group' form_fields = ['offer_l_1'] @staticmethod def is_displayed(player: Player): return player.role_actual == C.seller_1_ROLE and player.subsession.buyer_type == 'L型' class AcceptWaitPage(WaitPage): pass class Accept(Page): form_model = 'group' form_fields = ['accept'] @staticmethod def is_displayed(player: Player): return player.role_actual == C.buyer_ROLE class OfferWaitPage_1(WaitPage): pass class Offer_h_2(Page): form_model = 'group' form_fields = ['offer_h_2'] @staticmethod def is_displayed(player: Player): return player.role_actual == C.seller_2_ROLE and player.group.accept == 0 and player.subsession.buyer_type == 'H型' class Offer_l_2(Page): form_model = 'group' form_fields = ['offer_l_2'] @staticmethod def is_displayed(player: Player): return player.role_actual == C.seller_2_ROLE and player.group.accept == 0 and player.subsession.buyer_type == 'L型' class ResultsWaitPage(WaitPage): after_all_players_arrive = 'payoff' class Round_Results(Page): pass class RoundWaitPage(WaitPage): wait_for_all_groups = True @staticmethod def is_displayed(player: Player): return player.round_number == C.NUM_ROUNDS class Results(Page): @staticmethod def vars_for_template(player: Player): player_in_chosen_round = player.in_round(C.round_chosen) player.role_in_chosen_round = player_in_chosen_round.role_actual player.final_payoff = player_in_chosen_round.payoffs @staticmethod def is_displayed(player: Player): return player.round_number == C.NUM_ROUNDS page_sequence = [Introduction, instructions, UnderstandingWait, RoleAssign, Offer_h_1, Offer_l_1, AcceptWaitPage, Accept, OfferWaitPage_1, Offer_h_2, Offer_l_2, ResultsWaitPage, Round_Results, RoundWaitPage, Results]