File indexing completed on 2024-05-12 15:21:14

0001 /* GCompris - comparator.js
0002  *
0003  * SPDX-FileCopyrightText: 2022 Aastha Chauhan <aastha.chauhan01@gmail.com>
0004  *
0005  * Authors:
0006  *   Aastha Chauhan <aastha.chauhan01@gmail.com>
0007  *   SPDX-License-Identifier: GPL-3.0-or-later
0008  */
0009 .pragma library
0010 .import GCompris 1.0 as GCompris
0011 .import "qrc:/gcompris/src/core/core.js" as Core
0012 
0013 var numberOfLevel;
0014 var numberOfSubLevel;
0015 var items;
0016 
0017 function start(items_) {
0018     items = items_;
0019     numberOfLevel = items.levels.length;
0020     items.currentLevel = Core.getInitialLevel(numberOfLevel);
0021     items.score.currentSubLevel = 0;
0022     initLevel();
0023 }
0024 
0025 function stop() {
0026 }
0027 
0028 function initLevel() {
0029     items.dataListModel.clear();
0030     items.numberOfRowsCompleted = 0;
0031     items.background.resetSelectedButton();
0032     var currentDataset = items.levels[items.currentLevel];
0033     var minValue = currentDataset.minValue;
0034     var maxValue = currentDataset.maxValue;
0035     var numberOfEquations = currentDataset.numberOfEquations;
0036     var sameInteger = currentDataset.sameInteger;
0037     // By default, the precision is the unit, no decimal numbers
0038     var precision = currentDataset.precision ? currentDataset.precision : 1;
0039     var decimalNumbersCount = Math.log10(1 / precision);
0040     var maxDistanceBetweenNumbers = currentDataset.maxDistanceBetweenNumbers;
0041     if(maxDistanceBetweenNumbers) {
0042         minValue = minValue + maxDistanceBetweenNumbers;
0043         maxValue = maxValue - maxDistanceBetweenNumbers;
0044     }
0045 
0046     //RandomDataset
0047     if(currentDataset.random) {
0048         for(var i = 0; i < numberOfEquations; ++i) {
0049             var leftHandSideFloat = 0;
0050             var rightHandSideFloat = 0;
0051             var leftHandSide = 0;
0052             var rightHandSide = 0;
0053             // Find a number between [minValue+maxDistanceBetweenNumbers; maxValue-maxDistanceBetweenNumbers] at the good precision
0054             // Find the distance from this number to the second one between [-maxDistanceBetweenNumbers; +maxDistanceBetweenNumbers]
0055             // allowing the second number to be between [minValue; maxValue]
0056             // truncate the numbers at the good precision
0057             if(maxDistanceBetweenNumbers) {
0058                 leftHandSideFloat = Math.floor(Math.random() * (maxValue - minValue) / precision) * precision + minValue;
0059                 var distance = Math.floor(2 * Math.random() * maxDistanceBetweenNumbers / precision) * precision - maxDistanceBetweenNumbers;
0060                 rightHandSideFloat = leftHandSideFloat + distance;
0061                 leftHandSide = toDecimalLocaleNumber(leftHandSideFloat, decimalNumbersCount);
0062                 rightHandSide = toDecimalLocaleNumber(rightHandSideFloat, decimalNumbersCount);
0063             }
0064             else {
0065                 leftHandSideFloat = Math.floor(Math.random() * (maxValue - minValue + 1)) + minValue;
0066                 leftHandSide = toDecimalLocaleNumber(leftHandSideFloat, decimalNumbersCount);
0067                 rightHandSideFloat = Math.floor(Math.random() * (maxValue - minValue + 1)) + minValue;
0068                 rightHandSide = toDecimalLocaleNumber(rightHandSideFloat, decimalNumbersCount);
0069             }
0070 
0071             // If we use the option to have same integer part on both sides
0072             if(sameInteger) {
0073                 var sharedInteger = Math.trunc(leftHandSideFloat);
0074                 var rightHandDecimal = rightHandSideFloat - Math.trunc(rightHandSideFloat);
0075                 rightHandSideFloat = sharedInteger + rightHandDecimal;
0076                 rightHandSide = toDecimalLocaleNumber(rightHandSideFloat, decimalNumbersCount);
0077             }
0078 
0079             items.dataListModel.append({
0080                 "leftHandSide": leftHandSide,
0081                 "rightHandSide": rightHandSide,
0082                 "symbol": "",
0083                 "isValidationImageVisible": false,
0084                 "isCorrectAnswer": true
0085             })
0086         }
0087         items.score.numberOfSubLevels = currentDataset.numberOfSublevels;
0088     }
0089     //fixedDataset
0090     else {
0091         var sublevel = currentDataset.values[items.score.currentSubLevel];
0092         numberOfEquations = sublevel.length;
0093         for(var i = 0; i < numberOfEquations; i++) {
0094             var leftHandSide = sublevel[i][0].toString()
0095             var rightHandSide = sublevel[i][1].toString()
0096             items.dataListModel.append({
0097                 "leftHandSide": leftHandSide,
0098                 "rightHandSide": rightHandSide,
0099                 "symbol": "",
0100                 "isValidationImageVisible": false,
0101                 "isCorrectAnswer": true
0102             })
0103         }
0104         items.score.numberOfSubLevels = currentDataset.values.length;
0105     }
0106     numberOfSubLevel = items.score.numberOfSubLevels;
0107     // Refresh the bindings by forcing a change of value and always select the first line by default
0108     items.selectedLine = 1;
0109     items.selectedLine = 0;
0110 
0111     items.buttonsBlocked = false;
0112 }
0113 
0114 function checkAnswer() {
0115     var allCorrect = true;
0116 
0117     for(var i = 0; i < items.dataListModel.count; ++i) {
0118         var line = items.dataListModel.get(i);
0119         line.isCorrectAnswer = evaluateAnswer(line);
0120         if(!line.isCorrectAnswer) {
0121             allCorrect = false;
0122         }
0123         line.isValidationImageVisible = true;
0124     }
0125 
0126     if(allCorrect) {
0127         items.buttonsBlocked = true;
0128         items.score.currentSubLevel += 1;
0129         items.score.playWinAnimation();
0130         items.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/completetask.wav");
0131     }
0132     else {
0133         items.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/crash.wav");
0134     }
0135 }
0136 
0137 
0138 function evaluateAnswer(equation) {
0139     var leftHandSide = fromDecimalLocaleNumber(equation.leftHandSide);
0140     var rightHandSide = fromDecimalLocaleNumber(equation.rightHandSide);
0141     var symbol = equation.symbol;
0142 
0143     var isCorrectAnswer = true;
0144 
0145     if((leftHandSide < rightHandSide) && (symbol !== "<")) {
0146         isCorrectAnswer = false;
0147     }
0148     else if ((leftHandSide > rightHandSide) && (symbol !== ">")) {
0149         isCorrectAnswer = false;
0150     }
0151     else if ((leftHandSide === rightHandSide) && (symbol !== "=")) {
0152         isCorrectAnswer = false;
0153     }
0154     return isCorrectAnswer;
0155 }
0156 
0157 function upAction() {
0158     if (items.selectedLine > 0) {
0159         items.selectedLine --;
0160     } else {
0161         items.selectedLine = items.dataListModel.count - 1
0162     }
0163 }
0164 
0165 function downAction() {
0166     if (items.selectedLine < (items.dataListModel.count - 1)) {
0167         items.selectedLine ++;
0168     } else {
0169         items.selectedLine = 0
0170     }
0171 }
0172 
0173 function nextLevel() {
0174     items.score.stopWinAnimation()
0175     items.currentLevel = Core.getNextLevel(items.currentLevel, numberOfLevel);
0176     items.score.currentSubLevel = 0;
0177     initLevel();
0178 }
0179 
0180 function nextSubLevel() {
0181     if(numberOfSubLevel <= items.score.currentSubLevel) {
0182         items.bonus.good("flower")
0183     } else {
0184         initLevel();
0185     }
0186 }
0187 
0188 function previousLevel() {
0189     items.score.stopWinAnimation()
0190     items.currentLevel = Core.getPreviousLevel(items.currentLevel, numberOfLevel);
0191     items.score.currentSubLevel = 0;
0192     initLevel();
0193 }
0194 
0195 function toDecimalLocaleNumber(decimalNumber, precision) {
0196     var locale = GCompris.ApplicationSettings.locale;
0197     if(locale === "system") {
0198         locale = Qt.locale().name === "C" ? "en_US" : Qt.locale().name;
0199     }
0200     var decimalLocale = Core.convertNumberToLocaleString(decimalNumber, locale, 'f', precision);
0201     return decimalLocale;
0202 }
0203 
0204 function fromDecimalLocaleNumber(decimalNumberString) {
0205     var locale = GCompris.ApplicationSettings.locale;
0206     if(locale === "system") {
0207         locale = Qt.locale().name === "C" ? "en_US" : Qt.locale().name;
0208     }
0209     var decimalValue = Number.fromLocaleString(Qt.locale(locale), decimalNumberString);
0210     return decimalValue;
0211 }