Skip to content

Commit

Permalink
Merge pull request #108 from Arquisoft/refactor-game
Browse files Browse the repository at this point in the history
Refactor game to avoid code repetition
  • Loading branch information
pelazas authored Apr 27, 2024
2 parents 186895a + aad1fad commit c057b15
Show file tree
Hide file tree
Showing 9 changed files with 89 additions and 220 deletions.
18 changes: 9 additions & 9 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -119,15 +119,15 @@ services:
GROUP_SERVICE_URL: http://groupservice:8005
MULTIPLAYER_SERVICE_URL: http://multiplayerservice:8006

webapp:
container_name: webapp-${teamname:-defaultASW}
image: ghcr.io/arquisoft/wiq_en2a/webapp:latest
profiles: ["dev", "prod"]
build: ./webapp
depends_on:
- gatewayservice
ports:
- "80:80"
# webapp:
# container_name: webapp-${teamname:-defaultASW}
# image: ghcr.io/arquisoft/wiq_en2a/webapp:latest
# profiles: ["dev", "prod"]
# build: ./webapp
# depends_on:
# - gatewayservice
# ports:
# - "80:80"

prometheus:
image: prom/prometheus
Expand Down
3 changes: 2 additions & 1 deletion multiplayerservice/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ require('dotenv').config();
const io = socketIo(server, {
cors: {
//origin: 'http://conoceryvencer.xyz',
origin: process.env.WEBAPP_ENPOINT || 'http://localhost',
//origin: process.env.WEBAPP_ENPOINT || 'http://localhost',
origin: 'http://localhost:3000',
methods: ['GET', 'POST'],
credentials: true
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
import { FC, useEffect, useMemo, useState } from 'react'
import { Player, Question4Answers } from './GameSinglePlayer'
import { FC, useCallback, useEffect, useMemo, useState } from 'react'
import { Player, Question4Answers } from './singleplayer/GameSinglePlayer'
import axios from 'axios';
import shuffleAnswers from './util/SuffleAnswers';
import calculatePoints from './util/CalculatePoints';
import { SocketProps } from './multiplayer/GameMultiPlayer';
import "./QuestionsGame.scss"

interface PlayingGameProps {
questions: Question4Answers[]
setCurrentStage: (n: number) => void;
setPlayers: (players:Player[]) => void;
players: Player[];

setPlayers?: (players:Player[]) => void;
players?: Player[];
socket?: SocketProps;
partyCode?: string;
}

const PlayingGame: FC<PlayingGameProps> = ({questions, setCurrentStage, setPlayers, players}) => {
const PlayingGame: FC<PlayingGameProps> = ({questions, setCurrentStage, setPlayers, players, socket, partyCode}) => {

const uuid = localStorage.getItem("userUUID");
//const apiEndpoint = 'http://conoceryvencer.xyz:8000'
const apiEndpoint = process.env.REACT_APP_API_ENDPOINT || 'http://localhost:8000';

const [currentQuestion, setCurrentQuestion] = useState(0);
Expand All @@ -22,19 +28,44 @@ const PlayingGame: FC<PlayingGameProps> = ({questions, setCurrentStage, setPlaye

const [isWaiting, setIsWaiting] = useState<boolean>(false);

const answersShuffled = useMemo(() => {
return questions.map((question) => {
const answers = [question.correctAnswer, question.incorrectAnswer1, question.incorrectAnswer2, question.incorrectAnswer3];
for (let i = answers.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[answers[i], answers[j]] = [answers[j], answers[i]];
}
return answers;
});
}, [questions]);
const answersShuffled = useMemo(() => shuffleAnswers(questions), [questions]);

const endGame = useCallback(async () => {
const totalPoints = calculatePoints(correctAnswers, questions.length);
const requestData = {
"players": [{
"uuid": uuid,
"nCorrectAnswers": correctAnswers,
"nWrongAnswers": questions.length - correctAnswers,
"totalScore": totalPoints,
"isWinner": false
}]
};

const previousScore = parseInt(localStorage.getItem("score"));
localStorage.setItem("score", (previousScore + totalPoints).toString());

await axios.post(`${apiEndpoint}/updateStats`, requestData);
if(players){
players.map(player => {
const randomPoints = Math.floor(Math.random() * (1000 - 100 + 1) / 50) * 50 + 100;
if(player.isBot){
player.points += randomPoints;
}else {
player.points += calculatePoints(correctAnswers, questions.length);
}
return player;
})
setPlayers(players);
setCurrentStage(3);
}
if(socket)
socket.emit('playerFinished', partyCode, totalPoints);

}, [correctAnswers, questions.length, uuid, apiEndpoint, socket, partyCode, players, setPlayers, setCurrentStage]);

useEffect(() => {
const intervalId = setInterval(() => {
const intervalId = setInterval(async () => {
if((currentQuestion+1) < questions.length){
if (seconds > 0) {
setSeconds(prevSeconds => prevSeconds - 1);
Expand All @@ -43,12 +74,15 @@ const PlayingGame: FC<PlayingGameProps> = ({questions, setCurrentStage, setPlaye
setSelectedAnswer(null);
clearInterval(intervalId);
setSeconds(10);
if(currentQuestion+2 === questions.length && partyCode){ // is multiplayer
await endGame()
}
}
}
}, 1000);

return () => clearInterval(intervalId);
}, [seconds, currentQuestion, questions]);
}, [seconds, currentQuestion, questions, partyCode, endGame]);

const handleAnswerClick = async (answer: string, isCorrect:boolean) => {
setSeconds(10);
Expand All @@ -65,45 +99,12 @@ const PlayingGame: FC<PlayingGameProps> = ({questions, setCurrentStage, setPlaye
}, 1000);
setIsWaiting(false);
}
if(currentQuestion+2 === questions.length && partyCode){
await endGame();
}

};

const finishGame = async() => {
const totalPoints = calculatePoints(correctAnswers, questions.length);
// the player has finished the game
// update stats for each player
players.map(player => {
const randomPoints = Math.floor(Math.random() * (1000 - 100 + 1) / 50) * 50 + 100;
if(player.isBot){
player.points += randomPoints;
}else {
player.points += calculatePoints(correctAnswers, questions.length);
}
return player;
})
setPlayers(players);

const requestData ={ "players": [{
"uuid": uuid,
"nCorrectAnswers": correctAnswers,
"nWrongAnswers": questions.length - correctAnswers,
"totalScore": totalPoints,
"isWinner": false
}]}

// update score in localstorage
const previousScore = parseInt(localStorage.getItem("score"))
localStorage.setItem("score", (previousScore + totalPoints).toString())
setCurrentStage(3);
await axios.post(`${apiEndpoint}/updateStats`, requestData);
}

const calculatePoints = (correctAnswers: number, totalQuestions: number) => {
const incorrectQuestions = totalQuestions - correctAnswers;
const points = correctAnswers * 100 - incorrectQuestions * 25;
return points;
}

const getAnswers = () => {
const answers = answersShuffled[currentQuestion];
if (answers.length > 4) {
Expand Down Expand Up @@ -144,7 +145,8 @@ const PlayingGame: FC<PlayingGameProps> = ({questions, setCurrentStage, setPlaye
<>
<p data-testid="result">You answered {correctAnswers} out of {questions.length} questions correctly.</p>
<p data-testid="points">You earned {calculatePoints(correctAnswers, questions.length)} points.</p>
<button onClick={() => finishGame()} data-testid="next-button">Next</button>
{partyCode && <p data-testid="waiting">Waiting for the rest of the players to finish...</p>}
{players &&<button onClick={() => endGame()} data-testid="next-button">Next</button>}
</>
)}
</div>
Expand Down
4 changes: 2 additions & 2 deletions webapp/src/components/game/multiplayer/GameMultiPlayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import MenuMultiplayer from './MenuMultiplayer';
import { Container } from '@mui/material';
import LobbyMultiPlayer from './LobbyMultiPlayer';
import { Question4Answers } from '../singleplayer/GameSinglePlayer';
import QuestionsMultiPlayer from './QuestionsMultiPlayer';
import ScoreboardGame from '../ScoreboardGame';
import PlayingGame from '../PlayingGame';

interface GameMultiPlayerProps {

Expand Down Expand Up @@ -114,7 +114,7 @@ const GameMultiPlayer: FC<GameMultiPlayerProps> = () => {
<Container sx={{ mt: 9 }}>
{stage === 1 && <MenuMultiplayer socket={socket} handleCurrentStage={handleCurrentStage} handlePartyCode={handlePartyCode}/>}
{stage === 2 && <LobbyMultiPlayer socket={socket} handleCurrentStage={handleCurrentStage} partyCode={partyCode} users={users}/>}
{stage === 3 && <QuestionsMultiPlayer socket={socket} handleCurrentStage={handleCurrentStage} questions={questions} partyCode={partyCode}/>}
{stage === 3 && <PlayingGame socket={socket} setCurrentStage={handleCurrentStage} questions={questions} partyCode={partyCode}/>}
{stage === 4 && <ScoreboardGame userScoresMultiPlayer={sortedUsersByPoints}/>}
</Container>
)
Expand Down
151 changes: 0 additions & 151 deletions webapp/src/components/game/multiplayer/QuestionsMultiPlayer.tsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import axios from 'axios';
import { useState, useEffect } from 'react';
import LobbyGame from './LobbyGameSinglePlayer';
import PlayingGame from './PlayingGameSinglePlayer';
import PlayingGame from '../PlayingGame';
import ScoreboardGame from '../ScoreboardGame';
import { Container } from '@mui/material';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { render, fireEvent, waitFor,screen } from '@testing-library/react';
import PlayingGame from './PlayingGameSinglePlayer';
import PlayingGame from '../PlayingGame';

// Mock de las props necesarias para el componente
const mockProps = {
Expand Down
7 changes: 7 additions & 0 deletions webapp/src/components/game/util/CalculatePoints.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const calculatePoints = (correctAnswers: number, totalQuestions: number) => {
const incorrectQuestions = totalQuestions - correctAnswers;
const points = correctAnswers * 100 - incorrectQuestions * 25;
return points;
}

export default calculatePoints;
Loading

0 comments on commit c057b15

Please sign in to comment.