Element mixing algorithm

Hi, the title pretty much says it all, I’m making a game like Wakcy Wizards and what I’m trying to do is mixing the player’s elements inside his backpack to get a matching potion with the same elements.

I have tried many ways to achieve this but none of them seemed to do the job like I want it to.
I tried having requirments for each potion then looping through every potion to see if their requirments match what the player has

local module = {
	["potion1"] = {
		"Flower",
		"Water"
	},
	
	["potion2"] = {
		"Flower",
		"Water",
		"Stone"
	}
}

return module

However, I’m looking for a better approach, any idea on how to make it would help me alot. Thanks!

Alright so it wont exactly be like Wacky Wizards if you do, you’ll have to provide me a more in-depth description of how it works.

First of all we will make an array. In this array we will store all the ingredients you put in it.

local ingredients = {}

To add an ingredient we will use the following:

table.insert(ingredient, "Flower")

Now after this the table would look like this:

{
   [1] = "Flower",
}

Now from here we will make it so that you can pull a potion out of the result.

We will first need to loop through all possible potions:

local function findPotion(ingredients)
   local foundPotion = nil
   for potionName : string, potionIngredients : {string} in pairs(potions)
      ... 
   end
   return foundPotion
end

Now we will loop per ingredient: (Replace this with the ...)

local validPotion = true

for i, ingredient in pairs(ingredients) do
   -- First get how many ingredients are found before
   local amount = 1
   for j, ingredient2 in pairs(ingredients) do
      if j >= i then break end -- if the indexes are the same then stop
      if ingredient == ingredient2 then amount += 1 end
   end
   -- now check if the potion ingredients has it:
   if not table.find(potionIngredients. ingredients, amount) then 
      validPotion = false
      break
   end
end

-- We found the correct potion
if validPotion then
   foundPotion = potionName
   break 
end
1 Like

Thanks, that’s the same logic I went with, but what made me hesitate is having loops inside loops which made me think it’s bad practice, anyways I’ll try to remake it tomorrow. Thanks alot!

Aha, first I suggest to make something which somewhat works and work from there, for example this is more an anti-multiple ingredients parts, to make sure if the other ingredients are valid.

Oh yeah actually a problem I noticed, if you have too little ingredients it’ll return valid so let’s fix that.

Now we have to make sure the potion and the player have the same amount of ingredients, because if you have too much of something it is of course wrong.

-- inside the first for loop
if #playerIngredients == potionIngredients then
   ... -- second for loop
end

Now we are set!

1 Like

I see what you did there, but I ended up with something similar and it works fine

local sort_potion = function(...)
	local ingredients = ...;
	local score_tbl = {} -- score tracker for potions similar in elements number
	
	local highest = nil 
	local winner = nil -- potion that is chosen
	
	table.clear(score_tbl)

	for potion, required in potionmodule do
		if len(required) == #ingredients then --  if the elemnts the player has is the same as the potion
			score_tbl[potion] = 0 -- insert that potion inside the score table
			
			for index, ingredient in ingredients do
				if required[tostring(ingredient)] then
					score_tbl[potion]+= 1  -- if the potion inserted inside the score table has the same elm the player has it +1
				end
			end
			
		end
	end
	
	for potionName, score in score_tbl do
		if len(potionmodule[potionName]) == score then -- checks if the mixture is the same as the one we're trying to make
			winner = potionName
		end
	end
	
	print(winner)
	return winner

end

Sure that would work somewhat except for when you have multiple ingredients.
If for example the potion recipe is:

local Recipe = {"Flower", "Water"}

And you fill the cauldron with

local cauldron = {"Flower", "Flower"} 

It will still result in that exact potion (because it gives 2 points). Instead I suggest something more like what I did.

Another issue can be if the amount of items in the cauldron and the recipe are the same, but you have nothing which is the same then it can still give you exactly that potion.