from otree.api import * c = cu doc = '' class C(BaseConstants): NAME_IN_URL = 'foodloss_practice' PLAYERS_PER_GROUP = 5 NUM_ROUNDS = 3 OBENTO_SHOKICHI = 8 class Subsession(BaseSubsession): treatment = models.IntegerField() def creating_session(subsession: Subsession): session = subsession.session subsession.treatment=2 import random tmp = random.sample(list(range(1, C.PLAYERS_PER_GROUP+1)),C.PLAYERS_PER_GROUP) for p in subsession.get_players(): p.Order = tmp[p.id_in_group-1] class Group(BaseGroup): Zansu = models.IntegerField() Price = models.IntegerField() initial_zansu = models.IntegerField() def money_calc(group: Group): for player in group.get_players(): if player.round_number==1: player.money=1000 group.Zansu=C.OBENTO_SHOKICHI group.Price=400 group.initial_zansu=C.OBENTO_SHOKICHI player.finished=0 else: player.money = player.in_round(player.round_number-1).money group.Zansu=group.in_round(group.round_number-1).Zansu group.initial_zansu=group.in_round(group.round_number-1).Zansu price_list=[400,300,700] group.Price = price_list[player.round_number-1] if (player.money<=50 or group.Zansu<=0): player.finished=1 else: player.finished=0 def Zansuu_calc(group: Group): players = group.get_players() Obento = [player.Ch2 for player in players] # お弁当に余裕がある場合とない場合で分けて、買えた個数Boughtを計算する。 # はじめは、全員が買いたい個数を買っても余裕がある場合。 if sum(Obento)Residualならば、Residualだけ買う」っていう計算ができる。 for p in players: Residual = group.Zansu - sum(buy_list[1:p.Order]) if Residual > 0: p.Bought = min(p.Ch2, Residual) else: p.Bought = 0 # 次の forループは、お金の残額を計算することと、獲得ポイント(残り所持金+お弁当購入から得られる便益を計算したもの) for p in players: p.money=p.money-p.Bought*group.Price p.points = p.money + sum([i.Bought for i in p.in_all_rounds()]) * 700 # やっと最後。この期が終わった段階での残数を計算する。 group.Zansu=group.Zansu-sum(Obento) class Player(BasePlayer): Choice = models.IntegerField(choices=[[1, '行く'], [0, '行かない']], label='選択', widget=widgets.RadioSelect) money = models.IntegerField() Ch2 = models.IntegerField(label='購入数', min=0) Canbuy = models.IntegerField() Order = models.IntegerField() Bought = models.IntegerField() points = models.IntegerField() finished = models.IntegerField() def deduct_50(player: Player): group = player.group player.money=player.money-player.Choice*50 player.Canbuy=player.money//group.Price if player.Choice == 0: player.Ch2 = 0 def Ch2_max(player: Player): return player.Canbuy class WaitPage1(WaitPage): after_all_players_arrive = money_calc class Introduction(Page): form_model = 'player' @staticmethod def is_displayed(player: Player): return player.round_number == 1 class Cannotgo(Page): form_model = 'player' @staticmethod def is_displayed(player: Player): return player.finished==1 @staticmethod def before_next_page(player: Player, timeout_happened): player.Choice=0 player.Ch2=0 class Go(Page): form_model = 'player' form_fields = ['Choice'] @staticmethod def is_displayed(player: Player): return player.finished==0 @staticmethod def before_next_page(player: Player, timeout_happened): deduct_50(player) class Buy(Page): form_model = 'player' form_fields = ['Ch2'] @staticmethod def is_displayed(player: Player): return player.Choice==1 class WaitPage2(WaitPage): after_all_players_arrive = Zansuu_calc class Result_Buy(Page): form_model = 'player' class Finished(Page): form_model = 'player' @staticmethod def is_displayed(player: Player): return player.round_number==C.NUM_ROUNDS page_sequence = [WaitPage1, Introduction, Cannotgo, Go, Buy, WaitPage2, Result_Buy, Finished]