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

Accuracy equasion requires division by 0?

Asked by 3 years ago

Heads up: This post will contain math.

So I'm trying to build an accuracy calculator for my rhythm project, but the equation to calculate the accuracy requires division by 0. In words, the equasion goes like this:

Find the average of the time between the keypress and the time they key was supposed to be pressed for every keypresses since the song began

Subtract the average by the true value

Divide that by the true value

Multiply by 100

This is all well and good, but in my case, the true value is 0, because a second difference of 0 seconds means the key was hit at the perfect time. But of course, you can't divide by 0, and doing so seems to result in math.huge.

How would I go about resolving this?

If you need my code, here you go:

local sounds = game.SoundService
local CAS = game.ContextActionService
local rep = game.ReplicatedStorage
local getLevel = require(rep.GetLevel)
local beat = 0
local multiplier = 1000
local active = {}
local secDifs = {}

local testLvl = getLevel.GetLevel('TestingLevel')

local selectedLvl = testLvl
local beatDur = 60 / selectedLvl['BPM']
local TPU = 1 / selectedLvl['Speed'] -- Short for Time per unit

local function ProcessKeyPress(color)
    print(color..' has been pressed!')

    local correctNote

    for i, v in ipairs(active) do
        if v[1] == color then
            correctNote = v
        end
    end

    if correctNote ~= nil then
 -- This is  the part to  focus on!  -- This is  the part to  focus on!  -- This is  the part to  focus on!

        print('Nice!')

        local secDif = math.ceil((math.abs(beat - correctNote[2]) * beatDur) * multiplier)

        table.insert(secDifs, secDif)

        local all = 0

        for i, v in ipairs(secDifs) do
            all += v
        end

        local average = all / #secDifs
        local accuracy = ((average - 0) / 0) * 100

        print(accuracy)

        rep.AddPoints:Fire(secDif)
        print(beat, correctNote[2], beat - correctNote[2],  math.abs(beat - correctNote[2]),  (math.abs(beat - correctNote[2]) * beatDur), ((math.abs(beat - correctNote[2]) * beatDur) * multiplier))
        print('beat: '..tostring(beat), 'correctNote[2]: '..tostring(correctNote[2]), 'secDif  before  math.ceil: '..tostring((math.abs(beat - correctNote[2]) * beatDur) * multiplier), 'secDif: ',  tostring(secDif))
    else
        print('Miss!')
    end

    local closest = workspace.Notes:GetChildren()[1]

    if closest ~= nil then
        for i, v in ipairs(workspace.Notes:GetChildren()) do
            if math.floor(math.abs(v.Position.X)) < math.floor(closest.Position.X) and v.Name == color then
                --closest.Color = Color3.new(1, 0, 0)

                closest = v
            end
        end

        if math.ceil(math.abs(closest.Position.X) - workspace.Strumline[color].Position.X) <= 3 then
            coroutine.resume(coroutine.create(function()
                closest.Color = Color3.new(1, 1, 0)

                --wait(0.3)

                closest:Destroy()
            end))
        end
    end
end

rep.TempStart.Event:Wait()

print('eyey')

local keybinds = {
    Red = nil,
    Blue = nil,
    Green = nil,
    White = nil
}

for i, keybind in ipairs(rep.Keybinds:GetChildren())  do
    for i, enum in ipairs(Enum.KeyCode:GetEnumItems()) do
        if string.sub(tostring(enum), 14, string.len(tostring(enum))) == keybind.Value then
            keybinds[keybind.Name] = enum
        end
    end
end

selectedLvl['Song']:Play()

CAS:BindAction('Press red', function(nagareteku, instate, toki, no, naka, de, demo)
    if instate ~= Enum.UserInputState.Begin then return end

    ProcessKeyPress('Red')
end, false, keybinds['Red'])
CAS:BindAction('Press blue', function(nagareteku, instate, toki, no, naka, de, demo)
    if instate ~= Enum.UserInputState.Begin then return end

    ProcessKeyPress('Blue')
end, false, keybinds['Blue'])
CAS:BindAction('Press Green', function(nagareteku, instate, toki, no, naka, de, demo)
    if instate ~= Enum.UserInputState.Begin then return end

    ProcessKeyPress('Green')
end, false, keybinds['Green'])
CAS:BindAction('Press white', function(nagareteku, instate, toki, no, naka, de, demo)
    if instate ~= Enum.UserInputState.Begin then return end

    ProcessKeyPress('White')
end, false, keybinds['White'])

