# HG changeset patch # User Jason Maltzen # Date 2016-01-23 20:18:05 # Node ID 2c3944282ed8a24e3ab46ab1dbe4b574ec93e247 # Parent 0fc4dcb2a70ed73aeebcac3fe50469cd4e87e12b Fixes for starting with a min reagent count > 1 diff --git a/RecipeGenerator.cs b/RecipeGenerator.cs --- a/RecipeGenerator.cs +++ b/RecipeGenerator.cs @@ -235,13 +235,30 @@ namespace DesertPaintLab { if (costSortedReagents[(int)reagentIdx].Enabled) { + // queue up all combinations of MinReagents RecipeSearchNode initialNode = new RecipeSearchNode(costSortedReagents, reagentIdx); initialNode.FullQuantity = FullQuantity; initialNode.FullQuantityDepth = FullQuantityDepth; initialNode.MaxQuantity = maxQuantity; initialNode.MinReagents = minReagents; initialNode.MaxReagents = maxReagents; - searchQueue.Enqueue(initialNode); + + if (MinReagents > 1) + { + while (NextReagentSetBreadthFirst(initialNode, 1, minReagents) == true) + { + if (initialNode.ReagentCount == minReagents) + { + //Console.WriteLine("Initial node at size {0}/{1} with recipe: {2}", initialNode.ReagentCount, minReagents, initialNode.TestRecipe.ToString()); + RecipeSearchNode searchNode = new RecipeSearchNode(initialNode); + searchQueue.Enqueue(searchNode); + } + } + } + else + { + searchQueue.Enqueue(initialNode); + } } } @@ -302,31 +319,34 @@ namespace DesertPaintLab return false; } - using (StreamWriter writer = new StreamWriter(file, false)) + lock(workerLock) { - writer.WriteLine("MinReagents: {0}", MinReagents); - writer.WriteLine("MaxReagents: {0}", MaxReagents); - writer.WriteLine("FullQuantityDepth: {0}", FullQuantityDepth); - writer.WriteLine("FullQuantity: {0}", FullQuantity); - writer.WriteLine("TotalReagents: {0}", totalReagents); - writer.WriteLine("RecipeCount: {0}", recipeCount); - writer.WriteLine("SearchType: {0}", Mode.ToString()); - foreach (KeyValuePair pair in recipes) + using (StreamWriter writer = new StreamWriter(file, false)) { - PaintRecipe recipe = pair.Value; - string colorName = Palette.FindNearest(recipe.ReactedColor); - writer.WriteLine("BeginRecipe: {0}", colorName); - foreach (PaintRecipe.RecipeIngredient ingredient in recipe.Ingredients) + writer.WriteLine("MinReagents: {0}", MinReagents); + writer.WriteLine("MaxReagents: {0}", MaxReagents); + writer.WriteLine("FullQuantityDepth: {0}", FullQuantityDepth); + writer.WriteLine("FullQuantity: {0}", FullQuantity); + writer.WriteLine("TotalReagents: {0}", totalReagents); + writer.WriteLine("RecipeCount: {0}", recipeCount); + writer.WriteLine("SearchType: {0}", Mode.ToString()); + foreach (KeyValuePair pair in recipes) { - writer.WriteLine("Ingredient: {0}={1}", ingredient.name, ingredient.quantity); + PaintRecipe recipe = pair.Value; + string colorName = Palette.FindNearest(recipe.ReactedColor); + writer.WriteLine("BeginRecipe: {0}", colorName); + foreach (PaintRecipe.RecipeIngredient ingredient in recipe.Ingredients) + { + writer.WriteLine("Ingredient: {0}={1}", ingredient.name, ingredient.quantity); + } + writer.WriteLine("EndRecipe: {0}", colorName); } - writer.WriteLine("EndRecipe: {0}", colorName); + writer.WriteLine("SearchNodes: {0}", searchQueue.Count); + foreach (RecipeSearchNode node in searchQueue) + { + node.SaveState(writer); + } } - writer.WriteLine("SearchNodes: {0}", searchQueue.Count); - foreach (RecipeSearchNode node in searchQueue) - { - node.SaveState(writer); - } } return true; } @@ -684,6 +704,12 @@ namespace DesertPaintLab } } while (newQuantity < quantityLimit); + bool ok = NextReagentSetBreadthFirst(node, node.MinReagents, node.MaxReagents); + return ok; + } + + private bool NextReagentSetBreadthFirst(RecipeSearchNode node, uint minReagents, uint maxReagents) + { // search all variants at this depth of recipe // increase recipe depth @@ -699,9 +725,9 @@ namespace DesertPaintLab do { recipeFound = false; // back out until we find a node that can be incremented - if (currentDepth > node.MinReagents) + if (currentDepth > minReagents) { - while (node.ReagentCount > node.MinReagents) + while (node.ReagentCount > minReagents) { if (node.LastReagent < (totalReagents - 1)) { @@ -717,7 +743,7 @@ namespace DesertPaintLab // shouldn't happen //Console.WriteLine("No available reagents at depth {0}!", node.ReagentCount); node.RemoveLastReagent(); - if (node.ReagentCount == node.MinReagents) + if (node.ReagentCount == minReagents) { // just popped the last reagent at the top level ++currentDepth; @@ -729,7 +755,7 @@ namespace DesertPaintLab { //Console.WriteLine("Pop last reagent"); node.RemoveLastReagent(); - if (node.ReagentCount == node.MinReagents) + if (node.ReagentCount == minReagents) { // just popped the last reagent at the top level ++currentDepth; @@ -738,7 +764,7 @@ namespace DesertPaintLab } } // fill in the nodes up to the current depth - if (node.ReagentCount >= node.MinReagents) + if (node.ReagentCount >= minReagents && currentDepth <= maxReagents) { recipeFound = true; while (node.ReagentCount < currentDepth) @@ -752,7 +778,7 @@ namespace DesertPaintLab } } //Console.WriteLine("Catalysts: {0} Reagents: {1} Min: {2}", node.CatalystCount, node.ReagentCount, node.MinReagents); - } while ((node.CatalystCount >= node.ReagentCount) && (node.ReagentCount >= node.MinReagents)); // make sure to skip all-catalyst combinations + } while ((node.CatalystCount >= node.ReagentCount) && (node.ReagentCount >= minReagents)); // make sure to skip all-catalyst combinations if (recipeFound) { break; @@ -762,7 +788,7 @@ namespace DesertPaintLab ++currentDepth; if (log != null) { lock(log) { log.WriteLine("Increased depth to {0}/{1} [no recipe]", currentDepth, node.MaxReagents); } } } - } while (currentDepth <= node.MaxReagents); + } while (currentDepth <= maxReagents); if (recipeFound) { node.InitForQuantity(10+node.CatalystCount); // minimum quantity for this recipe diff --git a/RecipeSearchNode.cs b/RecipeSearchNode.cs --- a/RecipeSearchNode.cs +++ b/RecipeSearchNode.cs @@ -94,6 +94,36 @@ namespace DesertPaintLab } } + public RecipeSearchNode(RecipeSearchNode other) + { + this.costSortedReagents = new List(other.costSortedReagents); + this.reagents = new uint[costSortedReagents.Count]; + INVALID_REAGENT = (uint)costSortedReagents.Count; + for (int i = 0; i < costSortedReagents.Count; ++i) + { + this.reagents[i] = other.reagents[i]; + } + reagentInUse = new bool[costSortedReagents.Count]; + for (uint i = 0; i < costSortedReagents.Count; ++i) + { + reagentInUse[i] = other.reagentInUse[i]; + } + nextReagentPos = other.nextReagentPos; + + CurrentTargetQuantity = other.CurrentTargetQuantity; + MaxQuantity = other.MaxQuantity; + UsedQuantity = other.UsedQuantity; + CatalystCount = other.CatalystCount; + FullQuantityDepth = other.FullQuantityDepth; + FullQuantity = other.FullQuantity; + MinReagents = other.MinReagents; + MaxReagents = other.MaxReagents; + for (int i = 0; i < MaxReagents; ++i) + { + currentWeights[i] = other.currentWeights[i]; + } + } + public RecipeSearchNode(List costSortedReagents, uint[] reagents) { this.costSortedReagents = new List(costSortedReagents);