class Group(ContinuousDecisionGroup): current_matrix = models.PositiveIntegerField() def period_length(self): return Constants.period_length def initial_decision(self): return 0.5 def when_all_players_ready(self): super().when_all_players_ready() self.current_matrix = random.choice([0, 1]) self.save() self.emitter = DiscreteEventEmitter(0.1, self.period_length(), self, self.tick) self.emitter.start() def tick(self, current_interval, intervals): q1, q2 = list(self.group_decisions.values()) # decisions p11, p12, p21, p22 = [ pij[self.current_matrix] for pij in treatment(self.session)['transition_probabilities'] ] # transition probabilities # probability of a switch in 2 seconds = 1/2 # solved by P(switch in t) = (1-p)^10t = 1/2 Pmax = .034064 Pswitch = (p11 * q1 * q2 + p12 * q1 * (1 - q2) + p21 * (1 - q1) * q2 + p22 * (1 - q1) * (1 - q2)) * Pmax if random.uniform(0, 1) < Pswitch: self.current_matrix = 1 - self.current_matrix self.save() self.send('current_matrix', self.current_matrix)
def when_all_players_ready(self): super().when_all_players_ready() self.current_matrix = random.choice([0, 1]) self.save() self.emitter = DiscreteEventEmitter(0.1, self.period_length(), self, self.tick) self.emitter.start()
def when_all_players_ready(self): super().when_all_players_ready() self.state = 'results' self.t = 0 self.total_payoffs = {} self.countGood = {} self.periodResult = {} self.fixed_group_decisions = {} if parse_config( self.session.config['config_file'])[self.round_number - 1]['num_subperiods'] == 0: self.num_sub = random.randrange(5, 20) else: self.num_sub = parse_config( self.session.config['config_file'])[self.round_number - 1]['num_subperiods'] for i, player in enumerate(self.get_players()): self.total_payoffs[player.participant.code] = 0 self.countGood[player.participant.code] = 0 self.periodResult[player.participant.code] = "" self.fixed_group_decisions[player.participant.code] = 0 self.save() emitter = DiscreteEventEmitter( parse_config( self.session.config['config_file'])[self.round_number - 1]['seconds_per_tick'], self.period_length(), self, self.tick) emitter.start()
def when_all_players_ready(self): super().when_all_players_ready() # Needed for first tick logic self.x_t = None emitter = DiscreteEventEmitter(self.tick_length(), self.period_length(), self, self.tick, True) emitter.start()
def when_all_players_ready(self): super().when_all_players_ready() if not self.subperiod_results: self.subperiod_results = {} self.save(update_fields=['subperiod_results']) emitter = DiscreteEventEmitter( (self.seconds_per_tick() * self.subperiod_length()) + self.rest_length_seconds(), self.period_length(), self, self.subperiod_start, True) emitter.start()
def when_all_players_ready(self): super().when_all_players_ready() self.state = 'results' self.t = 0 self.fixed_group_decisions = {} for i, player in enumerate(self.get_players()): self.fixed_group_decisions[player.participant.code] = random.choice([1, 0]) self.save() self.send('initialDecisions', self.fixed_group_decisions) emitter = DiscreteEventEmitter(.25, self.period_length(), self, self.tick) emitter.start()
def when_all_players_ready(self): super().when_all_players_ready() self.state = 'results' self.t = 0 self.fixed_group_decisions = {} for i, player in enumerate(self.get_players()): self.fixed_group_decisions[player.participant.code] = 0 self.save() emitter = DiscreteEventEmitter(self.session.config['seconds_per_tick'], self.period_length(), self, self.tick) emitter.start()
def when_all_players_ready(self): """Initializes decisions based on ``player.initial_decision()``. If :attr:`num_subperiods` is set, starts a timed task to run the sub-periods. """ self.group_decisions = {} self.subperiod_group_decisions = {} for player in self.get_players(): self.group_decisions[ player.participant.code] = player.initial_decision() self.subperiod_group_decisions[ player.participant.code] = player.initial_decision() if self.num_subperiods(): emitter = DiscreteEventEmitter( self.period_length() / self.num_subperiods(), self.period_length(), self, self._subperiod_tick) emitter.start() elif self.rate_limit(): def _tick(current_interval, intervals): self.refresh_from_db() if self._group_decisions_updated: self.send('group_decisions', self.group_decisions) self._group_decisions_updated = False self.save(update_fields=['_group_decisions_updated']) update_period = self.rate_limit() emitter = DiscreteEventEmitter(update_period, self.period_length(), self, _tick) emitter.start() self.save()
class Group(DecisionGroup): current_matrix = models.PositiveIntegerField() def period_length(self): return parse_config( self.session.config['config_file'])[self.round_number - 1]['period_length'] def num_rounds(self): return len(parse_config(self.session.config['config_file'])) def when_all_players_ready(self): super().when_all_players_ready() self.current_matrix = random.choice([0, 1]) self.save() self.emitter = DiscreteEventEmitter(0.1, self.period_length(), self, self.tick) self.emitter.start() def pswitch(self, q1, q2): p11, p12, p21, p22 = [ pij[self.current_matrix] for pij in self.subsession.transition_probabilities() ] # transition probabilities # probability of a switch in 2 seconds = 1/2 # solved by P(switch in t) = (1-p)^10t = 1/2 Pmax = .034064 return (p11 * q1 * q2 + p12 * q1 * (1 - q2) + p21 * (1 - q1) * q2 + p22 * (1 - q1) * (1 - q2)) * Pmax def tick(self, current_interval, intervals): # TODO: Integrate into the otree-redwood DiscreteEventEmitter API, because otherwise # someone will forget this and get very confused when the tick functions use stale data. self.refresh_from_db() if len(self.group_decisions) != 2: return q1 = self.group_decisions[self.get_player_by_id(1).participant.code] q2 = self.group_decisions[self.get_player_by_id(2).participant.code] if random.uniform(0, 1) < self.pswitch(q1, q2): self.current_matrix = 1 - self.current_matrix self.save() self.send('current_matrix', self.current_matrix)