I'm trying to make a small runeword builder for diablo 2.
The user could list the runes he owns and the algorithm should show which runewords are possible to build.
I have built the algorithm and the most important part works. However, it has become very cumbersome and I wanted to ask if someone can find a simpler and clearer solution to this problem.
Here is the source of the most important part:
(full version: https://github.com/borsTiHD/diablo2-runewords-companion/blob/main/pages/runewords.vue )
calculatedRunewordList() {
// Reducing item stock and calculates how many items the user has
// Returns array of runeword names, that can be build with the stock
// https://stackoverflow.com/a/6300596/7625095
const itemsInStock = this.getInventory.reduce((acc, obj) => { return acc + obj.value }, 0)
if (itemsInStock <= 0) {
// Returning complete list with names, if the user dont have any item in stock
return this.getRunewordList.map((runeword) => runeword.name)
}
// List with possible runewords later on
const possibleRunewords = []
this.getRunewordList.forEach(({ name, recipe }) => {
let valid = true // Validation check
const currentStock = JSON.parse(JSON.stringify(this.getInventory)) // Getting clone of current stock from the inventory - important so the clone could be manipulated without changing the real inventory
// Looping through every rune the runeword needs
recipe.forEach((rune) => {
// Checking if the needed rune is in our inventory and if the value is greater than 1...
// We will reduce on stock value - important, because some runewords have more than one of the same rune (eg. 'Ko, Ko, Mal' -> 'Sanctuary')
const stockItem = currentStock.find((runeObj) => runeObj.name === rune)
if (stockItem && stockItem.value > 0) {
stockItem.value-- // Reduce stock value by one
} else {
// The needed rune is not in the current stock
// TODO -> Check if the needed rune could be made by an upgrade with other runes (need to check rune recipes)
valid = false // -> validation failed
}
})
// Pushes valid runeword name
if (valid) { possibleRunewords.push(name) }
})
return possibleRunewords
}
This method returns an array and is compared to display the possible runewords. Thanks :)
//Edit:
An example of what the thing is doing.
The user has the following runes:
const store = [
{ name: 'Tir', value: 1 },
{ name: 'Ral', value: 1 },
{ name: 'Tal', value: 1 },
{ name: 'Sol', value: 1 },
{ name: 'Ko', value: 2 },
{ name: 'Mal', value: 1 }
]
The result should display the following runewords:
const possibleRunewords = ['Leaf', 'Prudence', 'Sanctuary', 'Insight']
/*
// Needed recipes
Leaf: Tir, Ral
Prudence: Mal, Tir
Sanctuary: Ko, Ko, Mal ('Ko' is needed twice)
Insight: Ral, Tir, Tal, Sol
*/