greyBow
greyBow

Reputation: 1348

Formula for Calculating a Final Score

I'm stuck on one final piece of a calculation puzzle below. I know how to generate a percentage score of correct parts from total correct possible parts ((correctNumPartsOnBoard / totalPossibleCorrectParts)*100) but I want to the final percentage score to factor in the number the incorrect parts on the board as well. (even if all the right parts are on the board you still won't get 100% if there are also incorrect parts). Right now my current formula percentCorrectParts = ((correctNumPartsOnBoard / totalPossibleCorrectParts) / totalNumPartsOnBoard) * 100); is wrong and I'm having trouble pinpointing the correct calculation.

So, the way the calc would need to work is: a user needs to match one of the six possible animals, each animal has around 15 correct parts, but users can also drag incorrect parts onto the board (parts from the other animals are still visible so they could drag a different set of legs or horns on a lizard head, they could make frankenstein type creatures as well this way). So the total number of parts available would be 6*15. But seeing as how they're not all correct they would influence the score as well by bringing the overall score average of pieces on the board down.

What's the correct formula for this?

// Scoring System

using UnityEngine;
using System.Linq;
using System.Collections.Generic;

public class ScoreManager : MonoBehaviour
{
    public List<string> totalBuildBoardParts;       // Running list of all parts on board (by Tag)
    public int numCorrectPartsOnBoard;
    public int numIncorrectPartsOnBoard;
    public int totalPossibleCorrectParts;
    public float percentCorrectParts;

    void Start()
    {
        GameObject gameController = GameObject.FindGameObjectWithTag("gc");
        GameSetup gameSetup = gameController.GetComponent<GameSetup>();

        totalPossibleCorrectParts = gameSetup.totalPossibleCorrectParts;
        Debug.Log("TOTAL POSSIBLE CORRECT PARTS ARE: " + totalPossibleCorrectParts);
    }

    public void AddAnimalPartByTag(string tag)
    {
        // Add object tag to List
        totalBuildBoardParts.Add(tag);

        Debug.Log ("Added an object tagged as: " + tag);

        GameObject gameController = GameObject.FindGameObjectWithTag("gc");
        GameSetup gameSetup = gameController.GetComponent<GameSetup>();

        if (tag == gameSetup.activeTag)
        {
            numCorrectPartsOnBoard ++;

            Debug.Log ("There are " + numCorrectPartsOnBoard + " correct parts on the board");
        } else {
            numIncorrectPartsOnBoard ++;
        }

        CalculateScore();
    }

    public void RemoveAnimalPartByTag(string tag)
    {
        // Add object tag to List
        totalBuildBoardParts.Remove(tag);

        Debug.Log ("Removed an object tagged as: " + tag);

        GameObject gameController = GameObject.FindGameObjectWithTag("gc");
        GameSetup gameSetup = gameController.GetComponent<GameSetup>();

        if (tag == gameSetup.activeTag)
        {
            numCorrectPartsOnBoard --;

            Debug.Log ("There are " + numCorrectPartsOnBoard + " correct parts on the board");
        } else {
            numIncorrectPartsOnBoard --;
        }

        CalculateScore();
    }

    public void CalculateScore()
    {
        float totalNumPartsOnBoard = totalBuildBoardParts.Count();
        float correctNumPartsOnBoard = numCorrectPartsOnBoard; 
        percentCorrectParts = ((correctNumPartsOnBoard / totalPossibleCorrectParts) / totalNumPartsOnBoard) * 100);
        Debug.Log ("Your current score is: " + percentCorrectParts);
    }
}

Upvotes: 0

Views: 154

Answers (3)

maraaaaaaaa
maraaaaaaaa

Reputation: 8173

I think your formula should look like this:

int correctParts;
int possibleCorrect;
int incorrectParts;
int parts;

float percentFinished =
    Mathf.Max((((float)correctParts/possibleCorrect)   // Correct percent
    - ((float)incorrectParts/parts))                   // Minus incorrect percent
    * 100f,                                            // Normalized to 100
    0f);                                               // Always a minimum of 0

Also with this formula unlike other answers, you don't have to use all of the parts to get 100%, just get the total possible correct parts which doesn't necessarily have to use up all of your parts ;)

Scenario

Lets say you have 100 parts, with 3 right and 3 wrong. Total right we are aiming for here is 20.

int correctParts = 3;
int possibleCorrect = 20;
int incorrectParts = 3;
int parts = 100;

float percentFinished =
    Mathf.Max((((float)correctParts/possibleCorrect)   // Correct percent is 0.15 or 15%
    - ((float)incorrectParts/parts))                   // Minus incorrect percent which is .03 or 3%
    * 100f,                                            // Normalized to 100 which gives us 15% - 3% = 12%
    0f);                                               // Always a minimum of 0

Upvotes: 2

Ren
Ren

Reputation: 59

I think your final (%age) score should be: correctNumPartsOnBoard / totalNumPartsOnBoard * 100

If you have 80 correctparts and 20 incorrect then the total parts is 100 and you've got 80 of them correct so you should score 80% like this: 80 / (80+20) * 100

Upvotes: 0

Pierre-Luc Pineault
Pierre-Luc Pineault

Reputation: 9201

Your formula is probably correct. However, your datatypes are not.

You are currently doing an integer division, which results in an int too. So let's say that correctNumPartsOnBoard is 3 and totalPossibleCorrectParts is 5, 3/5 gives 0 because an int does not have any decimals.

You need to cast one of the two operands in the division as a datatype with decimals ( float, double or decimal for example):

percentCorrectParts = ((correctNumPartsOnBoard / (float)totalPossibleCorrectParts) / totalNumPartsOnBoard) * 100);

By setting denominator totalPossibleCorrectParts as a float, the first division will return a float. That float is then used in the second division, also returning correctly a float.

Upvotes: 3

Related Questions