Ejemplo n.º 1
0
def gas_helps(constraints, race):
    for unit, count in constraints:
        # reactor build time 50s, marine 25s
        if unit == MARINE and count > 3:
            return True
        # cycore time 50
        # warp gate time 160
        # zealot time 38 -> 28 with warpgate
        if unit == ZEALOT and count > 5:
            return True
    instance = Instance()
    instance.init_as_race(race)
    can_reach = set([i for i in xrange(NUM_UNITS) if instance.units[i] > 0])
    old_size = 0
    new_size = len(can_reach)
    gasless_events = filter(lambda event: event.cost[1] == 0, events)
    while old_size < new_size:
        old_size = new_size
        for event in gasless_events:
            for req, kind in event.requirements:
                if kind is not NOT and req not in can_reach:
                    break
            else:
                if event.result in [add, warp, research, warp]:
                    can_reach |= set([product for product in event.args])
        new_size = len(can_reach)
    required = set([i for unit, count in constraints])
    return required.issubset(can_reach)
Ejemplo n.º 2
0
def a_star_optimization(race, constraints):
    """
    Returns the optimal build order for fitting the given constraints, having calculated it via an A* search
    Optimality is measured according to time required to meet constraints. This function necessarily returns a most optimal build
    Contraints is an array of units required in the form [(UNIT_INDEX, UNIT_COUNT)]
    Race denotes the race: "Z", "P", or "T"
    """
    frozen_cons = frozenset(constraints)
    set_up(frozen_cons,race)
    frontier = PriorityQueue() # no limit
    first_instance = Instance()
    first_instance.init_as_race(race)
    # The items in the queue should be a tuple, with the first element being a tuple of events, and the second element being the last instance of those events.
    if has_constraints(first_instance, constraints):
        # Create the desired order using the events list
        best_order = Order(race = race, events_list = tuple())
        return best_order
    frontier.push((tuple(), first_instance), 1)
    while not frontier.isEmpty():
        events_so_far, current_instance = frontier.pop()
        # Check all available event options
        # TODO move filter into all avaialable
        options = current_instance.all_available() # somehow we need to handle gas tricks
        # filter ones that help
        # TODO chronoboost
        options = [[option, ""] for option in options if helps(option, frozen_cons) and Order(race = race, events_list = events_so_far + ([option,""],), calc = False).sanity_check(True)]
        while len(options) > 0:
            for index in xrange(len(options) -1, -1, -1): # yeah
                event_info = options[index]
                if (current_instance.available(now = True, event_index = event_info[0])):
                    del options[index]
                    new_instance = copy.deepcopy(current_instance)
                    new_instance.apply_event(event_info)
                    extension = (events_so_far + (event_info,), new_instance)
                    if events[event_info[0]].get_result() == boost:
                        pass
                    else:
                        frontier.push(extension, cost(extension[1]) + heuristic(extension[1],constraints))
                     
            current_instance.increment({},{})
            if has_constraints(current_instance, constraints):
                best_order = Order(race = race, events_list = events_so_far)
                return best_order
    raise Exception("a_star optimization shouldn't have exited without a solution.")