From 02da8998b2dd4eb6c40a6de3c089f2fb4b266f8a Mon Sep 17 00:00:00 2001 From: Pablo Lobeto Arenas Date: Mon, 1 Apr 2024 23:10:49 +0200 Subject: [PATCH 1/6] Added query for questions about chemical elements --- game/qgservice/generatorLogic/queries.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/game/qgservice/generatorLogic/queries.js b/game/qgservice/generatorLogic/queries.js index e4960ef..f41a73c 100644 --- a/game/qgservice/generatorLogic/queries.js +++ b/game/qgservice/generatorLogic/queries.js @@ -40,6 +40,13 @@ SELECT ?country ?countryLabel ?capital ?capitalLabel WHERE { } ` +const chemicalElementQuery = `SELECT ?element ?elementLabel ?symbol WHERE { + ?element wdt:P31 wd:Q11344; # Instance of chemical element + wdt:P246 ?symbol. # Chemical symbol + SERVICE wikibase:label { bd:serviceParam wikibase:language "en". } +} +` + const chatgptPrompt = ` From 06c6f80f6bc5292ba30a8885d4b46f3b4e38bfc5 Mon Sep 17 00:00:00 2001 From: Pablo Lobeto Arenas Date: Mon, 1 Apr 2024 23:46:22 +0200 Subject: [PATCH 2/6] Added chemical elements questions to qgController --- game/qgservice/QGController.js | 16 ++++++-- game/qgservice/generatorLogic/BindResults.js | 15 ++++++- game/qgservice/generatorLogic/queries.js | 5 ++- .../generatorLogic/questiongenerator.js | 40 ++++++++++++++++++- 4 files changed, 69 insertions(+), 7 deletions(-) diff --git a/game/qgservice/QGController.js b/game/qgservice/QGController.js index 63b6ca8..9eb7730 100644 --- a/game/qgservice/QGController.js +++ b/game/qgservice/QGController.js @@ -1,8 +1,8 @@ -const { generateQuestionPopulation, generateQuestionCapital } = require('./generatorLogic/questiongenerator'); +const { generateQuestionPopulation, generateQuestionCapital, generateQuestionChemical } = require('./generatorLogic/questiongenerator'); const Question4Answers = require('./Question4Answers'); const { executeSparqlQuery } = require('./generatorLogic/SparqlQuery') const { bindCapitalsResults, bindPopulationResults } = require('./generatorLogic/BindResults') -const { spainCapitalQuery, worldCapitalQuery, worldPopulationQuery } = require('./generatorLogic/queries') +const { spainCapitalQuery, worldCapitalQuery, worldPopulationQuery, chemicalElementQuery } = require('./generatorLogic/queries') const { createMathQuestions } = require('./generatorLogic/MathQuestions') let QGController = { @@ -32,7 +32,7 @@ let QGController = { } // world population - nQuestions = 5; + nQuestions = 2; const worldPopulationResult = await executeSparqlQuery(worldPopulationQuery); const worldPopulation = bindPopulationResults(worldPopulationResult) @@ -41,6 +41,16 @@ let QGController = { questions.push(question); } + // chemical elements + nQuestions = 3; + const chemicalResult = await executeSparqlQuery(chemicalElementQueryQuery); + const chemicalElement = bindCapitalsResults(chemicalResult) + + for (let i = 0; i < nQuestions; i++) { + const question = generateQuestionChemical(chemicalElement); + questions.push(question); + } + // math questions const mathquestions = await createMathQuestions(5) questions.push(...mathquestions) diff --git a/game/qgservice/generatorLogic/BindResults.js b/game/qgservice/generatorLogic/BindResults.js index 60330b6..ce6bcdc 100644 --- a/game/qgservice/generatorLogic/BindResults.js +++ b/game/qgservice/generatorLogic/BindResults.js @@ -24,7 +24,20 @@ function bindPopulationResults(queryResult){ return populationMap } +function bindChemicalResults(queryResult){ + const chemicalElementMap = new Map(); + + queryResult.results.bindings.forEach(entry => { + const elementLabel = entry.elementLabel.value; + const symbol = parseFloat(entry.symbol.value); + populationMap.set(symbol, elementLabel); + }); + + return chemicalElementMap +} + module.exports = { bindCapitalsResults, - bindPopulationResults + bindPopulationResults, + bindChemicalResults } diff --git a/game/qgservice/generatorLogic/queries.js b/game/qgservice/generatorLogic/queries.js index f41a73c..47ac989 100644 --- a/game/qgservice/generatorLogic/queries.js +++ b/game/qgservice/generatorLogic/queries.js @@ -43,7 +43,7 @@ SELECT ?country ?countryLabel ?capital ?capitalLabel WHERE { const chemicalElementQuery = `SELECT ?element ?elementLabel ?symbol WHERE { ?element wdt:P31 wd:Q11344; # Instance of chemical element wdt:P246 ?symbol. # Chemical symbol - SERVICE wikibase:label { bd:serviceParam wikibase:language "en". } + SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". } } ` @@ -65,5 +65,6 @@ module.exports = { spainPopulationQuery, //chatgptPrompt, spainCapitalQuery, - worldCapitalQuery + worldCapitalQuery, + chemicalElementQuery }; diff --git a/game/qgservice/generatorLogic/questiongenerator.js b/game/qgservice/generatorLogic/questiongenerator.js index 5dbbfa5..00cd737 100644 --- a/game/qgservice/generatorLogic/questiongenerator.js +++ b/game/qgservice/generatorLogic/questiongenerator.js @@ -64,6 +64,43 @@ function generateQuestionCapital(countryCapitalMap) { incorrectAnswer2: incorrectAnswers[1], incorrectAnswer3: incorrectAnswers[2], }; + // Save the question to MongoDB + const newQuestion = new Question4Answers(question); + newQuestion.save() + .then(savedQuestion => { + console.log('Question saved to MongoDB:', savedQuestion); + }) + .catch(error => { + console.error('Error saving question to MongoDB:', error.message); + }); + + return question; + } + + function generateQuestionChemical(chemicalElementMap) { + const chemicalElementArray = Array.from(chemicalElementMap); + + const randomIndex = Math.floor(Math.random() * chemicalElementArray.length); + const [ symbol, chemical] = chemicalElementArray[randomIndex]; + + const incorrectAnswers = []; + while (incorrectAnswers.length < 3) { + const randomElement = chemicalElementArray[Math.floor(Math.random() * chemicalElementArray.length)]; + const [randomSymbol, randomElementName] = randomElement; + if (randomSymbol !== symbol && !incorrectAnswers.includes(randomElementName)) { + incorrectAnswers.push(randomElementName); + } + } + + // Create the question object + const question = { + uuid: uuid.v4(), + question: `What is the symbol of ${chemical}?`, + correctAnswer: symbol, + incorrectAnswer1: incorrectAnswers[0], + incorrectAnswer2: incorrectAnswers[1], + incorrectAnswer3: incorrectAnswers[2], + }; // Save the question to MongoDB const newQuestion = new Question4Answers(question); @@ -80,5 +117,6 @@ function generateQuestionCapital(countryCapitalMap) { module.exports = { generateQuestionPopulation, - generateQuestionCapital + generateQuestionCapital, + generateQuestionChemical }; \ No newline at end of file From ee850432c958d1e263ee1fae242f92e6085009ae Mon Sep 17 00:00:00 2001 From: Pablo Lobeto Arenas Date: Tue, 2 Apr 2024 00:13:21 +0200 Subject: [PATCH 3/6] Added query for monuments and the country it belongs --- game/qgservice/generatorLogic/queries.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/game/qgservice/generatorLogic/queries.js b/game/qgservice/generatorLogic/queries.js index 47ac989..c291f7a 100644 --- a/game/qgservice/generatorLogic/queries.js +++ b/game/qgservice/generatorLogic/queries.js @@ -47,6 +47,13 @@ const chemicalElementQuery = `SELECT ?element ?elementLabel ?symbol WHERE { } ` +const monumentQuery = `SELECT ?monument ?monumentLabel ?country ?countryLabel WHERE { + ?monument wdt:P31 wd:Q4989906; # Instance of historical monument + wdt:P17 ?country. # Country of the monument + SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". } +} +LIMIT 100 +` const chatgptPrompt = ` @@ -66,5 +73,6 @@ module.exports = { //chatgptPrompt, spainCapitalQuery, worldCapitalQuery, - chemicalElementQuery + chemicalElementQuery, + monumentQuery }; From 924e101a372bf22474ff20c784c4b108a838607b Mon Sep 17 00:00:00 2001 From: Pablo Lobeto Arenas Date: Tue, 2 Apr 2024 00:18:21 +0200 Subject: [PATCH 4/6] Added bind result for monument --- game/qgservice/generatorLogic/BindResults.js | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/game/qgservice/generatorLogic/BindResults.js b/game/qgservice/generatorLogic/BindResults.js index ce6bcdc..a432738 100644 --- a/game/qgservice/generatorLogic/BindResults.js +++ b/game/qgservice/generatorLogic/BindResults.js @@ -30,14 +30,27 @@ function bindChemicalResults(queryResult){ queryResult.results.bindings.forEach(entry => { const elementLabel = entry.elementLabel.value; const symbol = parseFloat(entry.symbol.value); - populationMap.set(symbol, elementLabel); + chemicalElementMap.set(symbol, elementLabel); }); return chemicalElementMap } +function bindMonumentResults(queryResult){ + const monumentMap = new Map(); + + queryResult.results.bindings.forEach(entry => { + const monumentLabel = entry.monumentLabel.value; + const countryLabel = parseFloat(entry.countryLabel.value); + monumentMap.set(monumentLabel, countryLabel); + }); + + return monumentMap +} + module.exports = { bindCapitalsResults, bindPopulationResults, - bindChemicalResults + bindChemicalResults, + bindMonumentResults } From 2c87c929373530807236f7190d1cd19f6d6a88e9 Mon Sep 17 00:00:00 2001 From: Pablo Lobeto Arenas Date: Tue, 2 Apr 2024 00:30:41 +0200 Subject: [PATCH 5/6] Added the question generator for monument --- game/qgservice/generatorLogic/queries.js | 2 +- .../generatorLogic/questiongenerator.js | 45 +++++++++++++++++-- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/game/qgservice/generatorLogic/queries.js b/game/qgservice/generatorLogic/queries.js index c291f7a..8f355a6 100644 --- a/game/qgservice/generatorLogic/queries.js +++ b/game/qgservice/generatorLogic/queries.js @@ -52,7 +52,7 @@ const monumentQuery = `SELECT ?monument ?monumentLabel ?country ?countryLabel WH wdt:P17 ?country. # Country of the monument SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". } } -LIMIT 100 +LIMIT 1000 ` diff --git a/game/qgservice/generatorLogic/questiongenerator.js b/game/qgservice/generatorLogic/questiongenerator.js index 00cd737..ac3fcf8 100644 --- a/game/qgservice/generatorLogic/questiongenerator.js +++ b/game/qgservice/generatorLogic/questiongenerator.js @@ -87,8 +87,8 @@ function generateQuestionCapital(countryCapitalMap) { while (incorrectAnswers.length < 3) { const randomElement = chemicalElementArray[Math.floor(Math.random() * chemicalElementArray.length)]; const [randomSymbol, randomElementName] = randomElement; - if (randomSymbol !== symbol && !incorrectAnswers.includes(randomElementName)) { - incorrectAnswers.push(randomElementName); + if (randomElementName !== chemical && !incorrectAnswers.includes(randomSymbol)) { + incorrectAnswers.push(randomSymbol); } } @@ -115,8 +115,47 @@ function generateQuestionCapital(countryCapitalMap) { return question; } +function generateQuestionMonument(monumentMap) { + const monumentArray = Array.from(monumentMap); + + const randomIndex = Math.floor(Math.random() * monumentArray.length); + const [ monumentLabel, countryLabel] = monumentArray[randomIndex]; + + const incorrectAnswers = []; + while (incorrectAnswers.length < 3) { + const randomMonument = monumentArray[Math.floor(Math.random() * monumentArray.length)]; + const [randomMonumentLabel, randomCountry] = randomMonument; + if (randomMonumentLabel !== monumentLabel && !incorrectAnswers.includes(randomCountry)) { + incorrectAnswers.push(random); + } + } + + // Create the question object + const question = { + uuid: uuid.v4(), + question: `Where is ${monumentLabel}?`, + correctAnswer: countryLabel, + incorrectAnswer1: incorrectAnswers[0], + incorrectAnswer2: incorrectAnswers[1], + incorrectAnswer3: incorrectAnswers[2], + }; + +// Save the question to MongoDB +const newQuestion = new Question4Answers(question); +newQuestion.save() + .then(savedQuestion => { + console.log('Question saved to MongoDB:', savedQuestion); + }) + .catch(error => { + console.error('Error saving question to MongoDB:', error.message); + }); + +return question; +} + module.exports = { generateQuestionPopulation, generateQuestionCapital, - generateQuestionChemical + generateQuestionChemical, + generateQuestionMonument }; \ No newline at end of file From a5898f50bf36da69394c5373e24ae8b568f5462a Mon Sep 17 00:00:00 2001 From: Pablo Lobeto Arenas Date: Sat, 6 Apr 2024 05:04:45 +0200 Subject: [PATCH 6/6] Check thar game works correctly and added the monument to the game --- game/qgservice/QGController.js | 28 +++++++++++++------ game/qgservice/generatorLogic/BindResults.js | 4 +-- .../generatorLogic/questiongenerator.js | 2 +- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/game/qgservice/QGController.js b/game/qgservice/QGController.js index 9eb7730..33ec9c1 100644 --- a/game/qgservice/QGController.js +++ b/game/qgservice/QGController.js @@ -1,8 +1,8 @@ -const { generateQuestionPopulation, generateQuestionCapital, generateQuestionChemical } = require('./generatorLogic/questiongenerator'); +const { generateQuestionPopulation, generateQuestionCapital, generateQuestionChemical, generateQuestionMonument } = require('./generatorLogic/questiongenerator'); const Question4Answers = require('./Question4Answers'); const { executeSparqlQuery } = require('./generatorLogic/SparqlQuery') -const { bindCapitalsResults, bindPopulationResults } = require('./generatorLogic/BindResults') -const { spainCapitalQuery, worldCapitalQuery, worldPopulationQuery, chemicalElementQuery } = require('./generatorLogic/queries') +const { bindCapitalsResults, bindPopulationResults, bindChemicalResults, bindMonumentResults } = require('./generatorLogic/BindResults') +const { spainCapitalQuery, worldCapitalQuery, worldPopulationQuery, chemicalElementQuery, monumentQuery } = require('./generatorLogic/queries') const { createMathQuestions } = require('./generatorLogic/MathQuestions') let QGController = { @@ -12,7 +12,7 @@ let QGController = { const questions = []; // spain capitals - nQuestions = 2; + nQuestions = 3; const spainQueryResult = await executeSparqlQuery(spainCapitalQuery); const spainCapitals = bindCapitalsResults(spainQueryResult) @@ -22,7 +22,7 @@ let QGController = { } // world capitals - nQuestions = 3; + nQuestions = 2; const worldQueryResult = await executeSparqlQuery(worldCapitalQuery); const worldCapitals = bindCapitalsResults(worldQueryResult) @@ -42,17 +42,27 @@ let QGController = { } // chemical elements - nQuestions = 3; - const chemicalResult = await executeSparqlQuery(chemicalElementQueryQuery); - const chemicalElement = bindCapitalsResults(chemicalResult) + nQuestions = 2; + const chemicalResult = await executeSparqlQuery(chemicalElementQuery); + const chemicalElement = bindChemicalResults(chemicalResult) for (let i = 0; i < nQuestions; i++) { const question = generateQuestionChemical(chemicalElement); questions.push(question); } + // monuments + nQuestions = 2; + const monumentResult = await executeSparqlQuery(monumentQuery); + const monument = bindMonumentResults(monumentResult) + + for (let i = 0; i < nQuestions; i++) { + const question = generateQuestionMonument(monument); + questions.push(question); + } + // math questions - const mathquestions = await createMathQuestions(5) + const mathquestions = await createMathQuestions(3) questions.push(...mathquestions) res.json(questions); diff --git a/game/qgservice/generatorLogic/BindResults.js b/game/qgservice/generatorLogic/BindResults.js index a432738..25ecc42 100644 --- a/game/qgservice/generatorLogic/BindResults.js +++ b/game/qgservice/generatorLogic/BindResults.js @@ -29,7 +29,7 @@ function bindChemicalResults(queryResult){ queryResult.results.bindings.forEach(entry => { const elementLabel = entry.elementLabel.value; - const symbol = parseFloat(entry.symbol.value); + const symbol = entry.symbol.value; chemicalElementMap.set(symbol, elementLabel); }); @@ -41,7 +41,7 @@ function bindMonumentResults(queryResult){ queryResult.results.bindings.forEach(entry => { const monumentLabel = entry.monumentLabel.value; - const countryLabel = parseFloat(entry.countryLabel.value); + const countryLabel = entry.countryLabel.value; monumentMap.set(monumentLabel, countryLabel); }); diff --git a/game/qgservice/generatorLogic/questiongenerator.js b/game/qgservice/generatorLogic/questiongenerator.js index ac3fcf8..e259aa5 100644 --- a/game/qgservice/generatorLogic/questiongenerator.js +++ b/game/qgservice/generatorLogic/questiongenerator.js @@ -126,7 +126,7 @@ function generateQuestionMonument(monumentMap) { const randomMonument = monumentArray[Math.floor(Math.random() * monumentArray.length)]; const [randomMonumentLabel, randomCountry] = randomMonument; if (randomMonumentLabel !== monumentLabel && !incorrectAnswers.includes(randomCountry)) { - incorrectAnswers.push(random); + incorrectAnswers.push(randomCountry); } }