def reproduce(order1, order2, constraints):
    """
    Returns a new organism with mutation
    For asexual, pass None for order2
    Constraints - a frozen set of tuples representing guidelines (UNIT, COUNT)
    """
    if order2 == None:
        child = Order(events_list = copy.deepcopy(order1.events), race = order1.race, calc = False)
        mutate(child, constraints)
    else:
        while True:
            events_list = []
            for index in xrange(max(len(order1.events),len(order2.events))):
                options = []
                if index < len(order1.events):
                    options.append(order1.events[index])
                if index < len(order2.events):
                    options.append(order2.events[index])
                events_list.append(random.choice(options))
            child = Order(race = order1.race,events_list = events_list)
            if child.sanity_check(): # not a monster
                break
        mutate(child,constraints)
    return child
def randomly_fit(race,constraints):
    """
    Returns a random build order that fits the given constraints or fills supply
    Constraints is a frozen set with elements (UNIT, COUNT)
    """
    set_up(constraints, race)
    order = Order(race = race, calc = False)
    order.evaluate()
    while not has_constraints(order.at_time[-1],constraints) and order.at_time[-1].supply < 200:
        choice = random.choice([i for i in order.at_time[-1].all_available() if helps(i,constraints)])
        if events[choice].get_result() == boost:
            pass # caring to allow for chrono boost during random fit would require even more calculation
        else:
            order.append([choice,''],recalc = False,remember = False)
            order.evaluate() # not verified
    return order