from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) import random doc = '' class Constants(BaseConstants): name_in_url = 'BC_AIG' players_per_group = 3 num_rounds = 4 jackpot = c(6) guess_max = 100 instructions_aig_template = 'BC_AIG/instructions_aig.html' instructions_basic_template = 'BC_AIG/instructions_basic.html' instructions_chat_template = 'BC_AIG/instructions_chat.html' class Subsession(BaseSubsession): two_thirds_avg = models.FloatField(initial=0) num_winners = models.IntegerField() best_guess = models.FloatField() def calc_payoffs(self): groups = self.get_groups() guesses = [] for g in groups: if g.group_guess <= Constants.guess_max: guesses.append(g.group_guess) else: print("101 von der Gruppe") two_thirds_avg = (2 / 3) * (sum(guesses) / len(guesses)) self.two_thirds_avg = round(two_thirds_avg, 2) self.best_guess = min( guesses, key=lambda guess: abs(guess - self.two_thirds_avg) ) winners = [] for g in groups: if g.group_guess == self.best_guess: winners.append(g) self.num_winners = len(winners) for g in winners: g.is_winner = True g.payoff = Constants.jackpot / self.num_winners def two_thirds_avg_history(self): return [s.two_thirds_avg for s in self.in_previous_rounds()] def set_groups(self): ''' Assigns Participants to a group on a random basis. Replaces the round page used in: GroupDissWaitPage ''' if self.round_number == 1: self.group_randomly(fixed_id_in_group = False) else: self.group_like_round(1) class Group(BaseGroup): is_winner = models.BooleanField(initial=False) payoff = models.CurrencyField(initial=0, min=0) group_guess = models.FloatField(initial=101, min=0) status = models.IntegerField(initial=0) temp_guess = models.FloatField(initial=101) def dis_payoff(self): winners = self.get_players() for p in winners: p.p_payoff += (self.payoff / len(winners)) def set_payoff(self): self.subsession.calc_payoffs() # status 0: isLive check # status 1: not enough players start # status 2: enough players start def live_guess(self, id_in_group, input): if input[0] == "l": player = self.get_player_by_id(id_in_group) if player.is_live == -1: player.is_live = 1 num_players = 0 for ply in self.get_players(): if ply.is_live == 1: num_players += 1 if num_players == 3: rndm = random.randint(1,3) for ply in self.get_players(): if ply.id_in_group == rndm: ply.is_dealer = 1 ply.is_judge = 0 else: ply.is_dealer = 0 ply.is_judge = 1 #start deal self.status = 1 broadcast = {"case" : 2, "dealer" : rndm,"notLive" : [], "value" : ""} print("3") return {0: broadcast} elif self.status != 0: for ply in self.get_players(): if ply.id_in_group == id_in_group: ply.is_live = -1 broadcast = {"case" : 0, "dealer" : "","notLive" : [], "value" : ""} else: #pls wait broadcast = {"case" : 1, "dealer" : "","notLive" : [], "value" : ""} print("2") return {id_in_group: broadcast} else: print("1") return {} #_____________________________________________________________________________ elif input[0] =="s": if self.status != 0: return {} else: notLive = [] for ply in self.get_players(): if ply.is_live == -1: notLive.append(ply.id_in_group) ply.is_live = 0 #1Person active if len(notLive) == 2: dlr = 0 for ply2 in self.get_players(): if ply2.is_live == 1: ply2.is_dealer = 1 ply2.is_judge = 0 dlr = ply2.id_in_group #start deal self.status = 1 broadcast = {"case" : 2, "dealer" : dlr,"notLive" : notLive, "value" : ""} return {0: broadcast} #2Persons active elif len(notLive) == 1: dlr = 0 for ply3 in self.get_players(): if ply3.is_live == 1: if dlr == 0: ply3.is_dealer = 1 ply3.is_judge = 0 dlr= ply3.id_in_group else: ply3.is_dealer = 0 ply3.is_judge = 1 #start deal self.status = 1 broadcast = {"case" : 2, "dealer" : dlr,"notLive" : notLive, "value" : ""} return {0: broadcast} #noPerson active elif len(notLive) == 3: self.group_guess = 101 # Whatever ends the programm self.status = 3 return{} else: return{} #_____________________________________________________________________________ elif input[0] == "v": print(f'v recieved, status{self.status}') if self.status == 1: self.temp_guess = float(input[1]) dlr = 0 i = 0 players = self.get_players() for ply in players: if ply.is_live == 1: i += 1 if ply.is_dealer == 1: dlr = ply.id_in_group if i == 1: self.group_guess = self.temp_guess self.status = 3 broadcast = {"case" : 6, "dealer" : "","notLive" : "", "value" : self.group_guess} return {0: broadcast} else: #start check self.status = 2 broadcast = {"case" : 3, "dealer" : dlr,"notLive" : "", "value" : self.temp_guess} return {0: broadcast} else: return{} #_____________________________________________________________________________ elif input[0] =="y": if self.status == 2: players = self.get_players() i = 2 n = 0 for ply in players: if ply.id_in_group == id_in_group: ply.opinion = 1 if ply.is_live == 1: n += 1 if ply.is_judge == 1 and ply.id_in_group != id_in_group: if ply.opinion == 0: i = 0 elif ply.opinion == 1: i = 1 print(f'Yes{i}') if n == 3: if i == 1: self.group_guess = self.temp_guess self.status = 3 broadcast = {"case" : 6, "dealer" : "","notLive" : "", "value" : self.group_guess} return {0: broadcast} elif i == 0: dlr = 0 for ply2 in players: ply2.opinion = -1 if ply2.is_dealer == 1: dlr = ply2.id_in_group self.status = 1 broadcast = {"case" : 5, "dealer" : dlr,"notLive" : "", "value" : ""} return {0: broadcast} else: broadcast = {"case" : 4, "dealer" : "","notLive" : "", "value" : ""} return {id_in_group: broadcast} elif n == 2: self.group_guess = self.temp_guess self.status = 3 broadcast = {"case" : 6, "dealer" : "","notLive" : "", "value" : self.group_guess} return {0: broadcast} else: return{} #_____________________________________________________________________________ elif input[0] =="n": if self.status == 2: players = self.get_players() i = 2 n = 0 for ply in players: if ply.id_in_group == id_in_group: ply.opinion = 0 if ply.is_live == 1: n += 1 if ply.is_judge == 1 and ply.id_in_group != id_in_group: if ply.opinion == 0: i = 0 elif ply.opinion == 1: i = 1 print(f'No{i}') if n == 3: if i == 1 or i == 0: dlr = 0 for ply2 in players: ply2.opinion = -1 if ply2.is_dealer == 1: dlr = ply2.id_in_group self.status = 1 broadcast = {"case" : 5, "dealer" : dlr,"notLive" : "", "value" : ""} return {0: broadcast} else: broadcast = {"case" : 4, "dealer" : "","notLive" : "", "value" : ""} return {id_in_group: broadcast} elif n == 2: dlr = 0 for ply2 in players: ply2.opinion = -1 if ply2.is_dealer == 1: dlr = ply2.id_in_group self.status = 1 broadcast = {"case" : 5, "dealer" : dlr,"notLive" : "", "value" : ""} return {0: broadcast} else: return{} class Player(BasePlayer): guess_before_discussion = models.FloatField(blank=True, initial=101, max=Constants.guess_max, min=0) guess = models.FloatField(blank=True, initial=101, max=Constants.guess_max, min=0) is_winner = models.BooleanField(initial=False) p_payoff = models.CurrencyField(initial=0, min=0) vp_alter = models.StringField(initial='') vp_gender = models.StringField(choices=[['m', 'männlich'], ['w', 'weiblich'], ['d', 'divers']], initial='', widget=widgets.RadioSelect) vp_code = models.StringField(initial='') vp_stunden = models.StringField(choices=[['vph', '1 VP-Stunde'], ['geld', '4€ Teilnehmerbetrag']], widget=widgets.RadioSelect) vp_complCode = models.StringField(initial='') condition = models.StringField(initial='AIG') expertise = models.BooleanField(choices=[[True, 'Ja'], [False, 'Nein']], widget=widgets.RadioSelect) is_live = models.IntegerField(initial='-1') is_dealer = models.IntegerField(initial='-1') is_judge = models.IntegerField(initial='-1') opinion = models.IntegerField(initial='-1') vp_helpCode = models.StringField(initial='')