from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) import random doc = """ This anticommons game involves 3 players: 2 sellers and 1 buyer. The sellers together own one 4-piece puzzle. The buyer wants to buy it from the sellers, as it has a certain value for him/her. """ class Constants(BaseConstants): name_in_url = 'anticommons_sequential' players_per_group = 3 # if you change this, also change the quiz question about number of players!!! num_rounds = 1 # if you change this, also change the quiz question about number of rounds!!! value_puzzle = buyer_endowment = c(20) # if you change this, also change the quiz question about the value of the puzzle!! max_wtp = c(buyer_endowment/2) class Subsession(BaseSubsession): def creating_session(self): for p in self.get_players(): p.treatment = self.session.config['treatment'] for g in self.get_groups(): if (self.round_number % 2) == 1: g.order = 1 if (self.round_number % 2) == 0: g.order = 2 class Group(BaseGroup): order = models.IntegerField() WTP1 = models.CurrencyField() WTP2 = models.CurrencyField() WTA1 = models.CurrencyField() WTA2 = models.CurrencyField() def first_deal(self): buyer = self.get_player_by_id(1) seller1 = self.get_player_by_id(2) seller2 = self.get_player_by_id(3) if buyer.order == 1: if seller1.WTA <= buyer.WTP1: buyer.first_deal = True else: buyer.first_deal = False if buyer.order == 2: if seller2.WTA <= buyer.WTP2: buyer.first_deal = True else: buyer.first_deal = False seller1.first_deal = seller2.first_deal = buyer.first_deal self.WTP1 = buyer.WTP1 self.WTP2 = buyer.WTP2 self.WTA1 = seller1.WTA self.WTA2 = seller2.WTA def set_payoffs(self): buyer = self.get_player_by_id(1) seller1 = self.get_player_by_id(2) seller2 = self.get_player_by_id(3) if seller1.WTA <= buyer.WTP1: seller1.payoff = seller1.WTA seller1.sell = True buyer.buy1 = True else: seller1.payoff = c(0) seller1.sell = False buyer.buy1 = False if seller2.WTA <= buyer.WTP2: seller2.payoff = seller2.WTA seller2.sell = True buyer.buy2 = True else: seller2.payoff = c(0) seller2.sell = False buyer.buy2 = False if seller1.sell == True & seller2.sell == True: buyer.payoff = Constants.buyer_endowment + Constants.value_puzzle - seller1.WTA - seller2.WTA buyer.success = seller1.success = seller2.success = True else: buyer.payoff = Constants.buyer_endowment - seller1.payoff - seller2.payoff buyer.success = seller1.success = seller2.success = False if buyer.payoff < c(0): buyer.payoff = c(0) else: buyer.payoff = buyer.payoff if seller1.payoff < c(0): seller1.payoff = c(0) else: seller1.payoff = seller1.payoff if seller2.payoff < c(0): seller2.payoff = c(0) else: seller2.payoff = seller2.payoff class Player(BasePlayer): treatment = models.IntegerField() treatmentname = models.StringField() position = models.StringField() order = models.IntegerField() first_deal = models.BooleanField() quiz_1 = models.CharField( choices=["1 participant", "2 participants", "3 participants", "4 participants"], widget=widgets.RadioSelect) quiz_2 = models.CharField( choices=["10 rounds", "20 rounds", "30 rounds", "40 rounds"], widget=widgets.RadioSelect) quiz_3 = models.CharField( choices=["The Buyer will then not earn a monetary bonus.", "The Buyer will then earn a monetary bonus of 20 points.", "I have not been informed about how many points the Buyer will earn then."], widget=widgets.RadioSelect) quiz_4 = models.CharField( choices=["The Buyer will then not earn a monetary bonus.", "The Buyer will then earn a monetary bonus of 20 points.", "I have not been informed about how many points the Buyer will earn then."], widget=widgets.RadioSelect) quiz_5 = models.CharField( choices=["That Seller will then earn the number of points he/she asked for his/her part of the puzzle.", "That Seller will then earn zero points in that round.", "I have not been informed about how many points that Seller will earn then."], widget=widgets.RadioSelect) quiz_6 = models.CharField( choices=["That Seller will then earn the number of points he/she asked for his/her part of the puzzle.", "That Seller will then earn zero points in that round.", "I have not been informed about how many points that Seller will earn then."], widget=widgets.RadioSelect) motive_1 = models.IntegerField( choices=[1, 2, 3, 4, 5, 6, 7], widget=widgets.RadioSelectHorizontal) motive_2 = models.IntegerField( choices=[1, 2, 3, 4, 5, 6, 7], widget=widgets.RadioSelectHorizontal) motive_3 = models.IntegerField( choices=[1, 2, 3, 4, 5, 6, 7], widget=widgets.RadioSelectHorizontal) motive_4 = models.IntegerField( choices=[1, 2, 3, 4, 5, 6, 7], widget=widgets.RadioSelectHorizontal) motive_5 = models.IntegerField( choices=[1, 2, 3, 4, 5, 6, 7], widget=widgets.RadioSelectHorizontal) motive_6 = models.IntegerField( choices=[1, 2, 3, 4, 5, 6, 7], widget=widgets.RadioSelectHorizontal) motive_7 = models.IntegerField( choices=[1, 2, 3, 4, 5, 6, 7], widget=widgets.RadioSelectHorizontal) motive_8 = models.IntegerField( choices=[1, 2, 3, 4, 5, 6, 7], widget=widgets.RadioSelectHorizontal) WTA = models.CurrencyField( min=0, max=(Constants.value_puzzle), doc="Amount asked by the Seller" ) WTP1 = models.CurrencyField(min=0, doc="Amount offered by the buyer to Seller A") WTP2 = models.CurrencyField(min=0, doc="Amount offered by the buyer to Seller B") def WTP1_max(self): if self.group.order == 1: return Constants.value_puzzle if self.group.order == 2: if self.first_deal == True: return (Constants.value_puzzle - self.group.WTA2) if self.first_deal == False: return Constants.value_puzzle def WTP2_max(self): if self.group.order == 1: if self.first_deal == True: return (Constants.value_puzzle - self.group.WTA1) if self.first_deal == False: return Constants.value_puzzle if self.group.order == 2: return Constants.value_puzzle buyer_endowment = models.CurrencyField() value_puzzle = models.CurrencyField() buy1 = models.BooleanField() buy2 = models.BooleanField() sell = models.BooleanField() success = models.BooleanField() numberofpieces = models.StringField() spent = models.CurrencyField() def other_player(self): """Returns the opponent of the current player""" return self.get_others_in_group()[0] def role(self): if self.id_in_group == 1: return 'Buyer' if self.id_in_group == 2: return 'Seller A' if self.id_in_group == 3: return 'Seller B'