File indexing completed on 2024-05-19 07:29:45
0001 /* GCompris - missing-letter.js 0002 * 0003 * Copyright (C) 2014 "Amit Tomar" <a.tomar@outlook.com> 0004 * 0005 * Authors: 0006 * "Pascal Georges" <pascal.georgis1.free.fr> (GTK+ version) 0007 * "Amit Tomar" <a.tomar@outlook.com> (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 .import GCompris 1.0 as GCompris //for ApplicationInfo 0015 .import "qrc:/gcompris/src/activities/lang/lang_api.js" as Lang 0016 0017 var url = "qrc:/gcompris/src/activities/missing-letter/resource/" 0018 var langUrl = "qrc:/gcompris/src/activities/lang/resource/"; 0019 0020 var items 0021 var numberOfLevel 0022 0023 var questions 0024 var dataset 0025 var lessons 0026 var currentQuestion 0027 0028 // Do not propose these letter in the choices 0029 var ignoreLetters = '[ ,;:\\-\u0027]' 0030 var re = new RegExp(ignoreLetters, 'g') 0031 0032 function init(items_) { 0033 items = items_ 0034 } 0035 0036 function start() { 0037 var locale = GCompris.ApplicationInfo.getVoicesLocale(items.locale) 0038 0039 // register the voices for the locale 0040 GCompris.DownloadManager.updateResource(GCompris.GCompris.VOICES, {"locale": locale}) 0041 0042 dataset = Lang.load(items.parser, langUrl, 0043 GCompris.ApplicationSettings.useExternalWordset() ? "words.json" : "words_sample.json", 0044 "content-"+ locale +".json") 0045 0046 // If dataset is empty, we try to load from short locale 0047 // and if not present again, we switch to default one 0048 var localeUnderscoreIndex = locale.indexOf('_') 0049 if(!dataset) { 0050 var localeShort; 0051 // We will first look again for locale xx (without _XX if exist) 0052 if(localeUnderscoreIndex > 0) { 0053 localeShort = locale.substring(0, localeUnderscoreIndex) 0054 } else { 0055 localeShort = locale; 0056 } 0057 dataset = Lang.load(items.parser, langUrl, 0058 GCompris.ApplicationSettings.useExternalWordset() ? "words.json" : "words_sample.json", 0059 "content-"+localeShort+ ".json") 0060 } 0061 0062 // If still dataset is empty then fallback to english 0063 if(!dataset) { 0064 // English fallback 0065 items.background.englishFallback = true 0066 dataset = Lang.load(items.parser, langUrl, 0067 GCompris.ApplicationSettings.useExternalWordset() ? "words.json" : "words_sample.json", 0068 "content-en.json") 0069 } else { 0070 items.background.englishFallback = false 0071 } 0072 0073 lessons = Lang.getAllLessons(dataset) 0074 questions = initDataset() 0075 numberOfLevel = questions.length 0076 items.currentLevel = Core.getInitialLevel(numberOfLevel) 0077 initLevel() 0078 } 0079 0080 function initDataset() { 0081 var questions = [] 0082 for (var lessonIndex = 0; lessonIndex < lessons.length; lessonIndex++) { 0083 var lesson = Lang.getLessonWords(dataset, lessons[lessonIndex]) 0084 var guessLetters = getRandomLetters(lesson) 0085 questions[lessonIndex] = [] 0086 for (var j in lesson) { 0087 var clearQuestion = lesson[j].translatedTxt 0088 if(GCompris.ApplicationSettings.fontCapitalization === Quick.Font.AllUppercase) 0089 clearQuestion = clearQuestion.toLocaleUpperCase() 0090 else if(GCompris.ApplicationSettings.fontCapitalization === Quick.Font.AllLowercase) 0091 clearQuestion = clearQuestion.toLocaleLowerCase() 0092 0093 var maskedQuestion = getRandomMaskedQuestion(clearQuestion, guessLetters, lessonIndex) 0094 0095 questions[lessonIndex].push( 0096 { 0097 'image': lesson[j].image, 0098 'clearQuestion': clearQuestion, 0099 'maskedQuestion': maskedQuestion[0], 0100 'answer': maskedQuestion[1], 0101 'choices': maskedQuestion[2], 0102 'voice': lesson[j].voice, 0103 }) 0104 } 0105 } 0106 return questions 0107 } 0108 0109 // Get all the letters for all the words in the lesson excluding ignoreLetters 0110 function getRandomLetters(lesson) { 0111 var letters = [] 0112 for (var i in lesson) { 0113 var word = lesson[i].translatedTxt.replace(re, '') 0114 var lettersInCurrentWord; 0115 if(GCompris.ApplicationSettings.fontCapitalization === Quick.Font.AllUppercase) 0116 lettersInCurrentWord = word.toLocaleUpperCase().split('') 0117 else if(GCompris.ApplicationSettings.fontCapitalization === Quick.Font.AllLowercase) 0118 lettersInCurrentWord = word.toLocaleLowerCase().split('') 0119 else 0120 lettersInCurrentWord = word.split('') 0121 0122 for(var l in lettersInCurrentWord) { 0123 if(letters.indexOf(lettersInCurrentWord[l]) === -1) { 0124 letters.push(lettersInCurrentWord[l]); 0125 } 0126 } 0127 } 0128 return Core.shuffle(GCompris.ApplicationInfo.localeSort(letters, items.locale)) 0129 } 0130 0131 // Get a random letter in the given word excluding ignoreLetters 0132 function getRandomLetter(word) { 0133 var letters = word.replace(re, '').split('') 0134 var letter = letters[Math.floor(Math.random() * letters.length)] 0135 if(GCompris.ApplicationSettings.fontCapitalization === Quick.Font.AllUppercase) 0136 return letter.toLocaleUpperCase() 0137 else if(GCompris.ApplicationSettings.fontCapitalization === Quick.Font.AllLowercase) 0138 return letter.toLocaleLowerCase() 0139 0140 return letter 0141 } 0142 0143 function getRandomMaskedQuestion(clearQuestion, guessLetters, level) { 0144 var maskedQuestion = clearQuestion 0145 var goodLetter = getRandomLetter(maskedQuestion) 0146 0147 // If the word has several occurrences of the letter, choose one at random 0148 var goodLetterPositions = []; 0149 for(var i = 0; i < maskedQuestion.length; i++) { 0150 if (maskedQuestion[i] === goodLetter) { 0151 goodLetterPositions.push(i); 0152 } 0153 } 0154 var index = goodLetterPositions[Math.floor(Math.random() * goodLetterPositions.length)]; 0155 0156 // Replace the char at index with '_' 0157 var repl = maskedQuestion.split('') 0158 repl[index] = '_' 0159 maskedQuestion = repl.join('') 0160 0161 // Get some other letter to confuse the children 0162 var confusingLetters = [] 0163 for(var i = 0; i < Math.min(level + 2, 6); i++) { 0164 var letter = guessLetters.shift() 0165 if(confusingLetters.indexOf(letter) === -1 && letter !== goodLetter) { 0166 confusingLetters.push(letter); 0167 } 0168 guessLetters.push(letter) 0169 } 0170 confusingLetters.push(goodLetter) 0171 0172 return [maskedQuestion, goodLetter, Core.shuffle(confusingLetters)] 0173 } 0174 0175 function stop() { 0176 items.questionAnim.stop(); 0177 items.audioVoices.clearQueue(); 0178 } 0179 0180 function initLevel() { 0181 items.questionAnim.stop() 0182 items.score.currentSubLevel = 0 0183 items.score.numberOfSubLevels = questions[items.currentLevel].length 0184 showQuestion() 0185 } 0186 0187 function getCurrentQuestion() { 0188 return questions[items.currentLevel][items.score.currentSubLevel] 0189 } 0190 0191 function showQuestion() { 0192 currentQuestion = getCurrentQuestion() 0193 0194 playWord(currentQuestion.voice) 0195 items.answer = currentQuestion.answer 0196 items.answers.model = currentQuestion.choices 0197 items.questionText.text = currentQuestion.maskedQuestion 0198 items.questionImage.source = currentQuestion.image 0199 items.isGoodAnswer = false 0200 items.buttonsBlocked = false 0201 } 0202 0203 function nextLevel() { 0204 items.score.stopWinAnimation() 0205 items.currentLevel = Core.getNextLevel(items.currentLevel, numberOfLevel); 0206 initLevel(); 0207 } 0208 0209 function nextSubLevel() { 0210 if(items.score.currentSubLevel >= items.score.numberOfSubLevels) { 0211 items.bonus.good('flower') 0212 return 0213 } 0214 showQuestion() 0215 } 0216 0217 function previousLevel() { 0218 items.score.stopWinAnimation(); 0219 items.currentLevel = Core.getPreviousLevel(items.currentLevel, numberOfLevel); 0220 initLevel(); 0221 } 0222 0223 function showAnswer() { 0224 playLetter(currentQuestion.answer) 0225 items.isGoodAnswer = true 0226 items.questionText.text = currentQuestion.clearQuestion 0227 } 0228 0229 function playLetter(letter) { 0230 var locale = GCompris.ApplicationInfo.getVoicesLocale(items.locale) 0231 items.audioVoices.stop() 0232 items.audioVoices.clearQueue() 0233 items.audioVoices.append(GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/"+locale+"/alphabet/" + 0234 Core.getSoundFilenamForChar(letter))) 0235 } 0236 0237 function playCurrentWord() { 0238 var question = getCurrentQuestion() 0239 playWord(question.voice) 0240 } 0241 0242 function playWord(word) { 0243 var locale = GCompris.ApplicationInfo.getVoicesLocale(items.locale) 0244 var wordLocalized = word.replace("$LOCALE", locale) 0245 items.audioVoices.append(GCompris.ApplicationInfo.getAudioFilePath(wordLocalized)) 0246 } 0247 0248 function focusTextInput() { 0249 if (!GCompris.ApplicationInfo.isMobile && items && items.textinput) 0250 items.textinput.forceActiveFocus(); 0251 }