from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency ) import random doc = """ a.k.a. Keynesian beauty contest. Two players are picked randomly. Whoevers chosen number is closest to 2/3 of the average of the two numbers wins. """ class Constants(BaseConstants): players_per_group = None num_rounds = 1 name_in_url = 'Beauty_Contest_Paired' jackpot = Currency(100) guess_max = 100 instructions_template = 'Beauty_Contest_Paired/Instructions.html' class Subsession(BaseSubsession): two_thirds_avg = models.FloatField() best_guess = models.IntegerField() num_winners = models.IntegerField() def set_payoffs(self): players = random.sample(self.get_players(), 2) for p in players: p.is_selected = True selected_players = [p.participant.vars['name'] for p in players] selected_guesses = [p.guess for p in players] guesses = [p.guess for p in players] two_thirds_avg = (2 / 3) * sum(guesses) / len(players) self.two_thirds_avg = round(two_thirds_avg, 2) self.best_guess = min(guesses, key=lambda guess: abs(guess - self.two_thirds_avg)) winners = [p for p in players if p.guess == self.best_guess] self.num_winners = len(winners) for p in winners: p.is_winner = True p.payoff = Constants.jackpot / self.num_winners def vars_for_admin_report(self): players = self.get_players() print([p for p in players]) print([p.guess for p in players]) return {'guesses': [p.guess for p in players], 'best_guess': self.best_guess, 'winning_players': [p for p in players if p.guess == self.best_guess] } def number_of_players(self): return len(self.get_players()) class Group(BaseGroup): pass class Player(BasePlayer): guess = models.IntegerField(min=0, max=Constants.guess_max) is_winner = models.BooleanField(initial=False) is_selected = models.BooleanField(initial=False)