diff --git a/js/builder.js b/js/builder.js index b10b071..24b82cf 100644 --- a/js/builder.js +++ b/js/builder.js @@ -164,7 +164,7 @@ function init_autocomplete() { let item_arr = []; if (eq == 'weapon') { for (const weaponType of weapon_keys) { - for (const weapon of itemLists.get(weaponType)) { + for (const weapon of itemLists[weaponType]) { let item_obj = itemMap.get(weapon); if (item_obj["restrict"] && item_obj["restrict"] === "DEPRECATED") { continue; @@ -176,7 +176,7 @@ function init_autocomplete() { } } } else { - for (const item of itemLists.get(eq.replace(/[0-9]/g, ''))) { + for (const item of itemLists[eq.replace(/[0-9]/g, '')]) { let item_obj = itemMap.get(item); if (item_obj["restrict"] && item_obj["restrict"] === "DEPRECATED") { continue; diff --git a/js/load.js b/js/load.js index afdc85c..eceed6d 100644 --- a/js/load.js +++ b/js/load.js @@ -10,7 +10,12 @@ let sets = new Map(); let itemMap; let idMap; let redirectMap; -let itemLists = new Map(); +let itemLists = {}; +// List of 'raw' "none" items (No Helmet, etc), in order helmet, chestplate... ring1, ring2, brace, neck, weapon. +for (const it of itemTypes) { + itemLists[it] = []; +} + /* * Load item set from local DB. Calls init() on success. */ @@ -189,11 +194,6 @@ async function load_init() { }); } -// List of 'raw' "none" items (No Helmet, etc), in order helmet, chestplate... ring1, ring2, brace, neck, weapon. -for (const it of itemTypes) { - itemLists.set(it, []); -} - let none_items = [ ["armor", "helmet", "No Helmet"], ["armor", "chestplate", "No Chestplate"], @@ -241,7 +241,7 @@ function init_maps() { //console.log(items); for (const item of items) { if (item.remapID === undefined) { - itemLists.get(item.type).push(item.displayName); + itemLists[item.type].push(item.displayName); itemMap.set(item.displayName, item); if (none_items.includes(item)) { idMap.set(item.id, ""); diff --git a/js/skillpoints.js b/js/skillpoints.js index 1001de8..86b130c 100644 --- a/js/skillpoints.js +++ b/js/skillpoints.js @@ -117,6 +117,7 @@ function calculate_skillpoints(equipment, weapon) { let allFalse = [0, 0, 0, 0, 0]; if (consider.length > 0 || noboost.length > 0 || crafted.length > 0) { // Try every combination and pick the best one. + construct_scc_graph(consider); for (let permutation of perm(consider)) { let activeSetCounts = new Map(static_activeSetCounts); let has_skillpoint = allFalse.slice(); @@ -216,3 +217,45 @@ function calculate_skillpoints(equipment, weapon) { document.getElementById('stack-box').textContent = output_msg; return [equip_order, best_skillpoints, final_skillpoints, best_total, best_activeSetCounts]; } + +function construct_scc_graph(items_to_consider) { + let nodes = []; + for (const item of items_to_consider) { + nodes.push({item: item, children: [], parents: [], visited: false}); + } + let root_node = { + children: nodes, + parents: [], + visited: false + }; + // Dependency graph construction. + for (const node_a of nodes) { + const {item: a, children: a_children} = node_a; + for (const node_b of nodes) { + const {item: b, parents: b_parents} = node_b; + for (let i = 0; i < 5; ++i) { + if (b.reqs[i] < a.reqs[i] && b.skillpoints[i]) { + a_children.push(node_b); + b_parents.push(node_a); + break; + } + } + } + } + const res = [] + /* + * SCC graph construction. + * https://en.wikipedia.org/wiki/Kosaraju%27s_algorithm + */ + function visit(u, res) { + if (u.visited) { return; } + u.visited = true; + for (const child of u.children) { + if (!child.visited) { visit(child, res); } + } + res.push(u); + } + visit(root_node, res); + res.reverse(); + console.log(res); +}