summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mc-resources.py112
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)