diff --git a/gatewayservice/gateway-service.js b/gatewayservice/gateway-service.js index 822dc57..41540bf 100644 --- a/gatewayservice/gateway-service.js +++ b/gatewayservice/gateway-service.js @@ -68,6 +68,36 @@ app.get('/imgs/cities/question', async (req, res) => { } }); +app.get('/imgs/monuments/question', async (req, res) => { + try { + // Forward the request to the question service + const questionResponse = await axios.get(questionServiceUrl+'/imgs/monuments/question', req.body); + res.json(questionResponse.data); + } catch (error) { + res.status(error.response.status).json({ error: error.response.data.error }); + } +}); + +app.get('/imgs/tourist_attractions/question', async (req, res) => { + try { + // Forward the request to the question service + const questionResponse = await axios.get(questionServiceUrl+'/imgs/tourist_attractions/question', req.body); + res.json(questionResponse.data); + } catch (error) { + res.status(error.response.status).json({ error: error.response.data.error }); + } +}); + +app.get('/imgs/foods/question', async (req, res) => { + try { + // Forward the request to the question service + const questionResponse = await axios.get(questionServiceUrl+'/imgs/foods/question', req.body); + res.json(questionResponse.data); + } catch (error) { + res.status(error.response.status).json({ error: error.response.data.error }); + } +}); + app.post('/imgs/answer', async (req, res) => { try { const answer = req.body.answer; diff --git a/questionservice/question-service.js b/questionservice/question-service.js index d22cec0..000fea9 100644 --- a/questionservice/question-service.js +++ b/questionservice/question-service.js @@ -31,7 +31,7 @@ class WIQ_API{ imgToAssociatedMap = new Map() //Num of fetched items - const itemsNum = 100 + const itemsNum = 200 //Required by wikidata to accept the request const headers = new Headers(); @@ -50,16 +50,37 @@ class WIQ_API{ for (let i = 0; i < numOfChosen; i++) { this.#getRandomNumNotInSetAndUpdate(itemsNum, chosenNums) } - + const associates = [] const imgs = [] - for(var i=0;i0){ + imgs.push(data.results.bindings[chosenNums.pop()].image.value) + associates.push(finalChosenLabels.pop()) + imgToAssociatedMap.set(imgs[counter], associates[counter]) + counter-- } - chosenNums = [] //Choose a random item of the chosen to make the question const chosenNum = this.#getRandomNumNotInSetAndUpdate(numOfChosen,chosenNums) const chosenAssociate = associates[chosenNum] @@ -98,8 +119,8 @@ app.get('/imgs/flags/question', async (req, res) => { SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". } ?item wdt:P31 wd:Q6256; wdt:P41 ?image. - FILTER NOT EXISTS { ?item wdt:P41 wd:Q3024110 } - }` + } + LIMIT 200` const question = JSON.parse(await wiq.getQuestionAndImages(query,"flags","belongs to")); res.json(question); }); @@ -112,14 +133,66 @@ app.get('/imgs/flags/question', async (req, res) => { */ app.get('/imgs/cities/question', async (req, res) => { //Gets city images and their associated names - const query = `SELECT ?item ?itemLabel ?image WHERE - { - SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". } - ?item wdt:P31 wd:Q515; + const query = `SELECT ?item ?itemLabel ?image WHERE { + SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". } + ?item wdt:P31 wd:Q515. + ?item wdt:P18 ?image. + } + LIMIT 200` + const question = JSON.parse(await wiq.getQuestionAndImages(query,"imagen","corresponds to")); + res.json(question); +}); + +/** + * Returns the needed information to construct a question of the form + * "Which of the following images corresponds to xMonument?" with 4 options + * @param {} req - Not used + * @param {Object} res - Contains the question (question) and the monuments (images) +*/ +app.get('/imgs/monuments/question', async (req, res) => { + //Gets monument images and their associated names + const query = `SELECT ?item ?itemLabel ?image WHERE { + SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". } + ?item wdt:P31 wd:Q4989906; wdt:P18 ?image. - FILTER NOT EXISTS { ?item wdt:P41 wd:Q3024110. } - } - LIMIT 100` + } + LIMIT 200` + const question = JSON.parse(await wiq.getQuestionAndImages(query,"images","corresponds to")); + res.json(question); +}); + +/** + * Returns the needed information to construct a question of the form + * "Which of the following tourist attractions corresponds to xTouristAttraction?" with 4 options + * @param {} req - Not used + * @param {Object} res - Contains the question (question) and the tourist attractions (images) +*/ +app.get('/imgs/tourist_attractions/question', async (req, res) => { + //Gets attractions images and their associated names + const query = `SELECT ?item ?itemLabel ?image WHERE { + SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". } + ?item wdt:P31 wd:Q570116; + wdt:P18 ?image. + } + LIMIT 200` + const question = JSON.parse(await wiq.getQuestionAndImages(query,"images","corresponds to")); + res.json(question); +}); + +/** + * Returns the needed information to construct a question of the form + * "Which of the following images corresponds to xFood?" with 4 options + * @param {} req - Not used + * @param {Object} res - Contains the question (question) and the foods (images) +*/ +app.get('/imgs/foods/question', async (req, res) => { + //Gets food images and their associated names + const query = `SELECT ?item ?itemLabel ?image WHERE { + SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". } + ?item wdt:P31 wd:Q8195619; + wdt:P18 ?image. + } + LIMIT 200` const question = JSON.parse(await wiq.getQuestionAndImages(query,"images","corresponds to")); res.json(question); }); diff --git a/webapp/src/components/Game.jsx b/webapp/src/components/Game.jsx index 1c6566e..fed60c3 100644 --- a/webapp/src/components/Game.jsx +++ b/webapp/src/components/Game.jsx @@ -7,6 +7,9 @@ import Question from "./Question"; const Game = () => { const [flagGameStarted, setFlagGameStarted] = useState(false); const [cityGameStarted, setCityGameStarted] = useState(false); + const [monumentGameStarted, setMonumentGameStarted] = useState(false); + const [touristAttractionGameStarted, setTouristAttractionGameStarted] = useState(false); + const [foodGameStarted, setFoodGameStarted] = useState(false); const isAuthenticated = useIsAuthenticated(); const navigate = useNavigate(); const auth = useAuthUser(); @@ -16,6 +19,15 @@ const Game = () => { const startCitiesGame = () => { setCityGameStarted(!cityGameStarted); }; + const startMonumentsGame = () => { + setMonumentGameStarted(!monumentGameStarted); + }; + const startTouristAttractionsGame = () => { + setTouristAttractionGameStarted(!touristAttractionGameStarted); + }; + const startFoodsGame = () => { + setFoodGameStarted(!foodGameStarted); + }; useEffect(() => { if (!isAuthenticated()) { navigate("/login"); @@ -24,21 +36,37 @@ const Game = () => { return (
- {isAuthenticated()? (flagGameStarted || cityGameStarted) ?( + {isAuthenticated()? (flagGameStarted || cityGameStarted || monumentGameStarted + || touristAttractionGameStarted || foodGameStarted) ?(
{flagGameStarted && } {cityGameStarted && } + {monumentGameStarted && } + {touristAttractionGameStarted && } + {foodGameStarted && }
) : (
-

{auth.username}, Let's Play!

+

{auth.username}, Let's Play! Guess the...

+ + +
):""}