File indexing completed on 2024-05-05 15:53:20

0001 /* GCompris - superbrain.js
0002  *
0003  * SPDX-FileCopyrightText: 2015 Holger Kaelberer <holger.k@elberer.de>
0004  *
0005  * Authors:
0006  *   Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
0007  *   Holger Kaelberer <holger.k@elberer.de> (Qt Quick port)
0008  *
0009  *   SPDX-License-Identifier: GPL-3.0-or-later
0010  */
0011 .pragma library
0012 .import QtQuick 2.12 as Quick
0013 .import "qrc:/gcompris/src/core/core.js" as Core
0014 
0015 var maxLevel = 8;
0016 var maxSubLevel = 6;
0017 var items;
0018 var baseUrl = "qrc:/gcompris/src/activities/graph-coloring/resource/shapes/";
0019 
0020 var levels = [
0021             { numberOfPieces: 3, numberOfColors: 5, help: true,  uniqueColors: true  },
0022             { numberOfPieces: 4, numberOfColors: 6, help: true,  uniqueColors: true  },
0023             { numberOfPieces: 5, numberOfColors: 7, help: true,  uniqueColors: true  },
0024             { numberOfPieces: 5, numberOfColors: 7, help: true,  uniqueColors: false },
0025             { numberOfPieces: 3, numberOfColors: 5, help: false, uniqueColors: true  },
0026             { numberOfPieces: 4, numberOfColors: 6, help: false, uniqueColors: true  },
0027             { numberOfPieces: 5, numberOfColors: 7, help: false, uniqueColors: true  },
0028             { numberOfPieces: 5, numberOfColors: 7, help: false, uniqueColors: false }
0029         ];
0030 var maxPieces = 5;
0031 var solution = new Array(maxPieces);
0032 var colors = [
0033             "#387BE0",  // dark blue
0034             "#8EEB76",  // light green
0035             "#E65B48",  // red
0036             "#E7F7FD",  // bluish white
0037             "#E31BE3",  // magenta
0038             "#E8EF48",  // yellow
0039             "#BBB082",  // brown
0040             "#49BBF0",  // light blue
0041             "#D81965",   // dark magenta
0042         ];
0043 var symbols = [
0044             baseUrl + "star.svg",
0045             baseUrl + "triangle.svg",
0046             baseUrl + "heart.svg",
0047             baseUrl + "cloud.svg",
0048             baseUrl + "diamond.svg",
0049             baseUrl + "star_simple.svg",
0050             baseUrl + "cross.svg",
0051             baseUrl + "ring.svg",
0052             baseUrl + "circle.svg",
0053         ];
0054 
0055 var ackColors = new Array();
0056 var currentIndeces = new Array();
0057 var maxColors = colors.length;
0058 
0059 var STATUS_UNKNOWN = 0;
0060 var STATUS_MISPLACED = 1;
0061 var STATUS_CORRECT = 2;
0062 
0063 function start(items_) {
0064     items = items_;
0065     items.currentLevel = Core.getInitialLevel(maxLevel);
0066     items.score.currentSubLevel = 0;
0067     initLevel();
0068 }
0069 
0070 function stop() {
0071 }
0072 
0073 function initLevel() {
0074     // init sublevel
0075     ackColors = new Array(levels[items.currentLevel].numberOfPieces);
0076     items.score.numberOfSubLevels = maxSubLevel;
0077     var selectedColors = new Array(maxColors);
0078     solution = new Array(levels[items.currentLevel].numberOfPieces);
0079     for (var i = 0; i < maxColors; ++i)
0080         selectedColors[i] = false;
0081     // generate solution:
0082     for(var i = 0; i < levels[items.currentLevel].numberOfPieces; ++i) {
0083         var j;
0084         do
0085             j = Math.floor(Math.random() * levels[items.currentLevel].numberOfColors);
0086         while (levels[items.currentLevel].uniqueColors && selectedColors[j]);
0087 
0088         solution[i] = j;
0089         selectedColors[j] = true;
0090     }
0091     //console.log("XXX solution: " + JSON.stringify(solution));
0092     // populate currentIndeces:
0093     items.colorsRepeater.model.clear();
0094     items.currentRepeater.model = new Array();
0095     currentIndeces = new Array();
0096     for (var i = 0; i < levels[items.currentLevel].numberOfColors; ++i) {
0097         currentIndeces[i] = i;
0098         items.colorsRepeater.model.append({"itemIndex": i});
0099     }
0100     items.chooserGrid.model = currentIndeces;
0101     // add first guess row:
0102     items.guessModel.clear();
0103     appendGuessRow();
0104     items.buttonsBlocked = false;
0105 }
0106 
0107 function appendGuessRow() {
0108     var guessRow = new Array();
0109     for (var i = 0; i < levels[items.currentLevel].numberOfPieces; ++i) {
0110         var col =
0111         guessRow.push({
0112                           index: i,
0113                           colIndex: (ackColors[i] === undefined) ? 0 : ackColors[i],
0114                           status: STATUS_UNKNOWN,
0115                           isAcked: (ackColors[i] !== undefined)
0116                       });
0117     }
0118     items.guessModel.insert(0, {
0119                                 guess: guessRow,
0120                                 result: {correct: 0, misplaced: 0}
0121                             });
0122     var obj = items.guessModel.get(0);
0123     items.currentRepeater.model = obj.guess;
0124 }
0125 
0126 function ackColor(column, colIndex) {
0127     ackColors[column] = (ackColors[column] == colIndex) ?  undefined : colIndex;
0128     for (var i = 0; i < items.guessModel.count; i++) {
0129         var obj = items.guessModel.get(i).guess.get(column);
0130         obj.isAcked = (ackColors[column] == obj.colIndex);
0131     }
0132     items.currentRepeater.model.get(column).colIndex = colIndex;
0133     items.currentRepeater.model.get(column).isAcked = (ackColors[column] !== undefined);
0134 }
0135 
0136 function checkGuess() {
0137     var obj = items.guessModel.get(0);
0138     var correctCount = 0;
0139     var misplacedCount = 0;
0140 
0141     // these will be used to check for mismatches later
0142     var remainingIndices = [];  // stores indices where mismatches can happen
0143     var remainingColors = [];   // stores the solution values at those indices
0144 
0145     // check for exact matches first:
0146     for (var i = 0; i < levels[items.currentLevel].numberOfPieces; i++) {
0147         var guessIndex = obj.guess.get(i).colIndex;
0148         var newStatus;
0149         if (solution[i] == guessIndex) {
0150             // correct
0151             if (levels[items.currentLevel].help)
0152                 obj.guess.setProperty(i, "status", STATUS_CORRECT);
0153             correctCount++;
0154         }
0155         else {
0156             remainingIndices.push(i);
0157             remainingColors.push(solution[i]);
0158         }
0159     }
0160     obj.result = ({ correct: correctCount });
0161     if (remainingIndices.length == 0) {
0162         items.buttonsBlocked = true;
0163         items.score.currentSubLevel += 1;
0164         items.score.playWinAnimation();
0165         items.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/completetask.wav");
0166     }
0167 
0168     for (var i = 0; i < remainingIndices.length; i++) {
0169         var index = remainingIndices[i];
0170         var guessIndex = obj.guess.get(index).colIndex;
0171         var newStatus = STATUS_UNKNOWN;
0172         if (remainingColors.indexOf(guessIndex) != -1) {
0173             // misplaced
0174             if (levels[items.currentLevel].help)
0175                 obj.guess.setProperty(index, "status", STATUS_MISPLACED);
0176 
0177             // remove guessIndex from remainingColors, so that multiple mismatches are not reported
0178             remainingColors.splice(remainingColors.indexOf(guessIndex), 1)
0179 
0180             misplacedCount++;
0181         }
0182     }
0183     obj.result = ({ misplaced: misplacedCount, correct: correctCount });
0184 
0185     appendGuessRow();
0186 }
0187 
0188 function nextLevel() {
0189     items.score.stopWinAnimation();
0190     items.currentLevel = Core.getNextLevel(items.currentLevel, maxLevel);
0191     items.score.currentSubLevel = 0;
0192     initLevel();
0193 }
0194 
0195 function previousLevel() {
0196     items.score.stopWinAnimation();
0197     items.currentLevel = Core.getPreviousLevel(items.currentLevel, maxLevel);
0198     items.score.currentSubLevel = 0;
0199     initLevel();
0200 }
0201 
0202 function nextSubLevel() {
0203     if(items.score.currentSubLevel >= maxSubLevel) {
0204         items.bonus.good("smiley");
0205     }
0206     else {
0207         initLevel();
0208     }
0209 }