local stTick = tick()
local permT = tick()

game:GetService('RunService').Heartbeat:Connect(function()
    beat += math.floor(((tick() - stTick) / beatDur) * 1000) / 1000 -- Reduce time to 3 decimals
    stTick = tick()
end)

for i, v in ipairs(selectedLvl['Chart']) do
    local activateKeyPress = coroutine.create(function()
        print(v[1]..' wait duration: '..tostring((v[2] * beatDur) - TPU * 3), 'unactivate wait duration: '..tostring(((v[2] * beatDur) - TPU * 3) + (TPU * 6)))

        wait((v[2] * beatDur) - TPU * 3)

        table.insert(active, v)

        print(v[1]..' active')

        wait(TPU * 6)

        print(v[1]..' not active')

        for I, V in ipairs(active) do
            if v == V then
                rep.AddPoints:Fire(-25)

                table.remove(active, I)
            end
        end
    end)

    local createKeys = coroutine.create(function()
        wait((v[2] * beatDur) - (TPU * 20))

        local keyClone = workspace.Strumline[v[1]]:Clone()
        keyClone.Parent = workspace.Notes
        keyClone.Transparency = 0

        print(workspace.Strumline[v[1]])

        keyClone.Position = workspace.Strumline[v[1]].Position - Vector3.new(20, 0, 0)

        local tween = game.TweenService:Create(keyClone, TweenInfo.new(
            TPU * 40,
            Enum.EasingStyle.Linear,
            Enum.EasingDirection.InOut
        ), {Position = workspace.Strumline[v[1]].Position + Vector3.new(20, 0, 0)})

        tween:Play()
    end)

    coroutine.resume(activateKeyPress)
    coroutine.resume(createKeys)
end

If you need the module script code and the bindable event code, here you also go:

local levels = {
    TestingLevel = {
        Song = game.SoundService.Tem,
        Speed = 32, --  32 units per second, or 32u/s
        BPM = 120,
        Chart = { -- Every table in the Chart represents a note. Properties: string button, num beat, num beatToReleaseAt
            {'Red',  10},
            {'Green',  11},
            {'Blue',  12},
            {'White',  13},
            {'Blue',  14},
            {'Green',  15},
            {'Red',  16, 21},
            {'Green',  17},
            {'Blue',  18},
            {'White',  19},
            {'Blue',  20},
            {'Green',  21},
            {'Red',  22, 27},
            {'Green',  24},
            {'Blue',  25},
            {'White',  26},
            {'Blue',  27},
            {'Green',  28},
            {'Red',  29, 34},
            {'Green',  30},
            {'Blue',  31},
            {'White',  32},
            {'Blue',  33},
            {'Green',  34},
            {'Red',  35, 45}
        }
    }
}
local module = {}

module.GetLevel = function(name)
    return levels[name]
end

return module

e

local rep = game.ReplicatedStorage
local frame = script.Parent
local points = 0

rep.AddPoints.Event:Connect(function(pointsToAdd)
    points += pointsToAdd

    frame.Score.Text = 'Points: '..tostring(points)

    print(points)
end)

rep.ChangeAccuracy.Event:Connect(function(accuracy)   -- Currently unused
    frame.Accuracy = tostring(accuracy)..'%'
end)

rep.TempStart.Event:Connect(function()
    script.Parent.Visible = true
end)

Anything is appreciated!

0
Just answering blindly here; cant you just use an id statement? If its 0 then make it 1 or something so then when it multiplies, it gives the highest score. AlexanderYar 788 — 3y
0
The issue here is not whether the players pressed the key with a second difference of 0. No matter the difference, the equation requires division by 0 unless I change something about the equasion. deeskaalstickman649 475 — 3y
0
Then change the equation. If your not smart enough to do it the first time, you will figure it out eventually. AlexanderYar 788 — 3y
0
How can I change the equation to still provide an accurate accuracy if the true value is 0? deeskaalstickman649 475 — 3y

Answer this question