# /usr/bin/python
# -*- coding: utf-8 -*-
# 2014, Johan Rönnblom <johan@ronnblom.net>
# This simulation is used to show the effect of allowing 'tweaks' to criteria
# used to determine whether someone fits a class of heroes.

import random

SIMULATIONS = 1000000
CRITERIA = 22
HERO_STAT = 0.7
MIN_HERO_STATS = 12
# Define a number of allowed 'tweaks' to lower the stat limit
# for some arbitrarily chosen criteria
TWEAKS = [0.3, 0.3, 0.3, 0.2, 0.2, 0.2, 0.1, 0.1, 0.1]

def scoreHero(useTweaks):
    # Copy available tweaks
    tweaks = TWEAKS[:]
    # Give our hero candidate random stats between 0 and 1
    stats = [random.random() for i in xrange(CRITERIA)]
    # Sort to score the closest hits first, using smaller
    # tweaks first if possible
    stats.sort(reverse = True)
    # score the hero
    score = 0
    for stat in stats:
        if stat >= HERO_STAT:
            score += 1
        elif useTweaks:
            # Try tweaking as little as possible
            # first to save heavier tweaks for later
            while tweaks:
                tweak = tweaks.pop()
                if stat >= HERO_STAT - tweak:
                    score += 1
                    break
    return score

for useTweaks in [False, True]:
    heroes = 0
    for candidate in xrange(SIMULATIONS):
        if scoreHero(useTweaks) >= MIN_HERO_STATS:
            heroes += 1
    tweak = ['without tweaks', 'with tweaks'][useTweaks]
    print '%.1f%% heroes found %s.' % (100.0 * heroes / SIMULATIONS, tweak)
