Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
2

Pick a value with the highest number?

Asked by
Vawx 10
9 years ago

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
0
I'm not the best scripter, although other ways to achieve this is appreciated. Vawx 10 — 9y
0
I really didn't think I'd get that many answers, thank you all allot. Vawx 10 — 9y
0
Also I forgot a bool values is true or false, I corrected. Vawx 10 — 9y

3 answers

Log in to vote
3
Answered by
BlueTaslem 18071 Moderation Voter Administrator Community Moderator Super Administrator
9 years ago

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.

0
Holy... You put so much time into this. I really can't thank you enough, appreciated. Vawx 10 — 9y
Ad
Log in to vote
1
Answered by 9 years ago

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! :)

0
Thanks a ton :) Vawx 10 — 9y
Log in to vote
0
Answered by 9 years ago

-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!

Answer this question