From af7fa853b0dbabd7af694abfab1772b6ad974d5f Mon Sep 17 00:00:00 2001 From: Andrew Miner Date: Mon, 2 Sep 2013 14:38:11 -0700 Subject: [PATCH] Re-add tools to crafting calculation --- html/script/crafting.js | 55 +++++++++++++++++++++++++-------- html/script/test.js | 67 ++++++++++++++++++++++++++++------------- 2 files changed, 88 insertions(+), 34 deletions(-) diff --git a/html/script/crafting.js b/html/script/crafting.js index 4603e80fc..66370e30c 100644 --- a/html/script/crafting.js +++ b/html/script/crafting.js @@ -60,7 +60,7 @@ function onCraftingSelectorChanged() { if (! hasRecipe(recipeName)) { $("#crafting_output").slideUp(SLIDE_DURATION); } else { - var plan = createCraftingPlan(count, recipeName); + var plan = createCraftingPlan(count, recipeName, __toolsIncluded); var result = createCraftingResult(__inventory); plan.alternatives[0].craft(result); @@ -214,16 +214,19 @@ function updatePageState(count, recipeName) { // Crafting Node Object /////////////////////////////////////////////////////////////////////////////////////////////// -function createCraftingNode(count, recipeName, alternatives, recipeBooks) { +function createCraftingNode(count, recipeName, shouldIncludeTools, alternatives, recipeBooks) { + if (shouldIncludeTools !== true) shouldIncludeTools = false; if (recipeBooks === undefined) recipeBooks = __recipeBooks; var object = { alternatives: [], children: [], count: count, + isToolNode: false, name: recipeName, parentNode: undefined, - recipe: undefined + recipe: undefined, + shouldIncludeTools: shouldIncludeTools }; if (count !== undefined) { @@ -234,9 +237,20 @@ function createCraftingNode(count, recipeName, alternatives, recipeBooks) { object.recipe = alternatives.shift(); object.alternatives = alternatives; + if (shouldIncludeTools) { + for (var i = 0; i < object.recipe.tools.length; i++) { + var tool = object.recipe.tools[i]; + var node = createCraftingNode(1, tool, shouldIncludeTools, undefined, recipeBooks); + if (node) { + node.isToolNode = true; + node.parentNode = object; + object.children.push(node); + } + } + } for (var i = 0; i < object.recipe.input.length; i++) { var input = object.recipe.input[i]; - var node = createCraftingNode(input.count, input.name, undefined, recipeBooks); + var node = createCraftingNode(input.count, input.name, shouldIncludeTools, undefined, recipeBooks); if (node) { node.parentNode = object; object.children.push(node); @@ -248,9 +262,11 @@ function createCraftingNode(count, recipeName, alternatives, recipeBooks) { var result = createCraftingNode(); result.alternatives = object.alternatives.copy(); result.count = object.count; + result.isToolNode = object.isToolNode; result.name = object.name; result.parentNode = undefined; result.recipe = object.recipe.copy(); + result.shouldIncludeTools = object.shouldIncludeTools; result.children = object.children.copy(); for (var i = 0; i < result.children.length; i++) { @@ -260,15 +276,16 @@ function createCraftingNode(count, recipeName, alternatives, recipeBooks) { return result; }; - object.craft = function(craftingResult, isCraftingChild) { + object.craft = function(craftingResult) { + if (shouldIncludeTools !== true) shouldIncludeTools = false; if (craftingResult === undefined) { craftingResult = createCraftingResult(); } var shouldContinueCrafting = function() { - if (isCraftingChild === true) { - return craftingResult.missingMaterials.contains(1, object.name); - } else { + if (object.parentNode === undefined || object.isToolNode) { return ! craftingResult.inventory.contains(object.count, object.name); + } else { + return craftingResult.missingMaterials.contains(1, object.name); } } @@ -277,6 +294,16 @@ function createCraftingNode(count, recipeName, alternatives, recipeBooks) { if (count++ > 100000) { throw "Too many iterations"; } + if (object.shouldIncludeTools) { + for (var i = 0; i < object.recipe.tools; i++) { + var tool = object.recipe.tools[i]; + var hasTool = craftingResult.inventory.contains(1, tool) || + craftingResult.missingMaterials.contains(1, tool); + if (! hasTool) { + craftingResult.addMissingMaterial(tool); + } + } + } for (var i = 0; i < object.recipe.input.length; i++) { var input = object.recipe.input[i]; for (var j = 0; j < input.count; j++) { @@ -294,9 +321,9 @@ function createCraftingNode(count, recipeName, alternatives, recipeBooks) { } for (var i = 0; i < object.children.length; i++) { var child = object.children[i]; - child.craft(craftingResult, true); + child.craft(craftingResult); } - if (isCraftingChild !== true) { + if (object.parentNode === undefined) { craftingResult.sortStepsBy(object); } return craftingResult; @@ -305,7 +332,8 @@ function createCraftingNode(count, recipeName, alternatives, recipeBooks) { object.createNextAlternative = function(recipeBooks) { if (recipeBooks === undefined) recipeBooks = __recipeBooks; if (object.alternatives.length === 0) return undefined; - var nextAlternative = createCraftingNode(object.count, object.name, object.alternatives, recipeBooks); + var nextAlternative = createCraftingNode( + object.count, object.name, object.shouldIncludeTools, object.alternatives, recipeBooks); object.alternatives = []; return nextAlternative; }; @@ -365,7 +393,8 @@ function createCraftingNode(count, recipeName, alternatives, recipeBooks) { // Crafting Plan Object /////////////////////////////////////////////////////////////////////////////////////////////// -function createCraftingPlan(count, recipeName, recipeBooks) { +function createCraftingPlan(count, recipeName, shouldIncludeTools, recipeBooks) { + if (shouldIncludeTools !== true) shouldIncludeTools = false; if (recipeBooks === undefined) recipeBooks = __recipeBooks; var object = { @@ -374,7 +403,7 @@ function createCraftingPlan(count, recipeName, recipeBooks) { alternatives: [] }; - var nodesToProcess = [ createCraftingNode(count, recipeName, undefined, recipeBooks) ]; + var nodesToProcess = [ createCraftingNode(count, recipeName, shouldIncludeTools, undefined, recipeBooks) ]; while (nodesToProcess.length > 0) { var node = nodesToProcess.shift(); var choiceNode = node.findNodeWithAlternatives(); diff --git a/html/script/test.js b/html/script/test.js index 5ecbb0b19..ecc13cfe7 100644 --- a/html/script/test.js +++ b/html/script/test.js @@ -176,7 +176,7 @@ test("Array.copy", function() { module("CraftingNode"); /////////////////////////////////////////////////////////////////////////////////////////////// test("create: simple", function() { - var node = createCraftingNode(12, "Furnace", undefined, __sampleRecipeBooks); + var node = createCraftingNode(12, "Furnace", false, undefined, __sampleRecipeBooks); deepEqual(node.alternatives.length, 0); deepEqual(node.children.length, 0); deepEqual(node.count, 12); @@ -186,7 +186,7 @@ test("create: simple", function() { }); test("create: complex", function() { - var node = createCraftingNode(1, "Iron Gear", undefined, __sampleRecipeBooks); + var node = createCraftingNode(1, "Iron Gear", false, undefined, __sampleRecipeBooks); deepEqual(node.name, "Iron Gear"); deepEqual(node.children.length, 2); deepEqual(node.children[0].name, "Iron Ingot"); @@ -215,8 +215,16 @@ test("create: complex", function() { deepEqual(node.children, []); }); +test("create: with tool", function() { + var node = createCraftingNode(1, "Iron Ingot", true, undefined, __sampleRecipeBooks); + deepEqual(node.alternatives.length, 0, JSON.stringify(node.alternatives)); + deepEqual(node.children.length, 1); + deepEqual(node.children[0].name, "Furnace"); + deepEqual(node.name, "Iron Ingot"); +}); + test("craft: simple", function() { - var node = createCraftingNode(1, "Furnace", undefined, __sampleRecipeBooks); + var node = createCraftingNode(1, "Furnace", false, undefined, __sampleRecipeBooks); var result = node.craft(); deepEqual(result.inventory.materials["Furnace"], 1); @@ -227,7 +235,7 @@ test("craft: simple", function() { deepEqual(result.stepList[0].count, 1); deepEqual(result.stepList[0].name, "Furnace"); - node = createCraftingNode(2, "Furnace", undefined, __sampleRecipeBooks); + node = createCraftingNode(2, "Furnace", false, undefined, __sampleRecipeBooks); result = node.craft(); deepEqual(result.inventory.materials["Furnace"], 2, JSON.stringify(result.inventory)); @@ -245,7 +253,7 @@ test("craft: with initial inventory", function() { var inventory = createManifest(); inventory.add(4, "Cobblestone"); var result = createCraftingResult(inventory); - var node = createCraftingNode(2, "Furnace", undefined, __sampleRecipeBooks); + var node = createCraftingNode(2, "Furnace", false, undefined, __sampleRecipeBooks); node.craft(result); deepEqual(result.inventory.materials["Furnace"], 2); @@ -261,7 +269,7 @@ test("craft: no-op", function() { var inventory = createManifest(); inventory.add(1, "Furnace"); var result = createCraftingResult(inventory); - var node = createCraftingNode(1, "Furnace", undefined, __sampleRecipeBooks); + var node = createCraftingNode(1, "Furnace", false, undefined, __sampleRecipeBooks); node.craft(result); deepEqual(result.inventory.materials["Furnace"], 1, JSON.stringify(result.inventory)); @@ -271,7 +279,7 @@ test("craft: no-op", function() { }); test("craft: deep tree", function() { - var node = createCraftingNode(1, "Iron Gear", undefined, __sampleRecipeBooks); + var node = createCraftingNode(1, "Iron Gear", false, undefined, __sampleRecipeBooks); var result = node.craft(); deepEqual(result.inventory.materials["Iron Gear"], 1); @@ -300,7 +308,7 @@ test("craft: deep tree", function() { }); test("craft: repeatedly craft ingredient", function() { - var node = createCraftingNode(1, "Bookshelf", undefined, __sampleRecipeBooks); + var node = createCraftingNode(1, "Bookshelf", false, undefined, __sampleRecipeBooks); var result = node.craft(); deepEqual(result.inventory.materials["Bookshelf"], 1, JSON.stringify(result.inventory)); @@ -324,7 +332,7 @@ test("craft: repeatedly craft ingredient", function() { }); test("craft: same item used multiple places", function() { - var node = createCraftingNode(1, "Mining Well", undefined, __sampleRecipeBooks); + var node = createCraftingNode(1, "Mining Well", false, undefined, __sampleRecipeBooks); var result = node.craft(); deepEqual(result.inventory.materials["Mining Well"], 1, JSON.stringify(result.inventory)); @@ -357,9 +365,26 @@ test("craft: same item used multiple places", function() { deepEqual(result.stepList.length, 8, JSON.stringify(result.stepList)); }); +test("craft: multiple tools needed", function() { + var node = createCraftingNode(1, "Iron Pickaxe", true, undefined, __sampleRecipeBooks); + var result = node.craft(); + + deepEqual(result.inventory.materials["Iron Pickaxe"], 1, JSON.stringify(result.inventory)); + deepEqual(result.inventory.materials["Birch Plank"], 2, JSON.stringify(result.inventory)); + deepEqual(result.inventory.materials["Stick"], 2, JSON.stringify(result.inventory)); + deepEqual(result.inventory.materials["Furnace"], 1, JSON.stringify(result.inventory)); + deepEqual(result.inventory.materials["Crafting Table"], 1, JSON.stringify(result.inventory)); + deepEqual(result.inventory.length, 5, JSON.stringify(result.inventory)); + + deepEqual(result.missingMaterials.materials["Birch Log"], 2, JSON.stringify(result.missingMaterials)); + deepEqual(result.missingMaterials.materials["Iron Ore"], 3, JSON.stringify(result.missingMaterials)); + deepEqual(result.missingMaterials.materials["Cobblestone"], 8, JSON.stringify(result.missingMaterials)); + deepEqual(result.missingMaterials.materials["milli-coal"], 375, JSON.stringify(result.missingMaterials)); + deepEqual(result.missingMaterials.length, 4, JSON.stringify(result.missingMaterials)); +}); test("copy", function() { - var node = createCraftingNode(3, "Stick", undefined, __sampleRecipeBooks); + var node = createCraftingNode(3, "Stick", false, undefined, __sampleRecipeBooks); var copiedNode = node.copy(); deepEqual(copiedNode.alternatives.length, 2); @@ -372,7 +397,7 @@ test("copy", function() { }); test("createNextAlternative", function() { - var node = createCraftingNode(1, "Stick", undefined, __sampleRecipeBooks); + var node = createCraftingNode(1, "Stick", false, undefined, __sampleRecipeBooks); deepEqual(node.alternatives.length, 2); var firstAlternate = node.createNextAlternative(__sampleRecipeBooks); @@ -395,7 +420,7 @@ test("createNextAlternative", function() { }); test("depthFirstTraversal", function() { - var node = createCraftingNode(1, "Iron Gear", undefined, __sampleRecipeBooks); + var node = createCraftingNode(1, "Iron Gear", false, undefined, __sampleRecipeBooks); var expectedNames = ["Iron Ingot", "Birch Plank", "Stick", "Wooden Gear", "Stone Gear", "Iron Gear"]; var names = []; @@ -404,17 +429,17 @@ test("depthFirstTraversal", function() { }); test("findNodeWithAlternatives", function() { - var node = createCraftingNode(1, "Iron Gear", undefined, __sampleRecipeBooks); + var node = createCraftingNode(1, "Iron Gear", false, undefined, __sampleRecipeBooks); var nodeWithAlternatives = node.findNodeWithAlternatives(); deepEqual(nodeWithAlternatives.name, "Stick"); - node = createCraftingNode(1, "Stick", undefined, __sampleRecipeBooks); + node = createCraftingNode(1, "Stick", false, undefined, __sampleRecipeBooks); nodeWithAlternatives = node.findNodeWithAlternatives(); deepEqual(nodeWithAlternatives.name, "Stick"); }); test("getNodeAt", function() { - var node = createCraftingNode(1, "Electronic Circuit", undefined, __sampleRecipeBooks); + var node = createCraftingNode(1, "Electronic Circuit", false, undefined, __sampleRecipeBooks); deepEqual(node.getNodeAt([0]).name, "Insulated Copper Cable"); deepEqual(node.getNodeAt([1]).name, "Refined Iron"); deepEqual(node.getNodeAt([0, 0]).name, "Copper Cable"); @@ -423,7 +448,7 @@ test("getNodeAt", function() { }); test("getPosition", function() { - var node = createCraftingNode(1, "Electronic Circuit", undefined, __sampleRecipeBooks); + var node = createCraftingNode(1, "Electronic Circuit", false, undefined, __sampleRecipeBooks); deepEqual(node.getNodeAt([0]).getPosition(), [0]); deepEqual(node.getNodeAt([1]).getPosition(), [1]); deepEqual(node.getNodeAt([0, 0]).getPosition(), [0, 0]); @@ -432,8 +457,8 @@ test("getPosition", function() { }); test("setNodeAt", function() { - var ironGearNode = createCraftingNode(1, "Iron Gear", undefined, __sampleRecipeBooks); - var furnaceNode = createCraftingNode(1, "Furnace", undefined, __sampleRecipeBooks); + var ironGearNode = createCraftingNode(1, "Iron Gear", false, undefined, __sampleRecipeBooks); + var furnaceNode = createCraftingNode(1, "Furnace", false, undefined, __sampleRecipeBooks); ironGearNode.setNodeAt([1, 0, 0], furnaceNode); deepEqual(ironGearNode.children[1].children[0].children[0].name, "Furnace"); @@ -443,7 +468,7 @@ test("setNodeAt", function() { module("CraftingPlan"); /////////////////////////////////////////////////////////////////////////////////////////////// test("create: single complex plan", function() { - var plan = createCraftingPlan(1, "Electronic Circuit", __sampleRecipeBooks); + var plan = createCraftingPlan(1, "Electronic Circuit", false, __sampleRecipeBooks); deepEqual(plan.count, 1); deepEqual(plan.recipeName, "Electronic Circuit"); deepEqual(plan.alternatives.length, 1); @@ -451,7 +476,7 @@ test("create: single complex plan", function() { }); test("create: multiple simple plans", function() { - var plan = createCraftingPlan(1, "Stick", __sampleRecipeBooks); + var plan = createCraftingPlan(1, "Stick", false, __sampleRecipeBooks); deepEqual(plan.count, 1); deepEqual(plan.recipeName, "Stick"); deepEqual(plan.alternatives[0].recipe.input[0].name, "Birch Plank"); @@ -461,7 +486,7 @@ test("create: multiple simple plans", function() { }); test("create: multiple complex plans", function() { - var plan = createCraftingPlan(1, "Iron Gear", __sampleRecipeBooks); + var plan = createCraftingPlan(1, "Iron Gear", false, __sampleRecipeBooks); var firstResult = plan.alternatives[0].craft(); var secondResult = plan.alternatives[1].craft(); var thirdResult = plan.alternatives[2].craft();