How to convert function to for loop

Code:

local player = game.Players.LocalPlayer

local leaderstats = player:WaitForChild("leaderstats")

local stage = leaderstats.Stage

local DifficultyDisplay = script.Parent.DifficultyDisplay

local StageDifficulties = {
	Easy = {1,4,"Easy"};
	Medium = {5,9,"Medium"};
	Hard = {10,14,"Hard"};
	Insane = {15,18,"Insane"};
}

local DifficultyColors = {
	["Easy"] = Color3.fromRGB(71, 213, 0);
	["Medium"] = Color3.fromRGB(223, 104, 0);
	["Hard"] = Color3.fromRGB(240, 40, 0);
	["Insane"] = Color3.fromRGB(182, 78, 241);
}

local function FindPlayerDifficulty(PlrStage)
	
	if PlrStage >= StageDifficulties.Easy[1] or PlrStage <= StageDifficulties.Easy[2] then
		
		return "Easy"
		
	elseif PlrStage >= StageDifficulties.Medium[1] or PlrStage <= StageDifficulties.Medium[2] then

		return "Medium" 
		
	elseif PlrStage >= StageDifficulties.Hard[1] or PlrStage <= StageDifficulties.Hard[2] then

		return "Hard"
		
	elseif PlrStage >= StageDifficulties.Insane[1] or PlrStage <= StageDifficulties.Insane[2] then

		return "Insane" 
		
	end
	
end

stage:GetPropertyChangedSignal("Value"):Connect(function()
	
	DifficultyDisplay.Text = FindPlayerDifficulty(stage.Value)
	
	DifficultyDisplay.TextColor3 = DifficultyColors[DifficultyDisplay.Text]
	
end)

DifficultyDisplay.Text = FindPlayerDifficulty(stage.Value)

DifficultyDisplay.TextColor3 = DifficultyColors[DifficultyDisplay.Text]

So I have no issues with this I am just wondering if I could add a for loop to the function in this script and if so how?

1 Like
for difficulty, data in StageDifficulties do
   -- 'data' is the table
   if PlrStage >= data[1] or PlrStage <= data[2] then
       return difficulty -- return the key, "Easy", "Medium", etc
   end
end

it would look like this:

local function FindPlayerDifficulty(PlrStage)
	for i,v in pairs(StageDifficulties) do
		if PlrStage >= v[1] and PlrStage <= v[2] then
			return v[3]
		end
	end
end

@HugeCoolboy2007’s should work just as well.

gives me incorrect the difficulty

i think i am lvl 1 or 2 but it gives me “Hard”

My script was mainly just for example:

local plrDifficulty = "Unknown" -- default

for difficulty, data in StageDifficulties do
   	if math.clamp(PlrStage, data[1], data[2]) == PlrStage then
       	plrDifficulty = difficulty -- sets the variable as the current difficulty that matches the condition
   	end
end
	
return plrDifficulty

It’s pretty simple:

local StageDifficulties = {
	Easy = {1,4,"Easy"};
	Medium = {5,9,"Medium"};
	Hard = {10,14,"Hard"};
	Insane = {15,18,"Insane"};
}

local function FindPlayerDifficulty(PlrStage) 
	local ascendingOrder = {"Easy", "Medium", "Hard", "Insane"}
	
	for _, difficulty in ascendingOrder do
		local data = StageDifficulties[difficulty]
				
		if PlrStage <= data[2] then
			return difficulty
		end
	end
	return "Unknown"
end

Examples:

print(FindPlayerDifficulty(3)) --Easy
print(FindPlayerDifficulty(9)) --Medium
print(FindPlayerDifficulty(11)) --Hard
print(FindPlayerDifficulty(17)) --Insane	
print(FindPlayerDifficulty(24)) --Unknown

It’s a bit tricky because Lua’s dictionaries aren’t ordered, which means when you iterate (loop) through it, it’ll give us a random order, so we define an ascending order of the difficulties and lie upon them.

As we are already making the difficulty check from the smallest to the largest (relative to the player’s level), you don’t need the minimum level for such difficulty & the keys for the StageDifficulties can already be used, so there’s no need for the values to be tables but rather just a number, but as I don’t know if you’re using these for something else I’d preferred to separate this solutions

