diff --git a/src/activities/digital_electricity/Dataset.qml b/src/activities/digital_electricity/Dataset.qml index e0e24fa7d..f33ba3206 100644 --- a/src/activities/digital_electricity/Dataset.qml +++ b/src/activities/digital_electricity/Dataset.qml @@ -1,254 +1,290 @@ /* GCompris - Dataset.qml * * Copyright (C) 2017 Rudra Nil Basu * * Authors: * Bruno Coudoin (GTK+ version) * Rudra Nil Basu (Qt Quick port) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . */ import QtQuick 2.6 QtObject { property var zero: { 'imageName': 'zero.svg', 'componentSource': 'Zero.qml', 'width': 0.12, 'height': 0.2, 'toolTipText': qsTr("Zero input") } property var one: { 'imageName': 'one.svg', 'componentSource': 'One.qml', 'width': 0.12, 'height': 0.2, 'toolTipText': qsTr("One input") } property var digitalLight: { 'imageName': 'DigitalLightOff.svg', 'componentSource': 'DigitalLight.qml', 'width': 0.12, 'height': 0.12, 'toolTipText': qsTr("Digital Light") } property var andGate: { 'imageName': 'gateAnd.svg', 'componentSource': 'AndGate.qml', 'width': 0.15, 'height': 0.12, 'toolTipText': qsTr("AND gate") } property var orGate: { 'imageName': 'gateOr.svg', 'componentSource': 'OrGate.qml', 'width': 0.15, 'height': 0.12, 'toolTipText': qsTr("OR gate") } property var notGate: { 'imageName': 'gateNot.svg', 'componentSource': 'NotGate.qml', 'width': 0.15, 'height': 0.12, 'toolTipText': qsTr("NOT gate") } property var xorGate: { 'imageName': 'gateXor.svg', 'componentSource': 'XorGate.qml', 'width': 0.15, 'height': 0.12, 'toolTipText': qsTr("XOR gate") } property var nandGate: { 'imageName': 'gateNand.svg', 'componentSource': 'NandGate.qml', 'width': 0.15, 'height': 0.12, 'toolTipText': qsTr("NAND gate") } property var norGate: { 'imageName': 'gateNor.svg', 'componentSource': 'NorGate.qml', 'width': 0.15, 'height': 0.12, 'toolTipText': qsTr("NOR gate") } property var switchKey: { 'imageName': 'switchOff.svg', 'componentSource': 'Switch.qml', 'width': 0.18, 'height': 0.15, 'toolTipText': qsTr("Switch") } // tutorial levels property var tutorialLevels: [ // level 1 { inputComponentList: [zero, one], playAreaComponentList: [digitalLight], determiningComponentsIndex: [0], wires: [], playAreaComponentPositionX: [0.4], playAreaComponentPositionY: [0.3], introMessage: [ qsTr("The Digital light will glow when its terminal is connected with an input of 1"), qsTr("Turn the Digital light on using the inputs provided") ] }, // level 2 { inputComponentList: [zero, one], playAreaComponentList: [andGate, digitalLight], determiningComponentsIndex: [1], wires: [ [0, 0, 1, 0] ], // from_component_index, from_terminal_no, to_component_index, to_terminal_no playAreaComponentPositionX: [0.4, 0.6], playAreaComponentPositionY: [0.3, 0.3], introMessage: [ qsTr("The AND Gate produces an output of one when both of it's input terminal are of value 1"), qsTr("Turn the Digital light on using an AND gate and the inputs provided") ] }, // level 3 { inputComponentList: [zero, one], playAreaComponentList: [orGate, digitalLight], determiningComponentsIndex: [1], wires: [ [0, 0, 1, 0] ], playAreaComponentPositionX: [0.4, 0.6], playAreaComponentPositionY: [0.3, 0.3], introMessage: [ qsTr("The OR Gate produces an output of 1 when at least one of the input terminal is of value 1"), qsTr("Turn the Digital light on using an OR gate and the inputs provided") ] }, // level 4 { inputComponentList: [zero], playAreaComponentList: [zero, one, orGate, andGate, digitalLight], determiningComponentsIndex: [4], wires: [ [0, 0, 2, 0], [2, 0, 3, 0], [3, 0, 4, 0]], playAreaComponentPositionX: [0.2, 0.3, 0.4, 0.6, 0.8], playAreaComponentPositionY: [0.1, 0.4, 0.3, 0.3, 0.4], introMessage: [ qsTr("NOTE: You can draw multiple wires from the output terminal of a component.") ] }, // level 5 { inputComponentList: [zero], playAreaComponentList: [notGate, notGate, orGate, orGate, andGate, digitalLight], determiningComponentsIndex: [5], wires: [ [4, 0, 5, 0], [2, 0, 4, 0], [3, 0, 4, 1]], playAreaComponentPositionX: [0.2, 0.2, 0.5, 0.5, 0.6, 0.8], playAreaComponentPositionY: [0.1, 0.4, 0.2, 0.6, 0.4, 0.4], introMessage: [ qsTr("The NOT gate takes a single binary input and flips the value in the output") ] }, // level 6 { inputComponentList: [zero, notGate, orGate, andGate], playAreaComponentList: [one, one, switchKey, switchKey, digitalLight], determiningComponentsIndex: [2, 3, 4], wires: [ ], playAreaComponentPositionX: [0.0, 0.0, 0.1, 0.1, 0.8], playAreaComponentPositionY: [0.0, 0.8, 0.3, 0.6, 0.4], introMessage: [ qsTr("Light the bulb using both the switches such that the bulb will glow when only one of the switches are turned on") ] }, // level 7 { inputComponentList: [zero, one], playAreaComponentList: [nandGate, digitalLight], determiningComponentsIndex: [1], wires: [ [0, 0, 1, 0] ], playAreaComponentPositionX: [0.4, 0.8], playAreaComponentPositionY: [0.4, 0.4], introMessage: [ qsTr("The NAND Gate takes two binary inputs and produces one binary output"), qsTr("The output of the NAND gate will be zero if the both the inputs are \"0\". Else, the output will be one."), qsTr("For a more detailed description about the gate, select it and click on the info button."), qsTr("Light the bulb using the NAND gate provided.") ] }, // level 8 { inputComponentList: [zero, one, andGate, orGate, nandGate], playAreaComponentList: [switchKey, switchKey, switchKey, digitalLight], determiningComponentsIndex: [0, 1, 2, 3], wires: [ ], playAreaComponentPositionX: [0.2, 0.2, 0.2, 0.8], playAreaComponentPositionY: [0.2, 0.5, 0.8, 0.5], introMessage: [ qsTr("Light the bulb using the components provided such that the bulb will glow under the following two circumstances:"), qsTr("1. The first switch is turned ON, or"), qsTr("2. Both of the second and the third switches are turned on.") ] }, // level 9 { inputComponentList: [zero, one], playAreaComponentList: [xorGate, digitalLight], determiningComponentsIndex: [1], wires: [ [0, 0, 1, 0] ], playAreaComponentPositionX: [0.4, 0.8], playAreaComponentPositionY: [0.4, 0.4], introMessage: [ qsTr("The XOR Gate takes two binary inputs and produces one binary output"), qsTr("The output of the XOR gate will be one if the number of \"1\" in the input is odd. Else, the output will be zero."), qsTr("Light the bulb using the XOR gate provided.") ] }, // level 10 { inputComponentList: [zero, one, xorGate], playAreaComponentList: [switchKey, switchKey, switchKey, digitalLight], determiningComponentsIndex: [0, 1, 2, 3], wires: [ ], playAreaComponentPositionX: [0.2, 0.2, 0.2, 0.8], playAreaComponentPositionY: [0.2, 0.4, 0.6, 0.4], introMessage: [ qsTr("Light the bulb using the three switches such that the bulb glows when odd number of the switches are turned on") ] }, // level 11 { inputComponentList: [one, notGate], playAreaComponentList: [norGate, digitalLight], determiningComponentsIndex: [1], wires: [ [0, 0, 1, 0] ], playAreaComponentPositionX: [0.6, 0.8], playAreaComponentPositionY: [0.5, 0.5], introMessage: [ qsTr("A NOR gate takes 2 binary input and outputs 1 if both of them are 0, otherwise produces an output of 1."), qsTr("For a more detailed description about the gate, select it and click on the info button."), qsTr("Light the bulb using the NOR gate provided.") ] }, // level 12 { inputComponentList: [nandGate], playAreaComponentList: [one, switchKey, digitalLight], determiningComponentsIndex: [1, 2], wires: [ [0, 0, 1, 0] ], playAreaComponentPositionX: [0.1, 0.3, 0.8], playAreaComponentPositionY: [0.5, 0.5, 0.5], introMessage: [ qsTr("Use the gates such that the bulb will glow only when the switch is turned off and remain off when the switch is turned on.") ] + }, + // level 13 + { + inputComponentList: [nandGate], + playAreaComponentList: [one, switchKey, switchKey, digitalLight], + determiningComponentsIndex: [1, 2, 3], + wires: [ [0, 0, 1, 0], [0, 0, 2, 0] ], + playAreaComponentPositionX: [0.0, 0.2, 0.2, 0.8], + playAreaComponentPositionY: [0.5, 0.4, 0.6, 0.5], + introMessage: [ + qsTr("Create a circuit using the components provided such that the bulb glows only when both of the switches are turned on.") + ] + }, + // level 14 + { + inputComponentList: [nandGate], + playAreaComponentList: [one, switchKey, switchKey, digitalLight], + determiningComponentsIndex: [1, 2, 3], + wires: [ [0, 0, 1, 0], [0, 0, 2, 0] ], + playAreaComponentPositionX: [0.0, 0.2, 0.2, 0.8], + playAreaComponentPositionY: [0.5, 0.4, 0.6, 0.5], + introMessage: [ + qsTr("Create a circuit using the components provided such that the bulb glows when either of the switches are turned on.") + ] + }, + // level 15 + { + inputComponentList: [nandGate], + playAreaComponentList: [one, switchKey, switchKey, digitalLight], + determiningComponentsIndex: [1, 2, 3], + wires: [ [0, 0, 1, 0], [0, 0, 2, 0] ], + playAreaComponentPositionX: [0.0, 0.2, 0.2, 0.8], + playAreaComponentPositionY: [0.5, 0.4, 0.6, 0.5], + introMessage: [ + qsTr("Create a circuit using the components provided such that the bulb glows only when both of the switches are turned off.") + ] } ] } diff --git a/src/activities/digital_electricity/digital_electricity.js b/src/activities/digital_electricity/digital_electricity.js index 66feb19e7..2ef3311e9 100644 --- a/src/activities/digital_electricity/digital_electricity.js +++ b/src/activities/digital_electricity/digital_electricity.js @@ -1,671 +1,761 @@ /* GCompris - digital_electricity.js * * Copyright (C) 2016 Pulkit Gupta * * Authors: * Bruno Coudoin (GTK+ version) * Pulkit Gupta (Qt Quick port) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . */ .pragma library .import QtQuick 2.3 as Quick var currentLevel = 1 var numberOfLevel var items var url = "qrc:/gcompris/src/activities/digital_electricity/resource/" var toolDelete var toolDeleteSticky var selectedIndex var animationInProgress var selectedTerminal var deletedIndex = [] var components = [] var connected = [] var determiningComponents = [] function start(items_) { items = items_ currentLevel = 1 numberOfLevel = items.tutorialDataset.tutorialLevels.length initLevel() } function stop() { for(var i = 0 ; i < components.length ; ++i) { var j for(j = 0 ; j < deletedIndex.length ; ++j) { if(deletedIndex[j] == i) break } if(j == deletedIndex.length) removeComponent(i) } } function initLevel() { items.bar.level = currentLevel var sizeMultiplier = 1 + (1 / (1.5 * currentLevel)) items.availablePieces.view.currentDisplayedGroup = 0 items.availablePieces.view.previousNavigation = 1 items.availablePieces.view.nextNavigation = 1 deletedIndex = [] components = [] connected = [] determiningComponents = [] animationInProgress = false toolDelete = false toolDeleteSticky = false deselect() updateToolTip("") if (!items.isTutorialMode) { items.tutorialInstruction.visible = false loadFreeMode(sizeMultiplier) } else { // load tutorial levels from dataset var levelProperties = items.tutorialDataset.tutorialLevels[currentLevel - 1] for (var i = 0; i < levelProperties.inputComponentList.length; i++) { var currentInputComponent = levelProperties.inputComponentList[i] items.availablePieces.model.append( { "imgName": currentInputComponent.imageName, "componentSrc": currentInputComponent.componentSource, "imgWidth": currentInputComponent.width * sizeMultiplier, "imgHeight": currentInputComponent.height * sizeMultiplier, "toolTipText": currentInputComponent.toolTipText }) } for (var i = 0; i < levelProperties.playAreaComponentList.length; i++) { var index = components.length var currentPlayAreaComponent = levelProperties.playAreaComponentList[i] var staticElectricalComponent = Qt.createComponent("qrc:/gcompris/src/activities/digital_electricity/components/" + currentPlayAreaComponent.componentSource) components[index] = staticElectricalComponent.createObject( items.playArea, { "index": index, "posX": levelProperties.playAreaComponentPositionX[i], "posY": levelProperties.playAreaComponentPositionY[i], "imgSrc": currentPlayAreaComponent.imageName, "toolTipTxt": currentPlayAreaComponent.toolTipText, "imgWidth": currentPlayAreaComponent.width, "imgHeight": currentPlayAreaComponent.height, "destructible": false }); } var _determiningComponentsIndex = levelProperties.determiningComponentsIndex for (var i = 0; i < _determiningComponentsIndex.length; i++) { determiningComponents[determiningComponents.length] = components[_determiningComponentsIndex[i]] } // creating wires for (i = 0; i < levelProperties.wires.length; i++) { var terminal_number = levelProperties.wires[i][1] var outTerminal = components[levelProperties.wires[i][0]].outputTerminals.itemAt(terminal_number) terminal_number = levelProperties.wires[i][3] var inTerminal = components[levelProperties.wires[i][2]].inputTerminals.itemAt(terminal_number) createWire(inTerminal, outTerminal, false) } if (levelProperties.introMessage.length != 0) { items.tutorialInstruction.visible = true items.tutorialInstruction.index = 0 items.tutorialInstruction.intro = levelProperties.introMessage } else { items.tutorialInstruction.visible = false } } } function loadFreeMode(sizeMultiplier) { items.availablePieces.model.append( { "imgName": "zero.svg", "componentSrc": "Zero.qml", "imgWidth": sizeMultiplier * 0.12, "imgHeight": sizeMultiplier * 0.2, "toolTipText": qsTr("Zero input") }) items.availablePieces.model.append( { "imgName": "one.svg", "componentSrc": "One.qml", "imgWidth": sizeMultiplier * 0.12, "imgHeight": sizeMultiplier * 0.2, "toolTipText": qsTr("One input") }) items.availablePieces.model.append( { "imgName": "DigitalLightOff.svg", "componentSrc": "DigitalLight.qml", "imgWidth": sizeMultiplier * 0.12, "imgHeight": sizeMultiplier * 0.12, "toolTipText": qsTr("Digital Light") }) items.availablePieces.model.append( { "imgName": "gateAnd.svg", "componentSrc": "AndGate.qml", "imgWidth": sizeMultiplier * 0.15, "imgHeight": sizeMultiplier * 0.12, "toolTipText": qsTr("AND gate") }) items.availablePieces.model.append( { "imgName": "gateNand.svg", "componentSrc": "NandGate.qml", "imgWidth": sizeMultiplier * 0.15, "imgHeight": sizeMultiplier * 0.12, "toolTipText": qsTr("NAND gate") }) items.availablePieces.model.append( { "imgName": "gateNor.svg", "componentSrc": "NorGate.qml", "imgWidth": sizeMultiplier * 0.15, "imgHeight": sizeMultiplier * 0.12, "toolTipText": qsTr("NOR gate") }) items.availablePieces.model.append( { "imgName": "gateNot.svg", "componentSrc": "NotGate.qml", "imgWidth": sizeMultiplier * 0.15, "imgHeight": sizeMultiplier * 0.12, "toolTipText": qsTr("NOT gate") }) items.availablePieces.model.append( { "imgName": "gateOr.svg", "componentSrc": "OrGate.qml", "imgWidth": sizeMultiplier * 0.15, "imgHeight": sizeMultiplier * 0.12, "toolTipText": qsTr("OR gate") }) items.availablePieces.model.append( { "imgName": "gateXor.svg", "componentSrc": "XorGate.qml", "imgWidth": sizeMultiplier * 0.15, "imgHeight": sizeMultiplier * 0.12, "toolTipText": qsTr("XOR gate") }) items.availablePieces.model.append( { "imgName": "comparator.svg", "componentSrc": "Comparator.qml", "imgWidth": sizeMultiplier * 0.3, "imgHeight": sizeMultiplier * 0.25, "toolTipText": qsTr("Comparator") }) items.availablePieces.model.append( { "imgName": "BCDTo7Segment.svg", "componentSrc": "BCDToSevenSegment.qml", "imgWidth": sizeMultiplier * 0.3, "imgHeight": sizeMultiplier * 0.4, "toolTipText": qsTr("BCD To 7 Segment") }) items.availablePieces.model.append( { "imgName": "sevenSegmentDisplay.svgz", "componentSrc": "SevenSegment.qml", "imgWidth": sizeMultiplier * 0.18, "imgHeight": sizeMultiplier * 0.4, "toolTipText": qsTr("7 Segment Display") }) items.availablePieces.model.append( { "imgName": "switchOff.svg", "componentSrc": "Switch.qml", "imgWidth": sizeMultiplier * 0.18, "imgHeight": sizeMultiplier * 0.15, "toolTipText": qsTr("Switch") }) items.availablePieces.model.append( { "imgName": "signalGenerator.svg", "componentSrc": "SignalGenerator.qml", "imgWidth": sizeMultiplier * 0.25, "imgHeight": sizeMultiplier * 0.18, "toolTipText": qsTr("Signal Generator") }) items.availablePieces.model.append( { "imgName": "bcdCounter.svg", "componentSrc": "BcdCounter.qml", "imgWidth": sizeMultiplier * 0.3, "imgHeight": sizeMultiplier * 0.4, "toolTipText": qsTr("BCD Counter") }) } function isTutorialMode() { return items.isTutorialMode } function checkAnswer() { - // for levels with single light - if (currentLevel != 6 && currentLevel != 8 && currentLevel != 10 && currentLevel != 12) { - if (determiningComponents[0].inputTerminals.itemAt(0).value == 1) - items.bonus.good('tux') - else - items.bonus.bad('tux') - } else if (currentLevel == 6) { + if (currentLevel == 6) { var digitalLight = determiningComponents[determiningComponents.length - 1] var switch1 = determiningComponents[0] var switch2 = determiningComponents[1] var switch1InitialState = switch1.imgSrc var switch2InitialState = switch2.imgSrc for (var A = 0; A <= 1; A++) { for (var B = 0; B <= 1; B++) { switch1.imgSrc = A == 1 ? "switchOn.svg" : "switchOff.svg" switch2.imgSrc = B == 1 ? "switchOn.svg" : "switchOff.svg" updateComponent(switch1.index) updateComponent(switch2.index) var operationResult = A ^ B if (operationResult != digitalLight.inputTerminals.itemAt(0).value) { switch1.imgSrc = switch1InitialState switch2.imgSrc = switch2InitialState updateComponent(switch1.index) updateComponent(switch2.index) items.bonus.bad('tux') return } } } items.bonus.good('tux') } else if (currentLevel == 8) { var switch1 = determiningComponents[0] var switch2 = determiningComponents[1] var switch3 = determiningComponents[2] var digitalLight = determiningComponents[3] var switch1InitialState = switch1.imgSrc var switch2InitialState = switch2.imgSrc var switch3InitialState = switch3.imgSrc for (var A = 0; A <= 1; A++) { for (var B = 0; B <= 1; B++) { for (var C = 0; C <= 1; C++) { switch1.imgSrc = A == 1 ? "switchOn.svg" : "switchOff.svg" switch2.imgSrc = B == 1 ? "switchOn.svg" : "switchOff.svg" switch3.imgSrc = C == 1 ? "switchOn.svg" : "switchOff.svg" updateComponent(switch1.index) updateComponent(switch2.index) updateComponent(switch3.index) var operationResult = A | (B & C) if (operationResult != digitalLight.inputTerminals.itemAt(0).value) { switch1.imgSrc = switch1InitialState switch2.imgSrc = switch2InitialState switch3.imgSrc = switch3InitialState updateComponent(switch1.index) updateComponent(switch2.index) updateComponent(switch3.index) items.bonus.bad('tux') return } } } } items.bonus.good('tux') } else if (currentLevel == 10) { var switch1 = determiningComponents[0] var switch2 = determiningComponents[1] var switch3 = determiningComponents[2] var digitalLight = determiningComponents[3] var switch1InitialState = switch1.imgSrc var switch2InitialState = switch2.imgSrc var switch3InitialState = switch3.imgSrc for (var A = 0; A <= 1; A++) { for (var B = 0; B <= 1; B++) { for (var C = 0; C <= 1; C++) { switch1.imgSrc = A == 1 ? "switchOn.svg" : "switchOff.svg" switch2.imgSrc = B == 1 ? "switchOn.svg" : "switchOff.svg" switch3.imgSrc = C == 1 ? "switchOn.svg" : "switchOff.svg" updateComponent(switch1.index) updateComponent(switch2.index) updateComponent(switch3.index) var operationResult = A ^ (B ^ C) if (operationResult != digitalLight.inputTerminals.itemAt(0).value) { switch1.imgSrc = switch1InitialState switch2.imgSrc = switch2InitialState switch3.imgSrc = switch3InitialState updateComponent(switch1.index) updateComponent(switch2.index) updateComponent(switch3.index) items.bonus.bad('tux') return } } } } items.bonus.good('tux') } else if (currentLevel == 12) { var switch1 = determiningComponents[0] var digitalLight = determiningComponents[1] var switch1InitialState = switch1.imgSrc for (var A = 0; A <= 1; A++) { switch1.imgSrc = A == 1 ? "switchOn.svg" : "switchOff.svg" updateComponent(switch1.index) var operationResult = !A if (operationResult != digitalLight.inputTerminals.itemAt(0).value) { switch1.imgSrc = switch1InitialState updateComponent(switch1.index) items.bonus.bad('tux') return } } items.bonus.good('tux') + } else if (currentLevel == 13) { + var switch1 = determiningComponents[0] + var switch2 = determiningComponents[1] + + var digitalLight = determiningComponents[2] + + var switch1InitialState = switch1.imgSrc + var switch2InitialState = switch2.imgSrc + + for (var A = 0; A <= 1; A++) { + for (var B = 0; B <= 1; B++) { + switch1.imgSrc = A == 1 ? "switchOn.svg" : "switchOff.svg" + switch2.imgSrc = B == 1 ? "switchOn.svg" : "switchOff.svg" + + updateComponent(switch1.index) + updateComponent(switch2.index) + + var operationResult = A & B + + if (operationResult != digitalLight.inputTerminals.itemAt(0).value) { + switch1.imgSrc = switch1InitialState + switch2.imgSrc = switch2InitialState + updateComponent(switch1.index) + updateComponent(switch2.index) + items.bonus.bad('tux') + return + } + } + } + items.bonus.good('tux') + } else if (currentLevel == 14) { + var switch1 = determiningComponents[0] + var switch2 = determiningComponents[1] + + var digitalLight = determiningComponents[2] + + var switch1InitialState = switch1.imgSrc + var switch2InitialState = switch2.imgSrc + + for (var A = 0; A <= 1; A++) { + for (var B = 0; B <= 1; B++) { + switch1.imgSrc = A == 1 ? "switchOn.svg" : "switchOff.svg" + switch2.imgSrc = B == 1 ? "switchOn.svg" : "switchOff.svg" + + updateComponent(switch1.index) + updateComponent(switch2.index) + + var operationResult = A | B + + if (operationResult != digitalLight.inputTerminals.itemAt(0).value) { + switch1.imgSrc = switch1InitialState + switch2.imgSrc = switch2InitialState + updateComponent(switch1.index) + updateComponent(switch2.index) + items.bonus.bad('tux') + return + } + } + } + items.bonus.good('tux') + } else if (currentLevel == 15) { + var switch1 = determiningComponents[0] + var switch2 = determiningComponents[1] + + var digitalLight = determiningComponents[2] + + var switch1InitialState = switch1.imgSrc + var switch2InitialState = switch2.imgSrc + + for (var A = 0; A <= 1; A++) { + for (var B = 0; B <= 1; B++) { + switch1.imgSrc = A == 1 ? "switchOn.svg" : "switchOff.svg" + switch2.imgSrc = B == 1 ? "switchOn.svg" : "switchOff.svg" + + updateComponent(switch1.index) + updateComponent(switch2.index) + + var operationResult = !(A | B) + + if (operationResult != digitalLight.inputTerminals.itemAt(0).value) { + switch1.imgSrc = switch1InitialState + switch2.imgSrc = switch2InitialState + updateComponent(switch1.index) + updateComponent(switch2.index) + items.bonus.bad('tux') + return + } + } + } + items.bonus.good('tux') + } + else { + if (determiningComponents[0].inputTerminals.itemAt(0).value == 1) + items.bonus.good('tux') + else + items.bonus.bad('tux') } } function nextLevel() { if(numberOfLevel < ++currentLevel ) { currentLevel = 1 } reset(); } function previousLevel() { if(--currentLevel < 1) { currentLevel = numberOfLevel } reset(); } function reset() { deselect() stop() items.availablePieces.model.clear() initLevel() } // Creates component from ListWidget to the drawing board area function createComponent(x, y, componentIndex) { x = x / items.playArea.width y = y / items.playArea.height var index if(deletedIndex.length > 0) { index = deletedIndex[deletedIndex.length - 1] deletedIndex.pop() } else index = components.length var component = items.availablePieces.repeater.itemAt(componentIndex) var electricComponent = Qt.createComponent("qrc:/gcompris/src/activities/digital_electricity/components/" + component.source) //console.log("Error loading component:", electricComponent.errorString()) components[index] = electricComponent.createObject( items.playArea, { "index": index, "posX": x, "posY": y, "imgSrc": component.imageName, "toolTipTxt": component.toolTipTxt, "imgWidth": component.imageWidth, "imgHeight": component.imageHeight, "destructible": true }); toolDeleteSticky = false deselect() componentSelected(index) updateComponent(index) } /* Creates wire between two terminals. Condition for creation of wire is that an input terminal * can only be connected to 1 wire, output terminals can be connected by any number of wires, and * an input terminal can be connected with an output terminal only. 'connected' variable is used * to make sure that an input is connected by only 1 wire. */ function terminalPointSelected(terminal) { if(selectedTerminal == -1 || selectedTerminal == terminal) selectedTerminal = terminal else if((selectedTerminal.type != terminal.type) && (selectedTerminal.parent != terminal.parent)) { var inTerminal = terminal.type == "In" ? terminal : selectedTerminal var outTerminal = terminal.type == "Out" ? terminal : selectedTerminal if(connected[inTerminal] == undefined || connected[inTerminal] == -1) { createWire(inTerminal, outTerminal, true) } deselect() } else { deselect() selectedTerminal = terminal terminal.selected = true } } function createWire(inTerminal, outTerminal, destructible) { var wireComponent = Qt.createComponent("qrc:/gcompris/src/activities/digital_electricity/Wire.qml") var wire = wireComponent.createObject( items.playArea, { "from": outTerminal, "to": inTerminal, "destructible": destructible }); inTerminal.value = outTerminal.value inTerminal.wires.push(wire) outTerminal.wires.push(wire) updateWires(inTerminal.parent.index) updateWires(outTerminal.parent.index) updateComponent(inTerminal.parent.index) connected[inTerminal] = outTerminal } /* Updates the output of the component. 'wireVisited' is used to update the value of * each wire once which will avoid updating the outputs of components in an infinite loop. */ function updateComponent(index) { var wireVisited = [] components[index].updateOutput(wireVisited) } /* Updates the orientation of the wire. It is called whenever a new wire is created or * an object is rotated. */ function updateWires(index) { var component = components[index] if(component == undefined || component.noOfInputs == undefined || component.noOfOutputs == undefined) return var rotatedAngle = component.initialAngle * Math.PI / 180 for(var i = 0 ; i < component.noOfInputs ; ++i) { var terminal = component.inputTerminals.itemAt(i) if(terminal.wires.length != 0) { var wire = terminal.wires[0] var otherAngle = wire.from.parent.initialAngle * Math.PI / 180 var x = wire.from.xCenterFromComponent var y = wire.from.yCenterFromComponent var x1 = wire.from.xCenter - x + x * Math.cos(otherAngle) - y * Math.sin(otherAngle) var y1 = wire.from.yCenter - y + x * Math.sin(otherAngle) + y * Math.cos(otherAngle) x = terminal.xCenterFromComponent y = terminal.yCenterFromComponent var x2 = terminal.xCenter - x + x * Math.cos(rotatedAngle) - y * Math.sin(rotatedAngle) var y2 = terminal.yCenter - y + x * Math.sin(rotatedAngle) + y * Math.cos(rotatedAngle) var width = Math.pow((Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2)),0.5) + 2 var angle = (180/Math.PI)*Math.atan((y2-y1)/(x2-x1)) if(x2 - x1 < 0) angle = angle - 180 wire.x = x1 wire.y = y1 wire.width = width wire.rotation = angle } } for(var i = 0 ; i < component.noOfOutputs ; ++i) { var terminal = component.outputTerminals.itemAt(i) for(var j = 0 ; j < terminal.wires.length ; ++j) { var x = terminal.xCenterFromComponent var y = terminal.yCenterFromComponent var x1 = terminal.xCenter - x + x * Math.cos(rotatedAngle) - y * Math.sin(rotatedAngle) var y1 = terminal.yCenter - y + x * Math.sin(rotatedAngle) + y * Math.cos(rotatedAngle) var wire = terminal.wires[j] var otherAngle = wire.to.parent.initialAngle * Math.PI / 180 x = wire.to.xCenterFromComponent y = wire.to.yCenterFromComponent var x2 = wire.to.xCenter - x + x * Math.cos(otherAngle) - y * Math.sin(otherAngle) var y2 = wire.to.yCenter - y + x * Math.sin(otherAngle) + y * Math.cos(otherAngle) var width = Math.pow((Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2)),0.5) + 2 var angle = (180/Math.PI)*Math.atan((y2-y1)/(x2-x1)) if(x2 - x1 < 0) angle = angle - 180 wire.x = x1 wire.y = y1 wire.width = width wire.rotation = angle } } } function deselect() { if(toolDeleteSticky == false) { toolDelete = false items.availablePieces.toolDelete.state = "notSelected" } items.availablePieces.rotateLeft.state = "canNotBeSelected" items.availablePieces.rotateRight.state = "canNotBeSelected" items.availablePieces.info.state = "canNotBeSelected" items.infoTxt.visible = false selectedIndex = -1 selectedTerminal = -1 for(var i = 0 ; i < components.length ; ++i) { var component = components[i] for(var j = 0 ; j < component.noOfInputs ; ++j) component.inputTerminals.itemAt(j).selected = false for(var j = 0 ; j < component.noOfOutputs ; ++j) component.outputTerminals.itemAt(j).selected = false } } function removeComponent(index) { var component = components[index] for(var i = 0 ; i < component.noOfInputs ; ++i) { var terminal = component.inputTerminals.itemAt(i) if(terminal.wires.length != 0) // Input Terminal can have only 1 wire removeWire(terminal.wires[0]) } for(var i = 0 ; i < component.noOfOutputs ; ++i) { var terminal = component.outputTerminals.itemAt(i) while (terminal.wires.length != 0) { removeWire(terminal.wires[0]) // Output Terminal can have more than 1 wire } } components[index].destroy() deletedIndex.push(index) deselect() } function removeWire(wire) { var inTerminal = wire.to var outTerminal = wire.from var removeIndex = inTerminal.wires.indexOf(wire) inTerminal.wires.splice(removeIndex,1) removeIndex = outTerminal.wires.indexOf(wire) outTerminal.wires.splice(removeIndex,1) connected[wire.to] = -1 inTerminal.value = 0 wire.destroy() updateComponent(inTerminal.parent.index) deselect() } function componentSelected(index) { selectedIndex = index items.availablePieces.rotateLeft.state = "canBeSelected" items.availablePieces.rotateRight.state = "canBeSelected" items.availablePieces.info.state = "canBeSelected" } function rotateLeft() { components[selectedIndex].rotationAngle = -2 components[selectedIndex].rotateComponent.start() } function rotateRight() { components[selectedIndex].rotationAngle = 2 components[selectedIndex].rotateComponent.start() } function displayInfo() { var component = components[selectedIndex] var componentTruthTable = component.truthTable deselect() items.infoTxt.visible = true items.infoTxt.text = component.information if(component.infoImageSrc != undefined) { items.infoImage.imgVisible = true items.infoImage.source = url + component.infoImageSrc } else { items.infoImage.imgVisible = false items.infoImage.source = "" } if(componentTruthTable.length == 0) items.displayTruthTable = false else { items.displayTruthTable = true var truthTable = items.truthTablesModel truthTable.clear() truthTable.rows = componentTruthTable.length truthTable.columns = componentTruthTable[0].length truthTable.inputs = component.noOfInputs truthTable.outputs = component.noOfOutputs for(var i = 0 ; i < componentTruthTable.length ; ++i) for(var j = 0 ; j < componentTruthTable[i].length ; ++j) truthTable.append({'value': componentTruthTable[i][j]}) } } function updateToolTip(toolTipTxt) { items.toolTip.show(toolTipTxt) }