from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) import random import csv author = 'William Brown' doc = """ Plurality voting contest with full information """ class Constants(BaseConstants): name_in_url = 'Plurality_Vote_Fullinfo' players_per_group = 5 num_rounds = 40 num_sessions = int(num_rounds / 10) file = open("Plurality_Vote_Fullinfo/voting_preferences.csv", 'r') data = csv.reader(file, delimiter=',') payouts = [] for x in range(num_sessions): payouts.append(list()) for _ in range(4): payouts[x].append(data.__next__()) class Subsession(BaseSubsession): def creating_session(self): if self.round_number == 10 or self.round_number == 20 or self.round_number == 30: matrix = self.get_group_matrix() for row in matrix: sys_random = random.SystemRandom() sys_random.shuffle(row) self.set_group_matrix(matrix) class Group(BaseGroup): total_for_A = models.IntegerField(initial=0, min=0, max=Constants.players_per_group) total_for_B = models.IntegerField(initial=0, min=0, max=Constants.players_per_group) total_for_C = models.IntegerField(initial=0, min=0, max=Constants.players_per_group) total_for_D = models.IntegerField(initial=0, min=0, max=Constants.players_per_group) winner = models.StringField() winner_num = models.IntegerField() def vote_A(self): self.total_for_A = 0 for p in self.get_players(): if p.vote_choice == 'A': self.total_for_A += 1 return self.total_for_A def vote_B(self): self.total_for_B = 0 for p in self.get_players(): if p.vote_choice == 'B': self.total_for_B += 1 return self.total_for_B def vote_C(self): self.total_for_C = 0 for p in self.get_players(): if p.vote_choice == 'C': self.total_for_C += 1 return self.total_for_C def vote_D(self): self.total_for_D = 0 for p in self.get_players(): if p.vote_choice == 'D': self.total_for_D += 1 return self.total_for_D def vote_winner(self): sys_random = random.SystemRandom() self.vote_A() self.vote_B() self.vote_C() self.vote_D() candidates = { "A": self.total_for_A, "B": self.total_for_B, "C": self.total_for_C, "D": self.total_for_D, } winning_candidate = [] maximum = 0 for name, votes in candidates.items(): if votes == maximum: winning_candidate.append(name) if votes > maximum: winning_candidate = [] winning_candidate.append(name) maximum = votes self.winner = sys_random.choice(winning_candidate) self.winner_num = 0 if self.winner == "A": self.winner_num = 0 elif self.winner == "B": self.winner_num = 1 elif self.winner == "C": self.winner_num = 2 else: self.winner_num = 3 def get_payoffs(self): players = self.get_players() for p in players: p.round_payoff = int(Constants.payouts[(self.round_number-1) // 10][self.winner_num][p.id_in_group - 1]) p.payoff += p.round_payoff class Player(BasePlayer): player_payoff = models.StringField() round_payoff = models.IntegerField() vote_choice = models.StringField( choices=['A', 'B', 'C', 'D'], widget=widgets.RadioSelect, doc="""Candidate player wishes to cast a vote for""" ) def player_payoff_1(self): self.player_payoff = Constants.payouts[(self.round_number-1) // 10][0][self.id_in_group - 1] return self.player_payoff def player_payoff_2(self): self.player_payoff = Constants.payouts[(self.round_number-1) // 10][1][self.id_in_group - 1] return self.player_payoff def player_payoff_3(self): self.player_payoff = Constants.payouts[(self.round_number-1) // 10][2][self.id_in_group - 1] return self.player_payoff def player_payoff_4(self): self.player_payoff = Constants.payouts[(self.round_number-1) // 10][3][self.id_in_group - 1] return self.player_payoff