from otree.api import * c = cu doc = '' class C(BaseConstants): NAME_IN_URL = 'johns_er_game' PLAYERS_PER_GROUP = None NUM_ROUNDS = 4 COST_BLUE = 2 COST_RED = 1 class Subsession(BaseSubsession): pass class Group(BaseGroup): winning_bid1 = models.IntegerField() winning_bid2 = models.IntegerField() winning_bid3 = models.IntegerField() winning_bid4 = models.IntegerField() winner1 = models.IntegerField(initial=0) winner2 = models.IntegerField(initial=0) winner3 = models.IntegerField(initial=0) winner4 = models.IntegerField(initial=0) def pickwinner(group: Group): players = group.get_players() #Only Consider Valid Bids for player in group.get_players(): if (group.round_number / 2) == int(group.round_number / 2): #Even Round if player.bid_amount <= player.endow_red: player.validbid = player.bid_amount else: player.validbid = player.endow_red if (group.round_number / 2) != int(group.round_number / 2): #Odd Round if player.bid_amount <= player.endow_blue: player.validbid = player.bid_amount else: player.validbid = player.endow_blue #Make a List of Bids bid_list = list(player.validbid for player in players) #Pick the Four Highest Bid Amounts group.winning_bid1 = sorted(bid_list)[-1] group.winning_bid2 = sorted(bid_list)[-2] group.winning_bid3 = sorted(bid_list)[-3] group.winning_bid4 = sorted(bid_list)[-4] #Players with the Four Highest Bids win1 = [player.id_in_group for player in players if player.bid_amount == group.winning_bid1] win2 = [player.id_in_group for player in players if player.bid_amount == group.winning_bid2] win3 = [player.id_in_group for player in players if player.bid_amount == group.winning_bid3] win4 = [player.id_in_group for player in players if player.bid_amount == group.winning_bid4] win = win1 + win2 + win3 + win4 group.winner1 = win[0] group.winner2 = win[1] group.winner3 = win[2] group.winner4 = win[3] #Distribute Prizes for player in group.get_players(): if (group.round_number / 2) == int(group.round_number / 2): #even if (player.id_in_group == group.winner1) | (player.id_in_group == group.winner2) | (player.id_in_group == group.winner3) | (player.id_in_group == group.winner4): player.winnings_blue = 4 player.winnings_red = 0 else: player.winnings_blue = 0 player.winnings_red = 0 else: #odd if (player.id_in_group == group.winner1) | (player.id_in_group == group.winner2) | (player.id_in_group == group.winner3) | (player.id_in_group == group.winner4): player.winnings_blue = 0 player.winnings_red = 4 else: player.winnings_blue = 0 player.winnings_red = 0 #Bid = 0 for Players that Do Not Win for player in group.get_players(): if (player.id_in_group != group.winner1) & (player.id_in_group != group.winner2) & (player.id_in_group != group.winner3) & (player.id_in_group != group.winner4): player.finalbid = 0 else: player.finalbid = player.validbid #Compute Currency for player in group.get_players(): if group.round_number == 1: #first round player.e_blue = player.endow_blue + player.winnings_blue - player.finalbid player.e_red = player.endow_red + player.winnings_red else: #all other rounds prev_player = player.in_round(player.round_number - 1) if (group.round_number / 2) == int(group.round_number / 2): player.e_blue = prev_player.endow_blue + player.winnings_blue player.e_red = prev_player.endow_red + player.winnings_red - player.finalbid else: player.e_blue = prev_player.endow_blue + player.winnings_blue - player.finalbid player.e_red = prev_player.endow_red + player.winnings_red def compute_payoffs(group: Group): for player in group.get_players(): if (player.e_blue == 0) & (player.e_red == 0): player.payoff = 0 elif (player.e_blue == 0) & (player.e_red !=0): player.payoff = int(player.e_red/C.COST_RED) elif (player.e_blue != 0) & (player.e_red == 0): player.payoff = int(player.e_blue/C.COST_BLUE) else: player.payoff = int(player.e_blue/C.COST_BLUE) + int(player.e_red/C.COST_RED) def declare_endowments(group: Group): for player in group.get_players(): if group.round_number==1: if player.id_in_group <= 26: player.endow_blue = 40 player.endow_red = 0 else: player.endow_blue = 0 player.endow_red = 40 else: prev_player = player.in_round(player.round_number - 1) player.endow_blue = prev_player.e_blue player.endow_red = prev_player.e_red class Player(BasePlayer): bid_amount = models.IntegerField(initial=0, min=0) winnings_blue = models.IntegerField(initial=0, max=4) winnings_red = models.IntegerField(initial=4, max=0) endow_blue = models.IntegerField(initial=0) endow_red = models.IntegerField(initial=0) e_red = models.IntegerField(initial=0) e_blue = models.IntegerField(initial=0) validbid = models.IntegerField(initial=0) finalbid = models.IntegerField() class Wait_DeclareEndow(WaitPage): after_all_players_arrive = declare_endowments class Instructions(Page): form_model = 'player' @staticmethod def is_displayed(player: Player): return player.round_number == 1 class BidRED(Page): form_model = 'player' form_fields = ['bid_amount'] @staticmethod def is_displayed(player: Player): #For Odd Rounds return (player.round_number/2) != int(player.round_number / 2) class BidBLUE(Page): form_model = 'player' form_fields = ['bid_amount'] @staticmethod def is_displayed(player: Player): #For Even Rounds return (player.round_number/2) == int(player.round_number / 2) class Wait_PickWinner(WaitPage): after_all_players_arrive = pickwinner class Wait_ComputePayoffs(WaitPage): after_all_players_arrive = compute_payoffs class Results(Page): form_model = 'player' page_sequence = [Wait_DeclareEndow, Instructions, BidRED, BidBLUE, Wait_PickWinner, Wait_ComputePayoffs, Results]