from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range, ) doc = """ Group Rent-Seeking Game. """ class Constants(BaseConstants): name_in_url = 'GroupRentSeekingDemo_1vs2' players_per_group = 3 num_rounds = 1 instructions_template = 'GroupRentSeekingDemo_1vs2/instructions.html' selectedrules_template = 'GroupRentSeekingDemo_1vs2/selectedrules.html' endowment = 750 Takara = 2880 class Subsession(BaseSubsession): def creating_session(self): if self.round_number == 1: self.group_randomly() else: self.group_like_round(1) class Group(BaseGroup): # グループ毎の合計投資量 group1_contributions = models.IntegerField() group2_contributions = models.IntegerField() is_select = models.IntegerField() random_num = models.IntegerField() winner = models.IntegerField() # 分配ルールの選択 group1_rule = models.StringField(initial='A', choices=[['A','A:[平等に分配]'], ['B','B:[相対的貢献度に応じた分配]'], ['C','C:[宝の半分は半分ずつ、残りの半分は投資額に応じて分配]']], label='' ) # 分配ルールの関数の定義(利得関数で使う用) group1_rule_A = models.IntegerField(initial=0) group1_rule_B = models.IntegerField(initial=0) group1_rule_C = models.IntegerField(initial=0) def compute(self): import random self.is_select = random.randint(1,2) #1の時はp1、2の時はp2が選択者 def set_payoffs(self): import random self.random_num = random.randint(2, 3) # 2の時はgroup2(p3)が勝利、3の時はgroup1が勝利 # role定義 players = self.get_players() p1 = self.get_player_by_id(1) p2 = self.get_player_by_id(2) p3 = self.get_player_by_id(3) # グループ別投資量合計 self.group1_contributions = p1.contribution + p2.contribution self.group2_contributions = p3.contribution # group1の勝利(id=1,id=2)の場合rate=1 利得関数で使う用 if self.group1_contributions > self.group2_contributions: self.winner = 1 elif self.group1_contributions < self.group2_contributions: self.winner = 0 elif self.group1_contributions == self.group2_contributions: self.winner = self.random_num #2or3 # 分配ルールの適用 if self.group1_rule == 'A': self.group1_rule_A = 1 elif self.group1_rule == 'B': self.group1_rule_B = 1 elif self.group1_rule == 'C': self.group1_rule_C = 1 # 利得関数(合計投資額の等しい時と等しくない時の場合分けあり) if self.group1_contributions == self.group2_contributions and self.group1_contributions == 0: p1.payoff = Constants.endowment - p1.contribution + (self.winner - 2) * (Constants.Takara /2 ) p2.payoff = Constants.endowment - p2.contribution + (self.winner - 2) * (Constants.Takara /2 ) p3.payoff = Constants.endowment - p3.contribution + (3 - self.winner) * Constants.Takara elif self.group1_contributions == self.group2_contributions: p1.payoff = Constants.endowment - p1.contribution + (self.winner - 2) * \ ((self.group1_rule_A * Constants.Takara /2 ) + (self.group1_rule_B * Constants.Takara * p1.contribution / self.group1_contributions ) + (self.group1_rule_C * (Constants.Takara /2 /2 + Constants.Takara /2 * p1.contribution / self.group1_contributions))) p2.payoff = Constants.endowment - p2.contribution + (self.winner - 2) * \ ((self.group1_rule_A * Constants.Takara /2 ) + (self.group1_rule_B * Constants.Takara * p2.contribution / self.group1_contributions ) + (self.group1_rule_C * (Constants.Takara /2 /2 + Constants.Takara /2 * p2.contribution / self.group1_contributions))) p3.payoff = Constants.endowment - p3.contribution + (3 - self.winner) * Constants.Takara else: p1.payoff = Constants.endowment - p1.contribution + self.winner * \ ((self.group1_rule_A * Constants.Takara /2 ) + (self.group1_rule_B * Constants.Takara * p1.contribution / self.group1_contributions ) + (self.group1_rule_C * (Constants.Takara /2 /2 + Constants.Takara /2 * p1.contribution / self.group1_contributions))) p2.payoff = Constants.endowment - p2.contribution + self.winner * \ ((self.group1_rule_A * Constants.Takara /2 ) + (self.group1_rule_B * Constants.Takara * p2.contribution / self.group1_contributions ) + (self.group1_rule_C * (Constants.Takara /2 /2 + Constants.Takara /2 * p2.contribution / self.group1_contributions))) p3.payoff = Constants.endowment - p3.contribution + (1 - self.winner) * Constants.Takara class Player(BasePlayer): # 投資量 contribution = models.IntegerField(initial=0, choices=[0,160,180,240,360,480,560,640,720], label='' ) # チェック contribution_check = models.StringField(initial='1', choices=[['0', '戻る(修正する)'], ['1', '次に進む']], label='前のページに戻り、修正しますか。次に進みますか。', ) rule_check = models.StringField(initial='1', choices=[['0', '戻る(修正する)'], ['1', '次に進む']], label='前のページに戻り、修正しますか。次に進みますか。', ) def role(self): if self.id_in_group == 1: return 'p1' elif self.id_in_group == 2: return 'p2' elif self.id_in_group == 3: return 'p3'