diff options
-rw-r--r-- | mc-resources.py | 112 |
1 files changed, 68 insertions, 44 deletions
diff --git a/mc-resources.py b/mc-resources.py index ef4cb31..dadd79d 100644 --- a/mc-resources.py +++ b/mc-resources.py @@ -208,6 +208,7 @@ def choose_recipe_for_item(dest_item): if dest_item in chosen_recipes: return chosen_recipes[dest_item] if dest_item not in recipe_lists: + chosen_recipes[dest_item] = None return None recipes = recipe_lists[dest_item] choices = {'gather': (None, {})} @@ -241,29 +242,23 @@ def choose_recipe_for_item(dest_item): chosen_tags[tag] = tag_map[tag] return recipe -# dependees -item_deps_added = [] - -# dependency -> dependee +# dependee -> dependency item_deps = {} items_needed = {} def add_item_deps(item): - if item not in item_deps_added: - item_deps_added.append(item) - if item not in item_deps: - item_deps[item] = [] - recipe = choose_recipe_for_item(item) - if recipe is not None: - for dep, _ in recipe[1]: - if dep[0] == '#': - dep = chosen_tags[dep[1:]] - if dep in item_deps: - item_deps[dep].append(item) - else: - item_deps[dep] = [item] - add_item_deps(dep) + if item in item_deps: + return + item_deps[item] = [] + recipe = choose_recipe_for_item(item) + if recipe is None: + return + for dep, _ in recipe[1]: + if dep[0] == '#': + dep = chosen_tags[dep[1:]] + item_deps[item].append(dep) + add_item_deps(dep) def add_needed_item(item, count): if item in items_needed: @@ -308,39 +303,17 @@ while True: continue break + while True: for item in items_needed: add_item_deps(item) original_needed = items_needed.copy() - steps = [] - gather_steps = [] ts = graphlib.TopologicalSorter(item_deps) try: - for item in ts.static_order(): - if item in items_needed: - needed = items_needed[item] - if needed == 0: - continue - recipe = choose_recipe_for_item(item) - if recipe is None: - gather_steps.append(f'gather {needed} {to_display_name(item)}') - add_needed_item(item, -needed) - else: - count = (needed - 1) // recipe[3] + 1 - ingredients = [] - for ingredient, c in recipe[1]: - if ingredient[0] == '#': - ingredients.append((chosen_tags[ingredient[1:]], c)) - else: - ingredients.append((ingredient, c)) - source = join_with_and([f'{c * count} {to_display_name(i)}' for i, c in ingredients]) - steps.append(f'{recipe[0]} {source} into {recipe[3] * count} {to_display_name(recipe[2])}') - for i, c in ingredients: - add_needed_item(i, c * count) - add_needed_item(item, -recipe[3] * count) + ts.prepare() except graphlib.CycleError as ex: print('cycle detected: ' + ' from '.join(to_display_name(id) for id in ex.args[1])) @@ -357,10 +330,61 @@ while True: break +gathers = [] +order = [] + +while ts.is_active(): + ready_smelt = [] + ready_nonsmelt = [] + ready = ts.get_ready() + for id in ready: + recipe = chosen_recipes[id] + if recipe is None: + gathers.append(id) + elif recipe[0] == 'smelt': + ready_smelt.append(id) + else: + ready_nonsmelt.append(id) + ts.done(id) + ready_smelt.sort() + ready_nonsmelt.sort() + order += ready_smelt + ready_nonsmelt + +order.reverse() + +steps = [] + +for item in order: + if item in items_needed: + needed = items_needed[item] + if needed == 0: + continue + recipe = choose_recipe_for_item(item) + count = (needed - 1) // recipe[3] + 1 + ingredients = [] + for ingredient, c in recipe[1]: + if ingredient[0] == '#': + ingredients.append((chosen_tags[ingredient[1:]], c)) + else: + ingredients.append((ingredient, c)) + source = join_with_and([f'{c * count} {to_display_name(i)}' for i, c in ingredients]) + steps.append(f'{recipe[0]} {source} into {recipe[3] * count} {to_display_name(recipe[2])}') + for i, c in ingredients: + add_needed_item(i, c * count) + add_needed_item(item, -recipe[3] * count) + +gathers.sort() +gathers.reverse() + +for item in gathers: + if item in items_needed: + needed = items_needed[item] + if needed != 0: + steps.append(f'gather {needed} {to_display_name(item)}') + items_needed[item] = 0 + steps.reverse() print('steps:') -for step in gather_steps: - print(' ' + step) for step in steps: print(' ' + step) |