Source: gameplay.js

/*
 *  2016 Maciej Wiecierzewski
 */

/** 
 * Gameplay related things
 * @namespace
 */
var gameplay = {};

/** Initialises variables */
gameplay.init = function()
{
    this.currentLevel = 0;
    this.symbolsImages = [];
}

/** Starts the tutorial */
gameplay.startTutorial = function()
{
    this.tutorialFinished = false;
    this.expressionNumber = 0;
    this.tutorialLevel = 0;
    
    this.initTutotialLevel();
    this.nextTutorialExpression();
}

gameplay.skipTutorial = function()  // looks redundant
{
    gameplay.initLevel();
}

/** initializes the level; used in tutorial mode */
gameplay.initTutotialLevel = function()
{
    this.setOperators(this.levelsData.tutorialLevels[this.currentLevel].operators);
    
    this.grammar = new Grammar(this.operators);
    this.expression = new Expression(this.grammar);
}

/** initializes the level */
gameplay.initLevel = function()
{
    this.setOperators(this.levelsData.levels[this.currentLevel].operators);
    
    var grammarAttr = this.levelsData.levels[this.currentLevel].grammarAttr;
    
    this.rulesProb = [];
    this.rulesProb['endRule'] = (grammarAttr['endRuleProb']) ? grammarAttr['endRuleProb'] : 0.1;
    this.rulesProb['nextSymbol'] = (grammarAttr['nextSymbolProb']) ? grammarAttr['nextSymbolProb'] : 1;
    this.rulesProb['0-aryOperator'] = (grammarAttr['0-aryOperatorProb']) ? grammarAttr['0-aryOperatorProb'] : 2;
    this.rulesProb['1-aryOperator'] = (grammarAttr['1-aryOperatorProb']) ? grammarAttr['1-aryOperatorProb'] : 2;
    this.rulesProb['2-aryOperator'] = (grammarAttr['2-aryOperatorProb']) ? grammarAttr['2-aryOperatorProb'] : 2;
    this.rulesProb['otherwise'] = (grammarAttr['otherwiseProb']) ? grammarAttr['otherwiseProb'] : 1;
    
    this.grammar = new Grammar(this.operators, this.rulesProb);
    
    this.expression = new Expression(this.grammar);
    this.expression.iterations = this.levelsData.levels[this.currentLevel].iterations;
    this.expression.minExpLength = this.levelsData.levels[this.currentLevel].minExpLength;
    this.expression.maxExpLength = this.levelsData.levels[this.currentLevel].maxExpLength;
    this.expression.expressionProbability();
    
    this.expressionNumber = 0;
    this.trials = 0;
    this.correctAnswers = 0;
}

/** Generates new expression; used tutorial mode */
gameplay.nextTutorialExpression = function()
{
    var expressions = this.levelsData.tutorialLevels[this.currentLevel].expressions;
    
    this.expressionNumber++;
    if(this.expressionNumber >= expressions.length)
    {
        this.tutorialFinished = true;
        return;
    }
        
    var expression = expressions[this.expressionNumber-1];
    this.expression.createFromString(expression);
    this.allCorrect = false;
}

/** Generates new expression */
gameplay.nextExpression = function()
{
    this.expressionNumber++;
    
    this.expression.generateExpression();
    this.allCorrect = false;
}

/**
 * Prepares array of 'Operator' objects and images array
 * @param {type} operators
 * @returns {gameplay.setOperators}
 */
gameplay.setOperators = function(operators)
{
    this.operators = [];
    this.symbolsImages = [];
    
    for(var i = 0; i < operators.length; i++)
    {
        if(operators[i].probability == undefined)
            operators[i].probability = 1;
        
        var operator = new Operator(operators[i].symbol,
            operators[i].precedence,
            operators[i].arity,
            operators[i].placement,
            operators[i].associativity,
            operators[i].probability);
            
        this.operators.push(operator);
        this.symbolsImages[operators[i].symbol] = operators[i].symbolImg;
    }
}

/**
 * 
 * @param {Array} order
 */
gameplay.checkSolution = function(order)
{
    this.trials++;
    
    var correctOrder = this.expression.opOrder;
    var correct = 0;
    this.result = new Array(correctOrder.length);
    
    for(var i = 0; i < correctOrder.length; i++)
    {
        if(correctOrder[i] === order[i])
        {
            this.result[i] = 1;
            correct++;
        }
        else if(order[i] !== 0)
        {
            this.result[i] = 2;
        }
    }
    
    if(correct === correctOrder.length)
    {
        this.allCorrect = true;
        this.correctAnswers++;
    }
}