Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Pick a value with the highest number?

Say there are 3 values in Workspace, like this.

Value1 = workspace.Value1
Value2 = workspace.Value2
Value3 = workspace.Value3

Also imagine that there is a voting GUI with 3 options (like a next minigame chooser), they pick an option and it adds +1 to the value they picked.

Now my problem is how would I write a code that detects the value with the highest number.

If you know how to do this just use an example and do this:

if Value1 (was picked) then
	print("This mini-game was chosen")
end

3 comments

0

I'm not the best scripter, although other ways to achieve this is appreciated.

0

I really didn't think I'd get that many answers, thank you all allot.

0

Also I forgot a bool values is true or false, I corrected.

3 answers

✓ Accepted answer

A simple way would be to

  1. determine the biggest value
  2. determine the first of the values that has the biggest

If there are only three, you could implement it something like this:

local most = math.max( one.Value, two.Value, three.Value )
-- takes the maximum of the three

if most == one.Value then
	-- one was largest
elseif most == two.Value then
	-- two was largest
else
	-- three was largest
end

It would probably be better to use a list, however.

local values = {one, two, three}
local largest = -1 -- (assuming they are all positive)
for _, value in pairs(values) do
	largest = math.max(largest, value.Value)
end

for i, value in pairs(values) do
	if largest == value.Value then
		-- value was picked! (Use its name or `i` or whatever)
	end
end

This has a deficiency, though, in that if there is a tie it will always pick the "first" one.

We should probably pick randomly among all the maximums:

local values = {one, two, three}
local largest = {}
local best = -1
for _, value in pairs(values) do
	-- We can cleverly avoid two loops this time
	local v = value.Value
	if v > best then
		largest = {value}
	elseif v == best then
		table.insert(largest, value)
	end
end

local choice = largest[math.random(#largest)]
-- a random one of the largest

A fairer approach

For map selection, though, I think picking only the plurality is unfair. Imagine there are three people playing a game, two of them are friends. The two friends are talking to each other and always want to play the same map as each other. So whatever the third person votes for doesn't matter.

Thus 33% of the people never get a say in the vote.

It would be fairer if everyone could count.

In that case, we want a weighted selection.

local one = workspace.DumbGame
local two = workspace.WonderfulGame
local values = {one, two, workspace.OtherChoice, workspace.FunGame}

local totalWeight = 0
for _, value in pairs(values) do
	totalWeight = totalWeight + value.Value
end
-- totalWeight is in effect the number of votes cast
-- (but works for fractional numbers too)

local stop = math.random() * totalWeight -- which vote to stop on
local choice, choiceName
for i, value in pairs(values) do
	stop = stop - value.Value
	if stop <= 0 then
		-- value was the one that was chosen!
		choice = value
		choiceIndex = i
		choiceName = value.Name
		break -- stop looking
	end
end

if choice == one then -- one way to do it
elseif choice == values[2] then -- another way to do it
elseif choiceIndex == 3 then -- a third way to do it
elseif choiceName == "FunGame" then -- a fourth way to do it

This last one is harder to see that it's correct. Here is how it works:

--Here are the choices:
[ 10 ][ 4 ][ 2][ 20 ]
-- There are 36 votes cast. Thus we would hope the percentages
-- are:
[ 28% ][ 11% ][ 6% ][ 55% ]

-- We can consider the above as the "lengths" of runs that add up to 100%
-- Then we number it like this:

0% [one] 28% [two] 39% [three] 45% [four] 100%

-- Now we pick a random number, say, 40%. This landed between 39% and 45%, so
-- choice 3 was picked. Only 6% of numbers (those between 39% and 45%) could
-- land here -- which is what we stated we originally wanted.

1 comment

0

Holy... You put so much time into this. I really can't thank you enough, appreciated.

I decided to create a modular way of doing this.

local value_location = workspace
local values_raw = {"Value1", "Value2", "Value3"}
local values = {}

if (#values_raw == 0) then return end -- no values!

for _, v in pairs(values_raw) do
	local value = value_location:FindFirstChild(v)

	if (value) then
		table.insert(values, value)
	end
end

if (#values == 0) then return end -- no actual values

local chosen

for _, v in pairs(values) do
	if (not chosen) then
		chosen = v
	else
		if (v.Value > chosen.Value) then
			chosen = v
		elseif (v.Value == chosen.Value) then
			local r = math.random(2)
			
			if (r == 1) then
				chosen = v
			end
		end
	end
end

if (not chosen) then
	chosen = values[math.random(#values)]
end

If this doesn't work, I'm sorry, I ran short on time to finish this. However, if you'd like anything to be explained, please do ask me of it, and I'll try to explain it when I have time once more.

I hope this helps! :)

1 comment

0

Thanks a ton :)

-side note- I am not an experienced scripter, if this does not work, I am sorry!!!

you could do greater than

if Value1 > Value2 then
	print("Whatever happens for value1")
else
	print("whatever happens for value2")

to add a third it would be extremely repetitive scripting, you would have to get a more advanced scripter to do that as it would have elseif and more else and thans, but this script should work for 2!

This discussion is preserved as it was. New answers, comments, and votes are closed.