def __init__(self, name, preconditions=None, effects=None): # excellent resource on weighted selection, i.e. loaded dice (i.e. PDF): # http://www.keithschwarz.com/darts-dice-coins/ self.name = name self.preconditions = [ (set(), set()) ] if not preconditions else preconditions # multiple conditions may apply self.effects = [] if effects is None else effects total_probability = sum([effect.probability for effect in effects]) if total_probability > 1: # test whether the total probability does not exceed 1 raise AttributeError( "The probability of the effects of an action must sum up to 1 or less than 1." ) elif total_probability < 1: # if the probability is less than 1, add the default effect where nothing changes self.effects.append(Effect(set(), set(), 1 - total_probability)) # sort the effects so that the most likely effect is on top; use for efficient rollouts along most probable path self.effects = sorted(self.effects, key=lambda effect: effect.probability, reverse=True) self._vose = Vose([(effect.probability, effect) for effect in self.effects])
} def check(prompt, ans): k = ''.join(ans.lower().split()) if k not in smappings: return False return smappings[k] == prompt prompts = tuple(mappings.keys()) accuracy = [CMA() for i in range(len(mappings))] total_accuracy = CMA() last_i = None while True: dice = Vose(*(1 - cma.value() for cma in accuracy)) i = next(dice) if last_i is not None and i == last_i: continue else: last_i = i prompt = prompts[i] ans = input(f'{prompt} = ') if check(prompt, ans): completion = int(100 * (1 - (len(prompts) / len(mappings)))) accuracy[i].update(1) total_accuracy.update(1) prn_accuracy = int(total_accuracy.value() * 100) print(f'correct ({prn_accuracy}% accurate)') else: accuracy[i].update(0)