Calculating quiz score, with weights and partial credit There is a quiz-game with simple rules. You have to guess one of three options. Each option has a particular weight, for example:


Option 1: 20 points 
Option 2: 30 points 
Option 3: 50 points


If player guesses the right option, he gets all amount of points. If not, he gets a part of those points:

 User choice || Right Answer || Score
      1             1            100%
      2             1            75%
      3             1            50%
      1             2            75%
      2             2            100%
      3             2            75%
      1             3            25%
      2             3            50%
      3             3            100%


You can easilly write a method to calculate score:

calcRateScore: function(fact, user) {

    var rateScore = 0;

    switch (fact) {
        case 1:
            switch (user) {
                case 1:
                    rateScore = 20;
                    break;
                case 2:
                    rateScore = 20 * 0.75;
                    break;
                case 3:
                    rateScore = 20 * 0.5;
                    break;
            }
            break;
        case 2:
            switch (user) {
                case 1:
                    rateScore = 30 * 0.75;
                    break;
                case 2:
                    rateScore = 30;
                    break;
                case 3:
                    rateScore = 30 * 0.75;
                    break;
            }
            break;
        case 3:
            switch (user) {
                case 1:
                    rateScore = 50 * 0.25;
                    break;
                case 2:
                    rateScore = 50 * 0.5;
                    break;
                case 3:
                    rateScore = 50;
                    break;
            }
            break;
    }

    return rateScore;
}


It works, but it looks horrible. How do I get rid of all this switch statements?
You don't seem to have any concept of objects or other reusable code in what you have written.  I would take a step back and think about what real-word objects you are trying to model.  At a minimum, I would think you would need three different concepts:


Answer Option: a single answer option that will be related to the question and hold logic on it fractional value as an answer.
Question: which stores a related set of answers and provides logic on calculating score for the question.
Quiz: which represents an ordered collection of questions.


Let me start by modeling the objects noted above:

// let's build a question class
function Question(text, baseScore) {
   this.text = null;
   this.answerOptions = [];
   this.selectedAnswerIndex = null;
   this.baseScore = null;

   this.setText(text);
   this.setBaseScore(baseScore);
}

// add methods to question class
Question.prototype = {
    setText: function(text) {
        this.text = text;

        // return the question object to allow for chaining
        return this;
    },
    setBaseScore: function(score) {
        this.baseScore = score;

        return this;
    },
    addAnswerOption: function(answer) {
        if(!answer instanceof Answer) {
            console.log('Give me an answer object!');
            return null;
        }
        this.answerOptions.push(answer);

        return this;
    }
    setAnswerIndex: function(idx) {
        this.selectedAnswerIndex = idx;

        return this;
    },
    getScore: function() {
        if(this.selectedAnswerIndex === null || this.baseScore === null) {
            return null;
        }
        var ansIdx = this.selectedAnswerIndex;
        var scoreModifier = this.answerOptions[ansIdx].questionScoreModifier;
        if(scoreModifier === null) {
            return null;
        }

        return this.baseScore * scoreModifier;
    }
};

// build answer class
function Answer(text, modifier) {
    this.text = null;
    this.questionScoreModifier = null;

    this.setText(text);
    this.setScoreModifier(modifier);
};

// answer class methods
Answer.prototype = {
    setText: function(text) {
        this.text = text;

        return this;
    },
    setScoreModifier(value) {
        this.questionScoreModifier = value;

        return this;
    }
};

// build quiz class
function Quiz(title) {
    this.title = null;
    this.questions = [];
    this.score = null;

    this.setTitle(title);
}

// quiz class methods
Quiz.prototype = {
    setTitle: function(text) {
        this.title = text;

        return this;
    },
    addQuestion: function(question) {
        if(question instanceof Question) {
            console.log('Give me a Question object!');
            return null;
        }
        this.questions.push(question);

        return this;
    },
    answerQuestion: function(questionIndex, answerIndex) {
        this.questions[questionIndex].setAnswerIndex(answerIndex);

        return this;
    },
    getTotalScore: function() {
        var total = 0;
        for(i=0; i&lt;this.questions.length; i++) {
            var questionScore = this.questions[i].getScore();
            if (questionScore !== null) {
                total +== questionScore;
            }
        }
        this.score = total;

        return total;
    }
}


You now have the basic building blocks to create your quiz. You could include this code anywhere and have a reusable quiz.

Now you need to build the quiz itself.  That may look like this:

// build your quiz
var myQuiz = new Quiz('My cool quiz');

// now let build some questions
var question1 = new Question(
    'This is text of question 1. What is correct answer?',
    50 
);

// now attach answers to the question
question1
    .addAnswerOption(new Answer('Answer worth 50%', .5))
    .addAnswerOption(new Answer('Answer worth 100%', 1))
    .addAnswerOption(new Answer('Answer worth 25%', .25));

// add the question to the quiz
myQuiz.addQuestion(question1);

// you could continue code like above to fill out your quiz


Finally, we can start working with the quiz to set answers and get scores.

// now let's set a user answer on a question
// we can assume that we get both the question index
// and the answer index for the question from elsewhere in javascript
// for example from clicking on answer selection
var questionIdx = {some value};
var answerIdx = {some value};

// set the answer
myQuiz.answerQuestion(questionIdx, answerIdx);

// we can also get total quiz score
var totalQuizScore = myQuiz.getTotalScore();

// or we can get scores on individual questions
var question1Score = myQuiz.questions[0].getScore();


Note that the outcome here is very reusable code that could be pretty much dropped anywhere within a larger application to implement your quiz.  In a real application you may also add something like a quiz rendering class to be able to render the quiz using javascript (and to separate display of quiz from core quiz objects).

It also makes it much easier to modify your code in the future. You need to change how questions are scored? - well just change the scoring logic within the answer and question classes as implemented in those class properties and methods.  As long as you keep the contract (i.e method calls) with the quiz, the quiz class itself would likely not need to be modified.