local StageDifficulties = {
	Easy = 4;
	Medium = 9;
	Hard = 14;
	Insane = 18;
}

local function FindPlayerDifficulty(PlrStage) 
	local ascendingOrder = {"Easy", "Medium", "Hard", "Insane"}
	
	for _, difficulty in ascendingOrder do
		local data = StageDifficulties[difficulty]
				
		if PlrStage <= data then
			return difficulty
		end
	end
	return "Unknown"
end

can you please explain what this line is

This locks the value between the first and second value in the table, if the actual value of PlrStage is the locked value, the user is at the current difficulty:

-- another example
local value = 12

local max = 8
local min = 3

local lockedValue = math.clamp(value, min, max)
print(lockedValue == realValue)
-- Prints 'false' because 12 is not in between 8 and 3

math.clamp returns a number that is either in between the minimum or maximum value, or if the number is the minimum or maximum, it returns that instead:

local n = 20

local max = 40
local min = 35

local value = math.clamp(n, min, max)
print(value, n)
-- Since 'n' is 20 and is not in between 40 and 35, 'value' would be 35 since that's the minimum value

Yes

1 Like

So what it’s basically doing is checking if the PlrStage is a number that is visible in between the other 2 values?

I love your explanation on math.clamp, but i noticed you stated one thing twice:

These statements in the sentence are the exact same.

EDIT —
You could also edit it to be like this:

math.clamp returns a number that is either in between the minimum or maximum value, or if the value is the minimum or maximum, then it returns that instead:

1 Like

Thanks for pointing that out! I’ll edit my reply now

1 Like

Sometimes but not always I get this error

image

Code:

local player = game.Players.LocalPlayer

local leaderstats = player:WaitForChild("leaderstats")

local stage = leaderstats.Stage

local DifficultyDisplay = script.Parent.DifficultyDisplay

local StageDifficulties = {
	["Easy"] = {1,4,Color3.fromRGB(71, 213, 0)};
	["Medium"] = {5,9,Color3.fromRGB(223, 104, 0)};
	["Hard"] = {10,14,Color3.fromRGB(240, 40, 0)};
	["Insane"] = {15,18,Color3.fromRGB(182, 78, 241)};
}

local function DifficultyInfo(PlrStage, Objective)
	
	if Objective == "Difficulty" then
		
		for difficulty, data in StageDifficulties do

			if math.clamp(PlrStage, data[1], data[2]) == PlrStage then

				return difficulty

			end

		end
		
	else
		
		for difficulty, data in StageDifficulties do

			if math.clamp(PlrStage, data[1], data[2]) == PlrStage then

				return data[3]

			end

		end
		
	end
	
end

stage:GetPropertyChangedSignal("Value"):Connect(function()
	
	DifficultyDisplay.Text = DifficultyInfo(stage.Value, "Difficulty")
	
	DifficultyDisplay.TextColor3 = DifficultyInfo(stage.Value, "Difficulty Color")
	
	
end)

DifficultyDisplay.Text = DifficultyInfo(stage.Value, "Difficulty")

DifficultyDisplay.TextColor3 = DifficultyInfo(stage.Value, "Difficulty Color")

Line #55 is: DifficultyDisplay.Text = DifficultyInfo(stage.Value, “Difficulty”)

This is because neither of the loops returned a value, just add

return "Unknown"

To the bottom of the DifficultyInfo function. Though, I propose this as a better function:

local function DifficultyInfo(PlrStage)
	for difficulty, data in StageDifficulties do
		if math.clamp(PlrStage, data[1], data[2]) == PlrStage then
			return difficulty, data[3] -- returns the name and the color
		end
	end
	
	return "", Color3.fromRGB() -- return 2 default values
end

local difficulty, color = DifficultyInfo(stage.Value)

But the error occurs sometimes not always

It does return values because I have a return set there and I have a if statement for the objective for what to return

If you have data that is being set to the value in leaderstats, that may be causing the issue; Sometimes the data may have been loaded when the script runs, or other times it hasn’t.

Since the default value for an IntValue is 0 and 0 doesn’t exist as a level, that could be your issue