File indexing completed on 2024-04-28 15:07:57

0001 /* GCompris - money.js
0002  *
0003  * SPDX-FileCopyrightText: 2014 Bruno Coudoin
0004  *
0005  * Authors:
0006  *   Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
0007  *   Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
0008  *
0009  *   SPDX-License-Identifier: GPL-3.0-or-later
0010  */
0011 .pragma library
0012 .import "qrc:/gcompris/src/core/core.js" as Core
0013 .import GCompris 1.0 as GCompris
0014 .import "moneyConstants.js" as MoneyConstants
0015 
0016 var url = "qrc:/gcompris/src/activities/money/resource/"
0017 
0018 // We create 3 prices categories to make the game more realistic.
0019 // List of images to use in the game (cheap objects)
0020 
0021 var numberOfLevel
0022 var dataset
0023 var items
0024 var centsMode
0025 var backMode
0026 var priceTotal
0027 
0028 function start(items_, datasetName) {
0029     items = items_
0030     dataset = items.levels
0031     switch(datasetName) {
0032         case "WITHOUT_CENTS":
0033             centsMode = false
0034             backMode = false
0035             break
0036         case "WITH_CENTS":
0037             centsMode = true
0038             backMode = false
0039             break
0040         case "BACK_WITHOUT_CENTS":
0041             centsMode = false
0042             backMode = true
0043             break
0044         case "BACK_WITH_CENTS":
0045             centsMode = true
0046             backMode = true
0047             break
0048     }
0049     numberOfLevel = dataset.length
0050     items.currentLevel = Core.getInitialLevel(numberOfLevel)
0051     initLevel()
0052 }
0053 
0054 function stop() {
0055 }
0056 
0057 function getCoinCount (pocket) {
0058     var count = 0
0059     for(var i = 0; i < pocket.length; i++) {
0060         if(pocket[i].val <= 2)
0061             count++
0062     }
0063     return count;
0064 }
0065 
0066 function initLevel() {
0067     items.answerModel.clear()
0068     items.pocketModel.clear()
0069 
0070     var data = dataset[items.currentLevel]
0071     var pocket = Core.shuffle(data.pocket)
0072     var coinCount = getCoinCount(pocket)
0073     items.moneyCount = data.pocket.length
0074 
0075     for(var i = 0; i < pocket.length; i++)
0076         items.pocketModel.append(pocket[i])
0077 
0078     var locale = GCompris.ApplicationSettings.locale
0079     if(locale == "system") {
0080         locale = Qt.locale().name == "C" ? "en_US" : Qt.locale().name
0081     }
0082     // fill up the store in a random way
0083     var storeModel = new Array()
0084     // the real minimum price should always be at least the number of items
0085     // in non cents mode, to always have positive prices
0086     // else it could happen to have a price of 1 and 3 items to sell...
0087     var realMinPrice = Math.max(data.minPrice, data.numberOfItem)
0088     priceTotal = Math.floor(realMinPrice + Math.random() *
0089                             (data.maxPrice - realMinPrice))
0090     var priceCounter = 0
0091     for(var i = 0; i < data.numberOfItem; i++) {
0092         var price
0093         if(i < data.numberOfItem - 1) {
0094             var delta = (centsMode ? 0 : 1)
0095             // Calc a random price for each item based on the previous prices
0096             price = Math.floor(delta +
0097                                Math.random() *
0098                                (2 * (priceTotal - priceCounter) / data.numberOfItem - delta))
0099         }
0100         else {
0101             // Put the remaining missing price on the last item
0102             price = priceTotal - priceCounter
0103             // If the price is 0, we recompute it to be between 1 and the remaining values
0104             // between the actual total price and the max price possible
0105             if(price == 0) {
0106                 price = delta + Math.floor(Math.random() * (data.maxPrice - priceTotal - delta));
0107                 priceTotal += price;
0108             }
0109         }
0110         var cents = 0
0111         if(centsMode) {
0112             if(items.currentLevel === 0)
0113                 cents += 0.10 + Math.floor(Math.random() * 9) / 10
0114             else
0115                 cents += 0.01 + Math.floor(Math.random() * 99) / 100
0116 
0117             // To be sure that the sums of the cents will never go higher than the
0118             // maxPrice, we remove them instead of adding them if the item price
0119             // is above 1
0120             if(price > 1) {
0121                 cents = cents - 1
0122             }
0123             priceTotal += cents
0124             price += cents
0125         }
0126 
0127         var priceText = Core.convertNumberToLocaleCurrencyString(Number(price), locale)
0128         if(!centsMode) {
0129             // Strip floating part
0130             priceText = priceText.replace((/[,.]00/), "")
0131         }
0132 
0133         storeModel.push({img: getRandomObject(price),
0134                          price: priceText})
0135         priceCounter += price
0136     }
0137     items.store.model = storeModel
0138 
0139     if(!backMode) {
0140         items.instructions.text =
0141                 qsTr("Click on the coins or on the notes at the bottom of the screen to pay." +
0142                      " If you want to remove a coin or a note, click on it on the upper screen area.")
0143     } else {
0144         var availableCurrency = pocket.slice()
0145         availableCurrency.sort(function sort(a, b) { return b.val - a.val });
0146         var amountToBeCovered = data.paid
0147         var tuxMoney = []
0148         while(amountToBeCovered > 0) {
0149             var maxPossible = 0
0150             for(var i = 0; i < availableCurrency.length; i++) {
0151                 if((availableCurrency[i].val <= amountToBeCovered)) {
0152                     maxPossible = availableCurrency[i]
0153                     break;
0154                 }
0155             }
0156             tuxMoney.push(maxPossible)
0157             amountToBeCovered -= maxPossible.val;
0158         }
0159         items.tuxMoney.model = tuxMoney
0160 
0161         var tuxTotal = 0
0162         for(var i=0; i < tuxMoney.length; i++)
0163             tuxTotal += tuxMoney[i].val
0164 
0165         var priceText = Core.convertNumberToLocaleCurrencyString(Number(tuxTotal), locale)
0166         if(!centsMode) {
0167             // Strip floating part
0168             priceText = priceText.replace((/.00/), "")
0169         }
0170 
0171         /* The money sign is inserted based on the current locale */
0172         items.instructions.text = qsTr("Tux just bought some items in your shop.\n" +
0173                                        "He gives you %1, please give back his change.")
0174                       .arg(priceText)
0175     }
0176 
0177     //Keyboard reset
0178     items.itemIndex = -1
0179     items.selectedArea = items.pocket
0180 
0181 }
0182 
0183 // Given a price return a random object
0184 function getRandomObject(price) {
0185     var objectList
0186     if(price < 5)
0187         objectList = MoneyConstants.cheapObjects
0188     else if(price < 10)
0189         objectList = MoneyConstants.normalObjects
0190     else
0191         objectList = MoneyConstants.expensiveObjects
0192 
0193     return objectList[Math.floor(Math.random() * objectList.length)]
0194 }
0195 
0196 function checkAnswer() {
0197     var paid = 0
0198     for (var i = 0; i < items.answerModel.count; ++i)
0199         paid += items.answerModel.get(i).val
0200 
0201     paid = paid.toFixed(2)
0202 
0203     if(!backMode) {
0204         if(paid === priceTotal.toFixed(2))
0205             items.bonus.good("flower")
0206     } else {
0207         if(paid === (dataset[items.currentLevel].paid - priceTotal).toFixed(2))
0208             items.bonus.good("flower")
0209     }
0210 }
0211 
0212 function pay(index) {
0213     items.audioEffects.play(url + "money1.wav")
0214     // Add it to the anwser
0215     items.answerModel.append(items.pocketModel.get(index))
0216 
0217     // Remove it from the pocket
0218     items.pocketModel.remove(index, 1)
0219 
0220     checkAnswer()
0221 }
0222 
0223 function unpay(index) {
0224     items.audioEffects.play(url + "money2.wav")
0225     // Add it to the pocket
0226     items.pocketModel.append(items.answerModel.get(index))
0227 
0228     // Remove it from the Answer
0229     items.answerModel.remove(index, 1)
0230 
0231     checkAnswer()
0232 }
0233 
0234 function nextLevel() {
0235     items.currentLevel = Core.getNextLevel(items.currentLevel, numberOfLevel);
0236     initLevel();
0237 }
0238 
0239 function previousLevel() {
0240     items.currentLevel = Core.getPreviousLevel(items.currentLevel, numberOfLevel);
0241     initLevel();
0242 }