Compare commits

...

43 Commits

Author SHA1 Message Date
Thomas Chazot 6005281801 Image qui fonctionne
continuous-integration/drone/push Build is passing Details
1 year ago
Thomas CHAZOT 547f02227f revert 53ac430987
continuous-integration/drone/push Build is passing Details
1 year ago
Thomas Chazot 53ac430987 fix /
continuous-integration/drone/push Build is passing Details
1 year ago
Thomas Chazot 450123404e icon pour download
1 year ago
Thomas Chazot fc11d0a0e5 évite doublons
1 year ago
Thomas Chazot 6a106608ba évite doublons
1 year ago
Thomas Chazot a01003d3c8 correct background dans le endgame
continuous-integration/drone/push Build is passing Details
1 year ago
Baptiste MARCEL 752fbaacb2 Merge branch 'master' of https://codefirst.iut.uca.fr/git/Crypteam/Cryptid
continuous-integration/drone/push Build is passing Details
1 year ago
Baptiste MARCEL bb6e6c6cba modif page home
1 year ago
Pierre FERREIRA 32bc994b41 Merge pull request 'EngGamePage' (#115) from EngGamePage into master
continuous-integration/drone/push Build is passing Details
1 year ago
Baptiste MARCEL e4df530d95 modif page présentation
continuous-integration/drone/push Build is passing Details
1 year ago
Baptiste MARCEL d8c5af20ba Merge branch 'master' into EngGamePage
continuous-integration/drone/push Build is passing Details
1 year ago
Baptiste MARCEL 669ca42bd1 modif page end game
continuous-integration/drone/push Build is passing Details
1 year ago
Pierre FERREIRA 32e3f1ce2e Merge pull request 'fixRT10' (#114) from fixRT10 into master
continuous-integration/drone/push Build is passing Details
1 year ago
Pierre Ferreira 1f00476f7f Merge branch 'master' of https://codefirst.iut.uca.fr/git/Crypteam/Cryptid into fixRT10
continuous-integration/drone/push Build is passing Details
1 year ago
Pierre Ferreira 294cd87672 commit pour merge le fix de thomas 🔧
1 year ago
Thomas Chazot 7d994ad89f indice afficher même après changement du graph
continuous-integration/drone/push Build is passing Details
1 year ago
Thomas Chazot 8ef1fb05bf fix pour pas qu'on puisse mettre plus de noeuds que voulu
continuous-integration/drone/push Build is passing Details
1 year ago
Pierre Ferreira fe2836b636 Merge branch 'master' of https://codefirst.iut.uca.fr/git/Crypteam/Cryptid into fixRT10
1 year ago
Pierre Ferreira d23c1277cd changement du nom du bouton ✏️
continuous-integration/drone/push Build is passing Details
1 year ago
Thomas Chazot e561118af7 fix pour pas que l'on puisse appuyer plusieurs fois sur le même noeuds
continuous-integration/drone/push Build is passing Details
1 year ago
Thomas Chazot 2d5ca7ae70 nombre de noeuds et d'indice dans la session
continuous-integration/drone/push Build is passing Details
1 year ago
Pierre Ferreira d6bc06bcba fix de tout le scoreboard
continuous-integration/drone/push Build is passing Details
1 year ago
Pierre Ferreira dab6ab2755 fix de plein de bug de rt10, nouvelle gestion de paramètre, problème de trad etc. 🚑
continuous-integration/drone/push Build is passing Details
1 year ago
Thomas CHAZOT de58aff695 Mise à jour de 'cryptide_project/src/Pages/Lobbies.tsx'
continuous-integration/drone/push Build is passing Details
1 year ago
Thomas CHAZOT af89e69255 Mise à jour de 'cryptide_project/Scripts/social_graph.sh'
continuous-integration/drone/push Build is passing Details
1 year ago
Pierre FERREIRA e94001ce1d Merge pull request 'sonarSmells' (#110) from sonarSmells into master
continuous-integration/drone/push Build is passing Details
1 year ago
Pierre Ferreira f88e8e66b4 fix du css, et du pb dans lobby 🚑
continuous-integration/drone/push Build is passing Details
1 year ago
Pierre Ferreira 5d89f8e1bd 🚑
continuous-integration/drone/push Build is failing Details
1 year ago
Pierre Ferreira 927bb1ff6b fix bug sonar 1
continuous-integration/drone/push Build is passing Details
1 year ago
Pierre FERREIRA 50092b31d6 Merge pull request 'trad' (#109) from trad into master
continuous-integration/drone/push Build is passing Details
1 year ago
Pierre Ferreira 5cdc99b168 Merge branch 'master' of https://codefirst.iut.uca.fr/git/Crypteam/Cryptid into trad
continuous-integration/drone/push Build is passing Details
1 year ago
Thomas Chazot 9e22cefef3 téléchargement au pdf fini
continuous-integration/drone/push Build is passing Details
1 year ago
Pierre Ferreira 20822a2311 changement de tout les tostring fr pour qu'ils aient la langue dynamique
continuous-integration/drone/push Build is passing Details
1 year ago
Pierre Ferreira 19d95804dd trad suite au merge 🔧
continuous-integration/drone/push Build is passing Details
1 year ago
Pierre Ferreira f2d6b89d03 Merge branch 'master' of https://codefirst.iut.uca.fr/git/Crypteam/Cryptid into trad
1 year ago
Pierre Ferreira 0a6e5bba9a traduction de l'historique en fr et en 📝
continuous-integration/drone/push Build is passing Details
1 year ago
Pierre Ferreira 8efeaca9d6 finitions de la traduction du tuto en fr 🌐
continuous-integration/drone/push Build is passing Details
1 year ago
Pierre Ferreira e7b0dfb9b4 mise en place de la traducton sur les pages de jeu et sur la première partie du tuto 📝
continuous-integration/drone/push Build is failing Details
1 year ago
Thomas CHAZOT df666c2fe6 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
1 year ago
Pierre Ferreira edb90ea926 🌐 toujours plus de trad 🌐
continuous-integration/drone/push Build is passing Details
1 year ago
Pierre Ferreira 34a53d016f ajout des traduction fr et en sur le lobby 💥
continuous-integration/drone/push Build is passing Details
1 year ago
Pierre Ferreira d65ec81b59 ajout de la traduction pour toute la page NewPlay pour fr et en
continuous-integration/drone/push Build is passing Details
1 year ago

@ -42,7 +42,7 @@ steps:
IMAGENAME: mysql:latest
CONTAINERNAME: mysql
COMMAND: create
OVERWRITE: true
#OVERWRITE: true
PRIVATE: false
CODEFIRST_CLIENTDRONE_ENV_MYSQL_ROOT_PASSWORD:
from_secret: MYSQL_ROOT_PASSWORD
@ -53,6 +53,9 @@ steps:
CODEFIRST_CLIENTDRONE_ENV_MYSQL_PASSWORD:
from_secret: MYSQL_PASSWORD
ADMINS: thomaschazot2,pierreferreira,baptistemarcel
when:
branch:
- CI/CD
- name: container-web
image: plugins/docker
@ -70,7 +73,7 @@ steps:
#depends_on: [ build ]
when:
branch:
- master
- CI/CD
#container deployment

@ -1,5 +1,6 @@
#!/bin/sh
npm install --force
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

@ -67,6 +67,9 @@ class AuthController {
// Stocker l'utilisateur dans la session)
req.session.user = user;
req.session.user.nbNodes = 25
req.session.user.nbIndices = 3
// Envoyer une réponse réussie
console.log("[" + hour + ":" + minutes + "] " + user.pseudo + " have been connected.");
@ -82,6 +85,20 @@ class AuthController {
}
}
static async UpdateNbNodesIndices(req, res){
try{
if (req.session.user){
req.session.user.nbNodes = req.body.nbNodes;
req.session.user.nbIndices = req.body.nbIndices;
res.status(200).json({ message: 'Nombre de noeuds mis à jour.' });
}
}
catch(error){
console.error(error);
res.status(500).json({ error: 'Erreur lors de la mise à jour du nombre de noeuds.' });
}
}
static async logout(req, res) {
const pseudo = req.session.user.pseudo;
const date = new Date();

@ -87,7 +87,7 @@ class SessionController {
req.session.user.onlineStats = {nbGames: nbGamesOL,
nbWins: nbWinsOL,
ratio: ratioOL};
res.status(200).json({ user: req.session.user });
}
catch(error){

@ -11,6 +11,7 @@ router.delete('/auth/logout', AuthController.logout)
router.delete('/auth/delAccount', AuthController.delAccount)
router.post('/auth/validatePassword', AuthController.validatePassword);
router.put('/auth/updatePassword', AuthController.updatePassword);
router.put('/session/updateNbNodes', AuthController.UpdateNbNodesIndices);
// Routes pour les sessions
router.get('/session', SessionController.getUserInformation);
@ -21,6 +22,7 @@ router.post('/session/addHardEnigmaStats', SessionController.addHardEnigmaStats)
router.post('/session/addOnlineStats', SessionController.addOnlineStats);
router.put('/session/updatePseudo', SessionController.UpdatePseudo);
// Routes pour le daily scoreboard
router.get('/scoreboard/getDailyMastermind', ScoreboardController.getDailyMastermind);
router.get('/scoreboard/getDailyEasyEnigma', ScoreboardController.getDailyEasyEnigma);

@ -94,11 +94,11 @@ function App() {
<Route path={`${basePath}/signup`} element={<SignUp />} />
<Route path={`${basePath}/presentation`} element={<Home />} />
<Route path={`${basePath}/lobby`} element={<Lobby/>} />
<Route path={`${basePath}/endgame`} element={<EndGame/>} />
<Route path={`${basePath}/endgame`} element={<EndGame lang={locale}/>} />
<Route path={`${basePath}/game`} element={<InGame locale={locale} changeLocale={changeLocale}/>}/>
<Route path={`${basePath}/info`} element={<InfoPage locale={locale} changeLocale={changeLocale}/>} />
<Route path={`${basePath}/tutorial`} element={<Tutorial locale={locale} changeLocale={changeLocale}/>} />
<Route path={`${basePath}/deduc`} element={<DeducCheck/>} />
<Route path={`${basePath}/deduc`} element={<DeducCheck lang={locale}/>} />
<Route path={`${basePath}/TheRealDeduc`} element={<DeducGrid/>} />
<Route path={`${basePath}/profile`} element={<Profile/>} />
<Route path={`${basePath}/join`} element={<Lobbies/>}/>

@ -24,6 +24,7 @@ import {basePath} from "../AdressSetup"
import GameCreator from "../model/GameCreator";
import Stub from "../model/Stub";
import EnigmeDuJourCreator from "../model/EnigmeDuJourCreator";
import { useIntl } from "react-intl";
interface MyGraphComponentProps {
onNodeClick: (shouldShowChoiceBar: boolean) => void;
@ -56,6 +57,8 @@ interface MyGraphComponentProps {
setChangeGraph : (func: (nbNodes: number, nbIndices: number) => void) => void
handleTurn :() => void
lang: string
}
let askedWrongBot = false
@ -72,7 +75,6 @@ let cptHistory = 0
let lastNodes: NodePerson[] = []
let cptEndgame = 0
let endgame= false
let firstHistory = true
let cptSquare = 0
let cptOnAskedWrong = 0
let cptPlayerLeft = 0
@ -83,13 +85,19 @@ let testTemps = 0
let testFirst = false
let gameStartTmp = true
let index = 0
let firstHistory = true
const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick, handleShowTurnBar, handleTurnBarTextChange, playerTouched, setPlayerTouched, changecptTour, solo, isDaily, difficulty, addToHistory, showLast, setNetwork, setNetworkEnigme, setPlayerIndex, askedWrong, setAskedWrong, importToPdf, setImportToPdf, importToJSON, setImportToJSON, setPutCorrectBackground, setPutGreyBackground, setPutImposssibleGrey, putCorrectBackground, putGreyBackground, putImposssibleGrey, handleTurn, setChangeGraph}) => {
const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick, handleShowTurnBar, handleTurnBarTextChange, playerTouched, setPlayerTouched, changecptTour, solo, isDaily, difficulty, addToHistory, showLast, setNetwork, setNetworkEnigme, setPlayerIndex, askedWrong, setAskedWrong, importToPdf, setImportToPdf, importToJSON, setImportToJSON, setPutCorrectBackground, setPutGreyBackground, setPutImposssibleGrey, putCorrectBackground, putGreyBackground, putImposssibleGrey, handleTurn, setChangeGraph, lang}) => {
let cptTour: number = 1
//* Gestion du temps :
let initMtn = 0
//* traduction
const intl = useIntl();
const {isLoggedIn, user, manager} = useAuth();
const { indices, indice, person, personNetwork, setNodeIdData, players, setPlayersData, askedPersons, setActualPlayerIndexData, room, actualPlayerIndex, turnPlayerIndex, setIndicesData, setWinnerData, dailyEnigme, setNbCoupData, settempsData, setNetworkDataData, setSeedData, nodesC, temps, setPersonData, setPersonNetworkData, setDailyEnigmeData, gameStart, setGameStartData} = useGame();
const params = new URLSearchParams(window.location.search);
@ -98,6 +106,10 @@ const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick, handleS
const [lastIndex, setLastIndex] = useState(-1)
const [elapsedTime, setElapsedTime] = useState(0);
const [netEnigme, setNetEnigme] = useState<Map<number, Pair<Indice, boolean>[]> | null>(null)
const [downloaded, setDownloaded] = useState(false)
const [updateHistory, setUpdateHistory] = useState<() => void>(() => {})
useEffect(() => {
if (testFirst){
@ -180,7 +192,6 @@ const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick, handleS
gameStartTmp=gameStart
if (gameStartTmp){
setGameStartData(false)
console.log(gameStart)
setLastIndex(turnPlayerIndex)
setPlayerIndex(playerIndex)
}
@ -206,7 +217,7 @@ const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick, handleS
}
setActualPlayerIndexData(index)
if (playerIndex == actualPlayerIndex){
handleTurnBarTextChange("À vous de jouer")
handleTurnBarTextChange(intl.formatMessage({ id: 'game.yourTurn' }))
handleShowTurnBar(true)
}
}
@ -345,7 +356,54 @@ const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick, handleS
format: 'a4', // Format du papier (par exemple, a4)
});
pdf.addImage(canvas.toDataURL('image/png'), 'PNG', 0, 0, pdf.internal.pageSize.getWidth(), pdf.internal.pageSize.getHeight());
if (isDaily){
pdf.addPage();
let text = ""
if (difficulty === "easy"){
indices.forEach((indice, index) => {
text += `Indice ${index + 1} : ${indice.ToString('fr')}.\n`
})
}
else{
const personIndice = new Map<number, string[]>()
indices.forEach((i, index) => {
personIndice.set(index, [])
})
netEnigme?.forEach((pairs, index) => {
pairs.forEach((pair) => {
const person = personNetwork?.getPersons().find((n) => index == n.getId())
const indice = indices.findIndex((i) => pair.first.getId() == i.getId())
if (person != undefined && indice != -1){
let string = "L'indice numéro " + (indice + 1) + " répond "
if (pair.second){
string += "vrai "
}
else{
string += "faux "
}
string += "pour " + person.getName()
personIndice.get(indice)?.push(string)
}
})
});
personIndice.forEach((indices, index) => {
text += `Indice ${index + 1}:\n`
indices.forEach((string) => {
text += `${string}.\n`
})
})
}
pdf.text(text, 10, 10);
}
setDownloaded(true)
pdf.save('graph.pdf');
});
}
}, [importToPdf])
@ -359,6 +417,7 @@ const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick, handleS
link.click();
URL.revokeObjectURL(url);
}
useEffect(() => {
@ -377,11 +436,9 @@ const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick, handleS
setIndicesData(choosenIndices)
const map = EnigmeDuJourCreator.createEnigme(networkPerson, choosenIndices, choosenPerson, Stub.GenerateIndice())
setDailyEnigmeData(map)
addToHistory("<----- [Tour " + 1 +"/"+networkPerson.getPersons().length + "] ----->");
changecptTour(1)
testTemps=0
}
useEffect(() => {
@ -437,6 +494,7 @@ const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick, handleS
}
}
};
const networkData = { nodes: nodes, edges: graph.edges };
const network = new Network(container, networkData, initialOptions);
@ -444,8 +502,20 @@ const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick, handleS
setNetwork(network)
setSeedData(network.getSeed())
if (solo){
if (solo && (difficulty === "intermediate" || !isDaily)){
addToHistory("<----- ["+ intl.formatMessage({ id: 'turn' }) +" " + 1 +"/"+networkData.nodes.length + "] ----->");
}
else{
indices.forEach((indice, index) => {
addToHistory(intl.formatMessage({ id: 'indice' }) + positionToEmoji(index, true) + " : " + indice.ToString(lang))
})
}
}
if (isDaily){
setNetworkEnigme(dailyEnigme)
setNetEnigme(dailyEnigme)
console.log(difficulty)
if (difficulty === "hard" || difficulty=== "intermediate"){
console.log(dailyEnigme)
@ -461,15 +531,6 @@ const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick, handleS
})
});
}
else if (difficulty === "easy"){
if (firstHistory){
firstHistory=false
indices.forEach((indice, index) => {
addToHistory("Indice " + positionToEmoji(index, true) + " : " + indice.ToString("fr"))
})
}
}
}
socket.on("give network", (playerId) => {
@ -539,7 +600,7 @@ const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick, handleS
setPlayerIndex(playerIndex)
setLastIndex(playerIndex)
if (playerIndex===actualPlayerIndex){
handleTurnBarTextChange("À vous de jouer")
handleTurnBarTextChange(intl.formatMessage({ id: 'game.yourTurn' }))
handleShowTurnBar(true)
}
}
@ -560,7 +621,6 @@ const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick, handleS
setPlayerIndex(index)
setLastIndex(index)
if (actualPlayerIndex==index){
handleTurnBarTextChange("À vous de jouer")
handleShowTurnBar(true)
}
})
@ -621,12 +681,12 @@ const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick, handleS
cptHistory++
if (cptHistory % 2 >= 0){
lastNodes.push(node)
addToHistory(testPlayers[askedIndex].pseudo + " à mis un " + positionToEmoji(askedIndex, works) + " à " + personNetwork.getPersons()[id].getName())
addToHistory(testPlayers[askedIndex].pseudo + intl.formatMessage({ id: 'history.mis' }) + positionToEmoji(askedIndex, works) + intl.formatMessage({ id: 'à' }) + personNetwork.getPersons()[id].getName())
}
}
if (playerIndex === actualPlayerIndex){
handleTurnBarTextChange("À vous de jouer")
handleTurnBarTextChange(intl.formatMessage({ id: 'game.yourTurn' }))
handleShowTurnBar(true)
}
else{
@ -671,7 +731,7 @@ const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick, handleS
setAskedWrong(true)
askedWrongBot=true
handleShowTurnBar(true)
handleTurnBarTextChange("Mauvais choix, posez un carré !")
handleTurnBarTextChange(intl.formatMessage({ id: 'game.wrong' }))
touchedPlayer = actualPlayerIndex
putGreyBackgroud()
}
@ -685,7 +745,7 @@ const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick, handleS
cptBug=0
cptOnAskedWrong ++
if (cptOnAskedWrong % 2 >= 0){
addToHistory(testPlayers[askingPlayer].pseudo + " ne peut plus poser de carré")
addToHistory(testPlayers[askingPlayer].pseudo + intl.formatMessage({ id: 'history.cantPose' }))
playerIndex = askingPlayer + 1
if(playerIndex == players.length){
playerIndex = 0
@ -693,7 +753,7 @@ const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick, handleS
setPlayerIndex(playerIndex)
setLastIndex(playerIndex)
if (playerIndex === actualPlayerIndex){
handleTurnBarTextChange("À vous de jouer")
handleTurnBarTextChange(intl.formatMessage({ id: 'game.yourTurn' }))
handleShowTurnBar(true)
}
else{
@ -749,14 +809,6 @@ const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick, handleS
})
}
else {
if (firstLap){
firstLap=false
if (solo && (difficulty === "intermediate" || !isDaily)){
addToHistory("<----- [Tour " + 1 +"/"+networkData.nodes.length + "] ----->");
}
}
}
const putCorrectBackground = () => {
@ -841,6 +893,7 @@ const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick, handleS
setLastIndex(-1)
setPlayerTouched(-1)
setWinnerData(winner)
firstHistory=true
first = true
@ -849,7 +902,6 @@ const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick, handleS
setAskedWrong(false)
askedWrongBot=false
endgame = true
firstHistory=true
cptBug=0
try{
if(isLoggedIn){
@ -875,6 +927,7 @@ const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick, handleS
}
finally{
setElapsedTime(0)
putCorrectBackground()
socket.off("end game")
socket.off("asked all")
socket.off("opacity activated")
@ -891,24 +944,6 @@ const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick, handleS
}
})
personNetwork.getPersons().forEach(p => {
let a = 0
for (let i of indices){
let tester = IndiceTesterFactory.Create(i)
if (tester.Works(p)){
a++
}
}
if (a==indices.length){
//networkData.nodes.update({id: p.getId(), label: p.getName() + "\n🔵"})
//console.log(p)
}
});
// Gérer le changement entre la physique et le déplacement manuel
network.on("dragging", (params) => {
if (params.nodes.length > 0) {
@ -1046,15 +1081,14 @@ const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick, handleS
const personTest = personNetwork?.getPersons().find((p) => p.getId() == params.nodes[0]) //person sélectionnée
const node = nodes.get().find((n: any) => params.nodes[0] == n.id)
if(node == undefined)return;
if (personTest != undefined && !node.label.includes(positionToEmoji(index, true)) && !node.label.includes(positionToEmoji(index, false))){ //si la personne existe et que le noeud n'a pas déjà été cliqué
if (node.label.includes(colorToEmoji(positionToColor(0), true)) || node.label.includes(colorToEmoji(positionToColor(0), false))) return
if (personTest != undefined){ //si la personne existe et que le noeud n'a pas déjà été cliqué
let index =0
let works = true
const statsTime = elapsedTime;
for (const i of indices){
const tester = IndiceTesterFactory.Create(i)
const test = tester.Works(personTest)
//@ts-ignore
if (node!=undefined){
if (node!=undefined && !node.label.includes(positionToEmoji(index, true)) && !node.label.includes(positionToEmoji(index, false))){
const nodeNode = nodes.get().find((n: any) => params.nodes[0] == n.id)
if(nodeNode == undefined)return;
networkData.nodes.update({id: params.nodes[0], label: nodeNode.label + positionToEmoji(index, test)})
@ -1072,7 +1106,7 @@ const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick, handleS
try{
console.log("time: " + testTemps)
if(user && isLoggedIn){
if(user && isLoggedIn && !downloaded){
if(solo){
if(isDaily){
// TODO: verif difficulté et add les stats
@ -1096,7 +1130,7 @@ const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick, handleS
}
else{
// add stats mastermind
if(user && user.mastermindStats){
if(user && user.mastermindStats && !downloaded){
manager.userService.addMastermindStats(user.pseudo, cptTour, elapsedTime);
}
}
@ -1113,9 +1147,9 @@ const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick, handleS
else{
if (isDaily){
if (difficulty==="intermediate"){
addToHistory(personTest.getName() + " n'est pas le coupable !"); //TODO préciser le nombre d'indice qu'il a de juste
addToHistory(personTest.getName() + intl.formatMessage({ id: 'history.NotCoupable' }));
cptTour ++; // On Incrémente le nombre de tour du joueur
addToHistory("<----- [Tour " + cptTour +"/"+networkData.nodes.length + "] ----->");
addToHistory("<----- ["+ intl.formatMessage({ id: 'turn' }) + " " + cptTour +"/"+networkData.nodes.length);
changecptTour(cptTour); // On le transmet a la page précédente avec la fonction
}
else if (difficulty==="easy"){
@ -1129,7 +1163,7 @@ const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick, handleS
}
}
else{
addToHistory(personTest.getName() + " n'est pas le coupable !"); //TODO préciser le nombre d'indice qu'il a de juste
addToHistory(personTest.getName() + intl.formatMessage({ id: 'history.NotCoupable' })); //TODO préciser le nombre d'indice qu'il a de juste
cptTour ++; // On Incrémente le nombre de tour du joueur
addToHistory("<----- [Tour " + cptTour +"/"+networkData.nodes.length + "] ----->");
changecptTour(cptTour); // On le transmet a la page précédente avec la fonction

@ -1,7 +1,7 @@
import React, {useEffect, useState} from 'react';
/* Naviagtion */
import { Navbar, Container, Nav, NavDropdown } from 'react-bootstrap';
import { Navbar, Container, Nav, NavDropdown } from 'react-bootstrap';
/* Lang */
import { FormattedMessage } from 'react-intl';
@ -58,13 +58,13 @@ function AppNavbar({changeLocale, locale}) {
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="me-auto">
<Nav.Link href={`${basePath}/`} style={{ color: theme.colors.text }}>
Jouer
<FormattedMessage id="navbar.play" />
</Nav.Link>
<Nav.Link href={`${basePath}/presentation`} style={{ color: theme.colors.text }}>
Présentation
<FormattedMessage id="navbar.presentation" />
</Nav.Link>
<Nav.Link href={`${basePath}/info`} style={{ color: theme.colors.text }}>
Info
<FormattedMessage id="navbar.info" />
</Nav.Link>
</Nav>
<div className='leftdiv'>

@ -20,6 +20,7 @@ import Bot from '../model/Bot';
/* server */
import { socket } from '../SocketConfig';
import { Form } from 'react-router-dom';
interface MyPlayerItemListProps {
player : Player,
@ -58,13 +59,13 @@ const PlayerItemList:React.FC<MyPlayerItemListProps> =({ player, room }) => {
{isBot && (
<ToggleButtonGroup type='radio' name={`options-${player.id}`} defaultValue={1}>
<ToggleButton id={`tbg-radio-1-${player.id}`} value={1}>
Facile
<FormattedMessage id='easy' />
</ToggleButton>
<ToggleButton id={`tbg-radio-2-${player.id}`} value={2}>
Intermédiaire
<FormattedMessage id='medium' />
</ToggleButton>
<ToggleButton id={`tbg-radio-3-${player.id}`} value={3}>
Fort
<FormattedMessage id='strong' />
</ToggleButton>
</ToggleButtonGroup>
)}

@ -8,6 +8,7 @@ import Person from '../res/img/Person.png'
import BotImg from '../res/img/bot.png'
import { socket } from '../SocketConfig';
import { FormattedMessage } from 'react-intl';
//@ts-ignore
@ -69,7 +70,7 @@ const PlayerList: React.FC<PlayerListProps> = ({ players, playerTouched, setPlay
textAlign: "center",
color: "white",
padding: "10px"}}
onClick={() => askEveryone()}>Ask everyone</button>
onClick={() => askEveryone()}><FormattedMessage id='askeveryone'/></button>
):
(
<button style={{
@ -80,7 +81,7 @@ const PlayerList: React.FC<PlayerListProps> = ({ players, playerTouched, setPlay
textAlign: "center",
color: "white",
padding: "10px"}}
onClick={() => askEveryone()}>Ask everyone</button>
onClick={() => askEveryone()}><FormattedMessage id='askeveryone'/></button>
)
}
</div>

@ -12,4 +12,17 @@
}
/* Personnalisez davantage selon vos préférences */
.carousselButton{
border:none;
background-color:darkgray;
color:white;
opacity: 60%;
width: 50px;
height: 70px;
font-size: 40px;
border-radius: 5px;
padding: 5px;
margin: 5px;
cursor: pointer;
}

@ -27,6 +27,8 @@ import { BiLineChart, BiLineChartDown } from 'react-icons/bi';
import { CarouselCaption } from 'react-bootstrap';
import { BsLine } from 'react-icons/bs';
import { FormattedMessage, useIntl } from 'react-intl';
//@ts-ignore
const ScoreBoard: React.FC<{ Player: User }> = ({ Player }) => {
const theme=useTheme();
@ -90,6 +92,21 @@ const ScoreBoard: React.FC<{ Player: User }> = ({ Player }) => {
fetchWeeklyStats();
}, []);
const intl = useIntl();
//@ts-ignore
const CustomPrevButton = ({ previousSlide }) => (
<button className='carousselButton' onClick={previousSlide}>&lt;</button>
);
//@ts-ignore
const CustomNextButton = ({ nextSlide }) => (
<button className='carousselButton' onClick={nextSlide}>&gt;</button>
);
return (
<Tabs
activeKey={activeTab}
@ -100,56 +117,66 @@ const ScoreBoard: React.FC<{ Player: User }> = ({ Player }) => {
}}
id="ScoreBoard"
className="tabsStats justify-content-around">
<Tab eventKey="perso" title="Vos Stats" disabled={!Player.pseudo.startsWith("Guest_") ? false : true}>
<Tab eventKey="perso"
title={intl.formatMessage({ id: 'score.tab.stat' })}
disabled={!Player.pseudo.startsWith("Guest_") ? false : true}>
<Tab.Content className={`tabsStats ${activeTab !== 'perso' ? 'hidden' : ''}`}>
<Carousel adaptiveHeight wrapAround slidesToShow={1} cellSpacing={10} key={carouselKey}>
<Carousel
renderCenterLeftControls={({ previousSlide }) => <CustomPrevButton previousSlide={previousSlide} />}
renderCenterRightControls={({ nextSlide }) => <CustomNextButton nextSlide={nextSlide} />}
adaptiveHeight
wrapAround
slidesToShow={1}
cellSpacing={10}
key={carouselKey}
>
<div className="stats">
<h5>Mastermind</h5>
<h5><FormattedMessage id='info.mdj.mastermind'/></h5>
<hr />
<p>Parties Jouées: {Player.mastermindStats.nbGames}</p>
<p>Best-Score: {Player.mastermindStats.bestScore}</p>
<p>Moyenne d'essai: {Player.mastermindStats.avgNbTry.toFixed(2)}</p>
<p><FormattedMessage id='score.nbPlayed'/> : {Player.mastermindStats.nbGames}</p>
<p><FormattedMessage id='score.best'/>: {Player.mastermindStats.bestScore}</p>
<p><FormattedMessage id='score.moy'/>: {Player.mastermindStats.avgNbTry.toFixed(2)}</p>
</div>
<div className="stats">
<h5>Enigme facile</h5>
<h5><FormattedMessage id='score.titre.easy'/></h5>
<hr />
<p>Parties Jouées: {Player.easyEnigmaStats.nbGames}</p>
<p>Nombre de victoires: {Player.easyEnigmaStats.nbWins}</p>
<p>Ratio V/D: {Player.easyEnigmaStats.ratio.toFixed(2) + "%"}</p>
<p>Meilleur temps: {Player.easyEnigmaStats.bestTime + "s"}</p>
<p>Moyenne de temps: {Player.easyEnigmaStats.avgTime.toFixed(2) + "s"}</p>
<p><FormattedMessage id='score.nbPlayed'/>: {Player.easyEnigmaStats.nbGames}</p>
<p><FormattedMessage id='score.NbWin'/>: {Player.easyEnigmaStats.nbWins}</p>
<p><FormattedMessage id='score.ratio'/>: {Player.easyEnigmaStats.ratio.toFixed(2) + "%"}</p>
<p><FormattedMessage id='score.bestTmp'/>: {Player.easyEnigmaStats.bestTime + "s"}</p>
<p><FormattedMessage id='score.moyTmp'/>: {Player.easyEnigmaStats.avgTime.toFixed(2) + "s"}</p>
</div>
<div className="stats">
<h5>Enigme moyenne</h5>
<h5><FormattedMessage id='score.titre.int'/></h5>
<hr />
<p>Parties Jouées: {Player.mediumEnigmaStats.nbGames}</p>
<p>Best-Score: {Player.mediumEnigmaStats.bestScore}</p>
<p>Moyenne d'essai: {Player.mediumEnigmaStats.avgNbTry.toFixed(2)}</p>
<p><FormattedMessage id='score.nbPlayed'/>: {Player.mediumEnigmaStats.nbGames}</p>
<p><FormattedMessage id='score.best'/>: {Player.mediumEnigmaStats.bestScore}</p>
<p><FormattedMessage id='score.moy'/>: {Player.mediumEnigmaStats.avgNbTry.toFixed(2)}</p>
</div>
<div className="stats">
<h5>Enigme difficile</h5>
<h5><FormattedMessage id='score.titre.hard'/></h5>
<hr />
<p>Parties Jouées: {Player.hardEnigmaStats.nbGames}</p>
<p>Nombre de victoires: {Player.hardEnigmaStats.nbWins}</p>
<p>Ratio V/D: {Player.hardEnigmaStats.ratio.toFixed(2) + "%"}</p>
<p>Meilleur temps: {Player.hardEnigmaStats.bestTime + "s"}</p>
<p>Moyenne de temps: {Player.hardEnigmaStats.avgTime.toFixed(2) + "s"}</p>
<p><FormattedMessage id='score.nbPlayed'/>: {Player.hardEnigmaStats.nbGames}</p>
<p><FormattedMessage id='score.NbWin'/>: {Player.hardEnigmaStats.nbWins}</p>
<p><FormattedMessage id='score.ratio'/>: {Player.hardEnigmaStats.ratio.toFixed(2) + "%"}</p>
<p><FormattedMessage id='score.bestTmp'/>: {Player.hardEnigmaStats.bestTime + "s"}</p>
<p><FormattedMessage id='score.moyTmp'/>: {Player.hardEnigmaStats.avgTime.toFixed(2) + "s"}</p>
</div>
<div className="stats">
<h5>En ligne</h5>
<h5><FormattedMessage id='score.online'/></h5>
<hr />
<p>Parties Jouées: {Player.onlineStats.nbGames}</p>
<p>Nombre de victoires: {Player.onlineStats.nbWins}</p>
<p>Ratio V/D: {Player.onlineStats.ratio.toFixed(2) + "s"}</p>
<p><FormattedMessage id='score.nbPlayed'/>: {Player.onlineStats.nbGames}</p>
<p><FormattedMessage id='score.NbWin'/>: {Player.onlineStats.nbWins}</p>
<p><FormattedMessage id='score.ratio'/>: {Player.onlineStats.ratio.toFixed(2) + "s"}</p>
</div>
</Carousel>
</Tab.Content>
</Tab>
<Tab eventKey="daily" title="Daily">
<Tab eventKey="daily" title={intl.formatMessage({ id: 'score.tab.quoti' })}>
<Tab.Content className={`tabsStats ${activeTab !== 'daily' ? 'hidden' : ''}`}>
<Carousel adaptiveHeight wrapAround slidesToShow={1} cellSpacing={10} key={carouselKey}>
<div className="stats">
<h5>Mastermind</h5>
<h5><FormattedMessage id='info.mdj.mastermind'/></h5>
<hr />
{dailyMastermindStats !== null ? (dailyMastermindStats.tab.length !== 0 ? dailyMastermindStats.tab.map((stats: any, index: number) => (
<>
@ -163,13 +190,13 @@ const ScoreBoard: React.FC<{ Player: User }> = ({ Player }) => {
</Row>
</>
)) : (
<p className='text-warning'>Nothing for the moment</p>
<p className='text-warning'><FormattedMessage id='score.nothing'/></p>
)) : (
<p className='text-warning'>Nothing for the moment</p>
<p className='text-warning'><FormattedMessage id='score.nothing'/></p>
)}
</div>
<div className="stats">
<h5>Enigme facile</h5>
<h5><FormattedMessage id='score.titre.easy'/></h5>
<hr />
{dailyEasyEnigmaStats !== null ? (dailyEasyEnigmaStats.tab.length !== 0 ? dailyEasyEnigmaStats.tab.map((stats: any, index: number) => (
<>
@ -183,13 +210,13 @@ const ScoreBoard: React.FC<{ Player: User }> = ({ Player }) => {
</Row>
</>
)) : (
<p className='text-warning'>Nothing for the moment</p>
<p className='text-warning'><FormattedMessage id='score.nothing'/></p>
)) : (
<p className='text-warning'>Nothing for the moment</p>
<p className='text-warning'><FormattedMessage id='score.nothing'/></p>
)}
</div>
<div className="stats">
<h5>Enigme moyenne</h5>
<h5><FormattedMessage id='score.titre.int'/></h5>
<hr />
{dailyMediumEnigmaStats !== null ? (dailyMediumEnigmaStats.tab.length !== 0 ? dailyMediumEnigmaStats.tab.map((stats: any, index: number) => (
<>
@ -203,13 +230,13 @@ const ScoreBoard: React.FC<{ Player: User }> = ({ Player }) => {
</Row>
</>
)) : (
<p className='text-warning'>Nothing for the moment</p>
<p className='text-warning'><FormattedMessage id='score.nothing'/></p>
)) : (
<p className='text-warning'>Nothing for the moment</p>
<p className='text-warning'><FormattedMessage id='score.nothing'/></p>
)}
</div>
<div className="stats">
<h5>Enigme difficile</h5>
<h5><FormattedMessage id='score.titre.hard'/></h5>
<hr />
{dailyHardEnigmaStats !== null ? (dailyHardEnigmaStats.tab.length !== 0 ? dailyHardEnigmaStats.tab.map((stats: any, index: number) => (
<>
@ -223,13 +250,13 @@ const ScoreBoard: React.FC<{ Player: User }> = ({ Player }) => {
</Row>
</>
)) : (
<p className='text-warning'>Nothing for the moment</p>
<p className='text-warning'><FormattedMessage id='score.nothing'/></p>
)) : (
<p className='text-warning'>Nothing for the moment</p>
<p className='text-warning'><FormattedMessage id='score.nothing'/></p>
)}
</div>
<div className="stats">
<h5>En ligne</h5>
<h5><FormattedMessage id='score.online'/></h5>
<hr />
{dailyOnlineStats !== null ? (dailyOnlineStats.tab.length !== 0 ? dailyOnlineStats.tab.map((stats: any, index: number) => (
<>
@ -243,19 +270,19 @@ const ScoreBoard: React.FC<{ Player: User }> = ({ Player }) => {
</Row>
</>
)) : (
<p className='text-warning'>Nothing for the moment</p>
<p className='text-warning'><FormattedMessage id='score.nothing'/></p>
)) : (
<p className='text-warning'>Nothing for the moment</p>
<p className='text-warning'><FormattedMessage id='score.nothing'/></p>
)}
</div>
</Carousel>
</Tab.Content>
</Tab>
<Tab eventKey="weekly" title="Weekly">
<Tab eventKey="weekly" title={intl.formatMessage({ id: 'score.tab.hebdo' })}>
<Tab.Content className={`tabsStats ${activeTab !== 'weekly' ? 'hidden' : ''}`}>
<Carousel adaptiveHeight wrapAround slidesToShow={1} cellSpacing={10} key={carouselKey}>
<div className="stats">
<h5>Mastermind</h5>
<h5><FormattedMessage id='info.mdj.mastermind'/></h5>
<hr />
{weeklyMastermindStats !== null ? (weeklyMastermindStats.tab.length !== 0 ? weeklyMastermindStats.tab.map((stats: any, index: number) => (
<>
@ -269,13 +296,13 @@ const ScoreBoard: React.FC<{ Player: User }> = ({ Player }) => {
</Row>
</>
)) : (
<p className='text-warning'>Nothing for the moment</p>
<p className='text-warning'><FormattedMessage id='score.nothing'/></p>
)) : (
<p className='text-warning'>Nothing for the moment</p>
<p className='text-warning'><FormattedMessage id='score.nothing'/></p>
)}
</div>
<div className="stats">
<h5>Enigme facile</h5>
<h5><FormattedMessage id='score.titre.easy'/></h5>
<hr />
{weeklyEasyEnigmaStats !== null ? (weeklyEasyEnigmaStats.tab.length !== 0 ? weeklyEasyEnigmaStats.tab.map((stats: any, index: number) => (
<>
@ -289,13 +316,13 @@ const ScoreBoard: React.FC<{ Player: User }> = ({ Player }) => {
</Row>
</>
)) : (
<p className='text-warning'>Nothing for the moment</p>
<p className='text-warning'><FormattedMessage id='score.nothing'/></p>
)) : (
<p className='text-warning'>Nothing for the moment</p>
<p className='text-warning'><FormattedMessage id='score.nothing'/></p>
)}
</div>
<div className="stats">
<h5>Enigme moyenne</h5>
<h5><FormattedMessage id='score.titre.int'/></h5>
<hr />
{weeklyMediumEnigmaStats !== null ? (weeklyMediumEnigmaStats.tab.length !== 0 ? weeklyMediumEnigmaStats.tab.map((stats: any, index: number) => (
<>
@ -309,13 +336,13 @@ const ScoreBoard: React.FC<{ Player: User }> = ({ Player }) => {
</Row>
</>
)) : (
<p className='text-warning'>Nothing for the moment</p>
<p className='text-warning'><FormattedMessage id='score.nothing'/></p>
)) : (
<p className='text-warning'>Nothing for the moment</p>
<p className='text-warning'><FormattedMessage id='score.nothing'/></p>
)}
</div>
<div className="stats">
<h5>Enigme difficile</h5>
<h5><FormattedMessage id='score.titre.hard'/></h5>
<hr />
{weeklyHardEnigmaStats !== null ? (weeklyHardEnigmaStats.tab.length !== 0 ? weeklyHardEnigmaStats.tab.map((stats: any, index: number) => (
<>
@ -329,13 +356,13 @@ const ScoreBoard: React.FC<{ Player: User }> = ({ Player }) => {
</Row>
</>
)) : (
<p className='text-warning'>Nothing for the moment</p>
<p className='text-warning'><FormattedMessage id='score.nothing'/></p>
)) : (
<p className='text-warning'>Nothing for the moment</p>
<p className='text-warning'><FormattedMessage id='score.nothing'/></p>
)}
</div>
<div className="stats">
<h5>En ligne</h5>
<h5><FormattedMessage id='score.titre.online'/></h5>
<hr />
{weeklyOnlineStats !== null ? (weeklyOnlineStats.tab.length !== 0 ? weeklyOnlineStats.tab.map((stats: any, index: number) => (
<>
@ -349,9 +376,9 @@ const ScoreBoard: React.FC<{ Player: User }> = ({ Player }) => {
</Row>
</>
)) : (
<p className='text-warning'>Nothing for the moment</p>
<p className='text-warning'><FormattedMessage id='score.nothing'/></p>
)) : (
<p className='text-warning'>Nothing for the moment</p>
<p className='text-warning'><FormattedMessage id='score.nothing'/></p>
)}
</div>
</Carousel>

@ -12,7 +12,6 @@ const TurnBar: React.FC<TurnBarProps> = ({text})=> {
style={{
borderColor: theme.colors.secondary
}}>
{/* texte changeable et a traduire */}
<p>{text}</p>
</div>
);

@ -22,6 +22,7 @@ import html2canvas from 'html2canvas';
import jsPDF from 'jspdf';
import {basePath} from "../AdressSetup"
import PersonNetwork from "../model/PersonsNetwork";
import { useIntl } from "react-intl";
interface TutorialGraphProps {
setNetwork: (network: Network) => void
@ -53,6 +54,9 @@ const TutorialGraph: React.FC<TutorialGraphProps> = ({showLast, setNetwork, setP
//* Gestion du temps :
let initMtn = 0
//* traduction
const intl = useIntl();
const {isLoggedIn, user, manager} = useAuth();
const {setIndiceData, setIndicesData, setActualPlayerIndexData, setWinnerData, setPlayersData, setNetworkDataData, setPersonData} = useGame();
const params = new URLSearchParams(window.location.search);
@ -63,7 +67,7 @@ const TutorialGraph: React.FC<TutorialGraphProps> = ({showLast, setNetwork, setP
if (first){
first = false
setActualPlayerIndexData(0)
handleTurnBarTextChange("C'est à vous de jouer !")
handleTurnBarTextChange(intl.formatMessage({ id: 'game.yourTurn' }))
handleShowTurnBar(true)
}
@ -234,7 +238,7 @@ const TutorialGraph: React.FC<TutorialGraphProps> = ({showLast, setNetwork, setP
nodes.update({id: node.id, label: node.label + positionToEmoji(2, false)})
setPlayerTouched(-1)
displayModalstep(2);
handleTurnBarTextChange("Mauvais choix, posez un carré !")
handleTurnBarTextChange(intl.formatMessage({ id: 'game.wrong' }))
const tabGrey = [7, 0, 4, 1, 8]
for (const id of tabGrey){
const node = nodes.get().find((n: NodePerson) => n.id === id)
@ -272,7 +276,7 @@ const TutorialGraph: React.FC<TutorialGraphProps> = ({showLast, setNetwork, setP
if (node4 === undefined)return;
nodes.update({id: node4.id, label: node4.label + positionToEmoji(2, false)})
setPlayerIndex(0)
handleTurnBarTextChange("A vous de jouer !")
handleTurnBarTextChange(intl.formatMessage({ id: 'game.yourTurn' }))
handleShowTurnBar(true)
setTutoStep(3)
displayModalstep(3);

@ -28,7 +28,7 @@ function ErrorPage({ code = "", msg = "Something is wrong"}) {
</div>
<div className='centerDivH' style={{margin: "20px"}}>
<Button href={`${basePath}/`} variant='danger'>Retour à l'accueil</Button>
<Button href={`${basePath}/`} variant='danger'><FormattedMessage id='BackHome'/></Button>
</div>
</div>
);

@ -19,7 +19,7 @@ import Stub from '../model/Stub';
import { useGame } from '../Contexts/GameContext';
import { positionToEmoji } from '../ColorHelper';
function DeducCheck() {
function DeducCheck({lang}: {lang: string}) {
const theme = useTheme();
//const indices = Stub.GenerateIndice();
@ -76,7 +76,7 @@ function DeducCheck() {
<tbody>
{firstHalfIndices.map((indice, rowIndex) => (
<tr key={rowIndex}>
<td>{indice.ToString("fr")}</td>
<td>{indice.ToString(lang)}</td>
{players.map((player, colIndex) => (
<td key={colIndex}>
{/* <input type="checkbox"/> */}
@ -101,7 +101,7 @@ function DeducCheck() {
<tbody>
{secondHalfIndices.map((indice, rowIndex) => (
<tr key={rowIndex}>
<td>{indice.ToString("fr")}</td>
<td>{indice.ToString(lang)}</td>
{players.map((player, colIndex) => (
<td key={colIndex}>
{/* <input type="checkbox"/> */}

@ -1,124 +1,90 @@
.head{
/* Styles for the Winner and Indice section */
.head {
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
}
.leaderboard-header{
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
width: fit-content;
border-radius: 0px 0px 30px 30px;
border: solid;
border-width: 0 5px;
}
.leaderboard-header {
border: 2px solid;
border-color: #0064E0;
padding: 20px;
}
.bottomEnd{
text-align: center;
border-radius: 0px 0px 10px 10px;
}
/* Styles for the Winner's details */
.winner-details {
display: flex;
justify-content: space-around;
}
.winner{
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
}
.playersContainer {
display: flex;
flex-direction: column;
align-items: center;
/* padding-left: "5px"; */
width: 100px;
background-color: red;
}
.playerContainer{
/* display: flex;
align-items: center; */
/* flex-direction: column; */
/* width: 300px; */
width: 30%;
margin-bottom: 20px;
/* margin-bottom: 10px; */
border: solid 1px whitesmoke;
border-radius: 15px;
background-color: white;
}
.losingPlayersContainer{
justify-content: center;
}
.winner-details img {
width: 75px;
height: 75px;
border-radius: 50%;
margin-right: 10px;
}
/* Styles for the Indice Display */
.indiceDisplay {
border: 2px solid whitesmoke;
border-radius: 10px;
margin: 5px; /* Réduire la marge */
padding: 8px; /* Réduire le rembourrage */
box-shadow: 3px 3px 3px rgb(246, 246, 246); /* Réduire l'ombre */
}
/* Styles for the Losing Players Container */
.losingPlayersContainer {
display: flex;
flex-wrap: wrap;
justify-content: space-evenly;
margin: 10px 0;
max-width: 50%;
overflow-y: scroll;
max-height: 200px;
/* background-color: yellow; */
}
.indiceDisplay{
border: solid 2px whitesmoke;
border-radius: 10px;
margin: 0 15px 0 15px;
padding: 10px;
box-shadow: 5px 5px 5px rgb(246, 246, 246);
}
.SoloContainer{
margin: 5px;
}
/* Styles for individual Player Containers */
.playerContainer {
display: flex;
flex-direction: column;
align-items: center;
border: solid 1px whitesmoke;
margin-top: 30px;
margin-bottom: 30px;
border: 1px solid whitesmoke;
border-radius: 15px;
background-color: white;
}
max-width: 50%;
}
.indicesolo{
.soloContainer {
display: flex;
flex-wrap: wrap;
justify-content: space-evenly;
/* margin: 10px 0; */
/* max-height: 200px; */
}
.solostat{
display: flex;
justify-content: space-between;
width: 70%;
}
.solostat p {
justify-content: center;
align-items: center;
width: 100%; /* Ajoutez cette ligne pour occuper toute la largeur */
}
.solostat{
border: solid 1px whitesmoke;
border-radius: 15px;
background-color: white;
padding: 10px;
}
margin: 5px;
width: fit-content; /* Ajoutez cette ligne pour ajuster la largeur au contenu */
}
.center {
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
}
#vis-graph {
/* Styles for the Graph Container */
#vis-graph {
height: 500px;
margin: 50px;
margin: 5px;
border: 2px solid #ccc;
overflow: hidden;
}
overflow: hidden;
}

@ -35,13 +35,13 @@ import Player from '../model/Player';
import { useGame } from '../Contexts/GameContext';
/* Boostrap */
import { Button } from 'react-bootstrap';
import { Button, Col, Container, Row } from 'react-bootstrap';
import Bot from '../model/Bot';
import {basePath} from "../AdressSetup"
function EndGame() {
function EndGame({lang}: {lang: string}) {
const {networkData, seed} = useGame();
const params = new URLSearchParams(window.location.search);
@ -147,77 +147,191 @@ function EndGame() {
}, 2000);
};
return (
<div>
<div style={{overflow:"hidden"}}>
{playTurnSound && <audio src={WinSound} autoPlay />}
{!IsSolo ? (
<div>
<div className="head">
<header className='leaderboard-header' style={{ borderColor: theme.colors.primary }}>
<h1>{winner?.pseudo} a gagné !</h1>
<h3>Le coupable était <u>{person?.getName()}</u></h3>
</header>
</div>
<div className='winner'>
<img src={Person} width='250' height='250'/>
{!indicenull && (<h3 className='indiceDisplay'>{indices[players.findIndex((p) => p.id == winner?.id)].ToString("fr")}</h3>)}
</div>
<div className='bottomEnd'>
{/* <div className='centerDivH' onClick={resetAll}>
<BigButtonNav dest="/play" img={Leave}/>
</div> */}
<div className="losingPlayersContainer">
{players.map((player, index) => (
player.id !== winner?.id && (
<div className="playerContainer" key={index}>
<PersonStatus img={Person} state={Person} key={index} name={player.pseudo} playerTouched={1} setPlayerTouched={() => {}} index={index} playerIndex={-2} showCircle={false} askedWrong={false}/>
{!indicenull && (<h6 className='indiceDisplay'>{indices[players.findIndex((p) => p.id == player?.id)].ToString("fr")}</h6>)}
</div>
)
))}
</div>
</div>
</div>
<Container>
{/* Winner et son indice */}
<Row>
<Col>
<div className="losingPlayersContainer">
{/* Indices pairs */}
{players.map((player, index) => (
index % 2 == 0 && (
<div className="playerContainer" key={index}>
<PersonStatus img={Person} state={Person} key={index} name={player.pseudo} playerTouched={1} setPlayerTouched={() => {}} index={index} playerIndex={-2} showCircle={false} askedWrong={false}/>
{!indicenull && (<h6 className='indiceDisplay'>{indices[players.findIndex((p) => p.id == player?.id)].ToString(lang)}</h6>)}
</div>
)
))}
</div>
</Col>
<Col xs={6}>
<Row>
<div className="head">
<header className='leaderboard-header' style={{ borderColor: theme.colors.primary }}>
<h4>{winner?.pseudo} a gagné !</h4>
<h5>Le coupable était <u>{person?.getName()}</u></h5>
</header>
</div>
</Row>
<Row>
<div id="vis-graph"></div>
</Row>
<Row className="justify-content-md-center">
<Button href={`${basePath}/`} style={{
width:"50%",
margin:"10px"
}}>Retour à l'accueil</Button>
</Row>
</Col>
<Col>
<div className="losingPlayersContainer">
{players.map((player, index) => (
index % 2 == 1 && (
<div className="playerContainer" key={index}>
<PersonStatus img={Person} state={Person} key={index} name={player.pseudo} playerTouched={1} setPlayerTouched={() => {}} index={index} playerIndex={-2} showCircle={false} askedWrong={false}/>
{!indicenull && (<h6 className='indiceDisplay'>{indices[players.findIndex((p) => p.id == player?.id)].ToString(lang)}</h6>)}
</div>
)
))}
</div>
</Col>
</Row>
</Container>
): (
<div>
<div className="head">
<header className='leaderboard-header' style={{ borderColor: theme.colors.primary }}>
<h1>Vous avez gagné !</h1>
<h3>Le coupable était <u>{person?.getName()}</u></h3>
</header>
</div>
<div className='winner'>
<img src={Person} width='250' height='250'/>
<h1>{winner?.pseudo}</h1>
</div>
<div className='bottomEnd'>
<div className="SoloContainer">
<div className='solostat'>
{!IsDaily && <p>Nombre de coups : {nbCoup}</p> }
<p>Temps : {temps}s</p>
</div>
<div className='indicesolo'>
{indices.map((indice, index) => (
// <div className="playerContainer" key={index}>
<div>
<h6 className='indiceDisplay'> <u>Indice {index+1}</u> : {indice.ToString("fr")}</h6>
</div>
//</div>
))
}
</div>
</div>
</div>
</div>
)}
<div id="vis-graph"/>
<Container fluid>
{/* Perd une énigme */}
{!winner && (
<Row>
<Col>
<Row>
<div className="head">
<header className='leaderboard-header' style={{ borderColor: theme.colors.primary }}>
<h4>Vous avez perdu !</h4>
<h5>Le coupable était <u>{person?.getName()}</u></h5>
</header>
</div>
<div className='centerDivH' onClick={resetAll} style={{margin: "20px"}}>
<Button href={`${basePath}/`}>Retour à l'accueil</Button>
</div>
<Row>
{!IsDaily &&
<Col className='center'>
<p className='solostat'>Nombre de coups : {nbCoup}</p>
</Col>
}
<Col className='center'>
<p className='solostat'>Temps : {temps}s</p>
</Col>
</Row>
</Row>
<Row>
<Col>
{indices.map((indice, index) => (
index % 2 == 0 && (
<div className='playerContainer'>
<h6 className='indiceDisplay'> <u>Indice {index+1}</u> : {indice.ToString("fr")}</h6>
</div>
)
))}
</Col>
<Col xs={6}>
<div id="vis-graph"></div>
</Col>
<Col>
<div className="losingPlayersContainer">
{indices.map((indice, index) => (
index % 2 == 1 && (
<div className='playerContainer'>
<h6 className='indiceDisplay'> <u>Indice {index+1}</u> : {indice.ToString("fr")}</h6>
</div>
)
))}
</div>
</Col>
</Row>
<Row className="justify-content-md-center">
<Button href={`${basePath}/`} style={{
width:"50%",
margin:"10px"
}}>Retour à l'accueil</Button>
</Row>
</Col>
</Row>
)}
{/* Gagne une énigme */}
{winner && (
<Row>
<Col>
<Row>
<div className="head">
<header className='leaderboard-header' style={{ borderColor: theme.colors.primary }}>
<h4>Vous avez gagné !</h4>
<h5>Le coupable était <u>{person?.getName()}</u></h5>
</header>
</div>
<Row>
{!IsDaily &&
<Col className='center'>
<p className='solostat'>Nombre de coups : {nbCoup}</p>
</Col>
}
<Col className='center'>
<p className='solostat'>Temps : {temps}s</p>
</Col>
</Row>
</Row>
<Row>
<Col>
{indices.map((indice, index) => (
index % 2 == 0 && (
<div className='playerContainer'>
<h6 className='indiceDisplay'> <u>Indice {index+1}</u> : {indice.ToString("fr")}</h6>
</div>
)
))}
</Col>
<Col xs={6}>
<div id="vis-graph"></div>
</Col>
<Col>
<div className="losingPlayersContainer">
{indices.map((indice, index) => (
index % 2 == 1 && (
<div className='playerContainer'>
<h6 className='indiceDisplay'> <u>Indice {index+1}</u> : {indice.ToString("fr")}</h6>
</div>
)
))}
</div>
</Col>
</Row>
<Row className='justify-content-center'>
<Button href={`${basePath}/`} style={{
width:"50%",
margin:"10px"
}}>Retour à l'accueil</Button>
</Row>
</Col>
</Row>
)}
</Container>
)}
</div>
);
}

@ -3,8 +3,6 @@
justify-content: space-between;
/* background-color: #D7D4C6; */
background-color: #fff;
min-height: 100vh;
display: flex;
font-size: calc(10px + 2vmin);
/* color: #2A4541; */
}

@ -40,77 +40,91 @@ function Home() {
}
}, [isLoggedIn]);
return (
<div className="home-container">
<div className="left-section">
<div>
{/* <h2><FormattedMessage id="home.histoire.title"/></h2> */}
<h2>Introduction</h2>
<p>
{/* <FormattedMessage id="home.histoire" /> */}
Bienvenue dans notre jeu de déduction captivant, où l'intrigue et la malice se rejoignent dans une aventure palpitante ! Plongez-vous dans un monde de mystère et d'intrigue, où chaque interaction compte, et chaque indice vous rapproche de la vérité.Imaginez un graphique complexe où chaque sommet représente une personne, chaque axe une relation, et chaque détail compte. Vous êtes plongé dans un défi stimulant pour découvrir qui parmi ces individus est le mystérieux coupable. Chaque joueur détient un indice crucial, et seul le partage stratégique de ces indices vous mènera à la résolution du mystère. Explorez notre page de règles pour comprendre les subtilités du jeu, découvrez les indices qui peuvent vous guider, et élaborez des stratégies intelligentes pour identifier le coupable. Manipuler vos amis, afin d'être le premier à découvrir qui est le meurtrier ! Êtes-vous prêt à relever le défi et à démasquer le coupable caché dans le graphe ? Que l'enquête commence !
</p>
</div>
<div>
<h2><FormattedMessage id="home.jeu.title"/></h2>
<p>
{/* <FormattedMessage id="home.jeu" /> */}
Dans l'univers captivant de notre jeu de déduction, la tromperie et la ruse sont les maîtres mots de la réussite. Explorez le mystère qui se dissimule derrière chaque interaction de notre graphique complexe, dévoilant les liens entre les individus.
return (
<div className="home-container" style={{overflow:"hidden"}}>
<div className="left-section">
<div>
{/* <h2><FormattedMessage id="home.histoire.title"/></h2> */}
<h2>Introduction</h2>
<p style={{fontSize:"14px"}}>
{/* <FormattedMessage id="home.histoire" /> */}
Bienvenue dans notre jeu de déduction captivant, où l'intrigue et la malice se rejoignent dans une aventure palpitante !
Plongez-vous dans un monde de mystère et d'intrigue, où chaque interaction compte, et chaque indice vous rapproche de la vérité.
Imaginez un graphique complexe où chaque sommet représente une personne, chaque axe une relation, et chaque détail compte.
Vous êtes plongé dans un défi stimulant pour découvrir qui parmi ces individus est le mystérieux coupable.
Chaque joueur détient un indice crucial, et seul le partage stratégique de ces indices vous mènera à la résolution du mystère.
Explorez notre page de règles pour comprendre les subtilités du jeu, découvrez les indices qui peuvent vous guider, et élaborez des stratégies intelligentes pour identifier le coupable.
Manipuler vos amis, afin d'être le premier à découvrir qui est le meurtrier !
Êtes-vous prêt à relever le défi et à démasquer le coupable caché dans le graphe ? Que l'enquête commence !
</p>
</div>
Votre mission ultime ? Découvrir qui parmi les individus est le coupable, mais n'attendez pas une collaboration ouverte. Utilisez plutôt la manipulation subtile pour embrouiller les pistes, détourner l'attention de vos adversaires. Posez des questions stratégiques, répondez avec malice et plantez des indices trompeurs pour vous rapprocher du dénouement.
<hr/>
Chaque occasion offre la possibilité de semer le doute parmi vos adversaires. Lorsqu'un joueur vous interroge, répondez en plaçant adroitement un jeton carré pour suggérer que "selon votre indice, cette personne ne peut être le coupable", ou un jeton rond pour indiquer qu'elle reste dans la liste des suspects. Soyez vigilant, chaque geste peut être interprété, et la vérité se dissimule souvent derrière une façade d'indices trompeurs.
<div>
<h2><FormattedMessage id="home.jeu.title"/></h2>
<p style={{fontSize:"14px"}}>
{/* <FormattedMessage id="home.jeu" /> */}
Dans l'univers captivant de notre jeu de déduction, la tromperie et la ruse sont les maîtres mots de la réussite. Explorez le mystère qui se dissimule derrière chaque interaction de notre graphique complexe, dévoilant les liens entre les individus.
</p>
Si un joueur place un jeton carré, le questionneur doit également jouer son jeu en plaçant un jeton carré de sa couleur sur un nœud du graphique. La contre-manipulation devient ainsi une arme redoutable pour détourner l'accusation et semer la confusion. Pour en savoir plus, plongez-vous dans les détails de ce passionnant récit sur une autre page.
</p>
<br/>
<p>Pour des informations plus détaillées, consulter les <Link to={`${basePath}/info`}>règles</Link>.</p>
<br/>
<p style={{fontSize:"14px"}}>
{/* <FormattedMessage id="home.jeu" /> */}
Votre mission ultime ? Découvrir qui parmi les individus est le coupable, mais n'attendez pas une collaboration ouverte. Utilisez plutôt la manipulation subtile pour embrouiller les pistes, détourner l'attention de vos adversaires. Posez des questions stratégiques, répondez avec malice et plantez des indices trompeurs pour vous rapprocher du dénouement.
</p>
<p style={{fontSize:"14px"}}>
{/* <FormattedMessage id="home.jeu" /> */}
Chaque occasion offre la possibilité de semer le doute parmi vos adversaires. Lorsqu'un joueur vous interroge, répondez en plaçant adroitement un jeton carré pour suggérer que "selon votre indice, cette personne ne peut être le coupable", ou un jeton rond pour indiquer qu'elle reste dans la liste des suspects. Soyez vigilant, chaque geste peut être interprété, et la vérité se dissimule souvent derrière une façade d'indices trompeurs.
</p>
<p style={{fontSize:"14px"}}>
{/* <FormattedMessage id="home.jeu" /> */}
Si un joueur place un jeton carré, le questionneur doit également jouer son jeu en plaçant un jeton carré de sa couleur sur un nœud du graphique. La contre-manipulation devient ainsi une arme redoutable pour détourner l'accusation et semer la confusion. Pour en savoir plus, plongez-vous dans les détails de ce passionnant récit sur une autre page.
</p>
<h5>Pour des informations plus détaillées, consulter les <Link to={`${basePath}/info`}>règles</Link>.</h5>
<hr/>
</div>
<div>
<h6>Jeu inspiré par le jeu de société "Cryptide"</h6>
</div>
</div>
<div>
{/* <h2><FormattedMessage id="home.plus.title"/></h2>
<ul>
<li><FormattedMessage id="home.plus.1"/></li>
<li><FormattedMessage id="home.plus.2"/></li>
<li><FormattedMessage id="home.plus.3"/></li>
</ul> */}
<h2>Présentation Video :</h2>
(ici il y aura la vidéo)
<div className="vertical-divider"></div>
<div className="right-section">
{/* <h3><FormattedMessage id="game.time"/></h3>
<h3><FormattedMessage id="game.players"/></h3>
<h3><FormattedMessage id="game.age"/></h3> */}
<h3>
Temps : 20 minutes<br/>
Joueurs : 1 à 6<br/>
Âge : 8ans et +<br/>
</h3>
<hr/>
<h3>
<u><FormattedMessage id="game.createdBy"/></u><br/>
Chazot Thomas<br/>
Ferreira Pierre<br/>
Marcel Baptiste<br/>
</h3>
{/* <h3> <u><FormattedMessage id="game.illustratedBy"/></u><br/> Kwanchai Moriya</h3> */}
{/* <button>Jouer au jeu</button> */}
<br/>
<Link to={`${basePath}/`} className='button'
style={{
backgroundColor: theme.colors.primary,
borderColor: theme.colors.secondary
}}>
<FormattedMessage id="play"/>
</Link>
</div>
</div>
<div className="vertical-divider"></div>
<div className="right-section">
{/* <h3><FormattedMessage id="game.time"/></h3>
<h3><FormattedMessage id="game.players"/></h3>
<h3><FormattedMessage id="game.age"/></h3> */}
<h3>
Temps : 20 minutes<br/>
Joueurs : 1 à 6<br/>
Âge : 8ans et +<br/>
</h3>
<hr/>
<h3> <u><FormattedMessage id="game.createdBy"/></u><br/>
Chazot Thomas<br/>
Ferreira Pierre<br/>
Marcel Baptiste<br/>
</h3>
{/* <h3> <u><FormattedMessage id="game.illustratedBy"/></u><br/> Kwanchai Moriya</h3> */}
{/* <button>Jouer au jeu</button> */}
<br/>
<Link to={`${basePath}/`} className='button'
style={{
backgroundColor: theme.colors.primary,
borderColor: theme.colors.secondary
}}>
<FormattedMessage id="play"/>
</Link>
</div>
</div>
);
}

@ -14,14 +14,12 @@ import PlayerList from '../Components/PlayerList';
import TurnBar from '../Components/TurnBar';
/* Icon */
import Leave from "../res/icon/leave.png";
import Param from "../res/icon/param.png";
import Replay from "../res/icon/replay.png";
import Info from "../res/icon/infoGreen.png";
import Check from "../res/icon/checkboxGreen.png";
import Alpha from "../res/GreekLetters/alphaW.png";
import MGlass from "../res/icon/magnifying-glass.png";
import Download from "../res/icon/download.png"
import Pdf from "../res/icon/pdf.png"
import Tex from "../res/icon/tex.png"
import Reset from "../res/icon/reset.png";
import Oeye from "../res/icon/eye.png";
import Ceye from "../res/icon/hidden.png";
@ -55,6 +53,13 @@ import {generateLatexCode, generateLatexCodeEnigme} from '../Script/LatexScript'
import Pair from '../model/Pair';
import Indice from '../model/Indices/Indice';
import {basePath} from "../AdressSetup"
import { useAuth } from '../Contexts/AuthContext';
import ballonDeBasket from '../Script/ballon-de-basket.png';
import ballonDeFoot from '../Script/ballon-de-foot.png';
import baseball from '../Script/baseball.png';
import bowling from '../Script/bowling.png';
import tennis from '../Script/tennis.png';
let cptNavigation = 0
@ -65,6 +70,7 @@ const InGame = ({locale, changeLocale}) => {
const theme = useTheme();
const navigate = useNavigate()
const {user, manager} = useAuth()
const params = new URLSearchParams(window.location.search);
@ -104,6 +110,7 @@ const InGame = ({locale, changeLocale}) => {
const [askedWrong, setAskedWrong] = useState(false)
const [importToPdf, setImportToPdf] = useState(false)
const [importToJSON, setImportToJSON] = useState(false)
const [firstHistory, setFirstHistory] = useState(true)
const [putCorrectBackground, setPutCorrectBackground] = useState<() => void>(() => {});
const [putGreyBackgroud, setPutGreyBackground] = useState<() => void>(() => {});
@ -204,7 +211,7 @@ const InGame = ({locale, changeLocale}) => {
const zip = new JSZip();
if (isDaily && networkEnigme != null){
if (isDaily && (difficulty === "hard" || difficulty === "intermediate") && networkEnigme != null){
const tex = generateLatexCodeEnigme(personNetwork, person, indices, network, networkEnigme)
const blob = new Blob([tex], { type: 'application/x-latex;charset=utf-8' });
zip.file('socialGraph.tex', tex);
@ -216,17 +223,25 @@ const InGame = ({locale, changeLocale}) => {
}
const imageNames = ['ballon-de-basket.png', 'ballon-de-foot.png', "baseball.png", "bowling.png", "tennis.png"]; // Liste des noms de fichiers d'images
const imagesFolder = 'Script';
const imageNames2 = [ballonDeBasket, ballonDeFoot, baseball, bowling, tennis];
for (const imageName of imageNames) {
const imageUrl = process.env.PUBLIC_URL + `/${imagesFolder}/${imageName}`;
const imagesFolder = 'Script';
let test = 0
for (const image of imageNames2) {
/*
const imageUrl = `localhost/${imagesFolder}/${imageName}`;
console.log(imageUrl)
const response = await fetch(imageUrl);
*/
const response = await fetch(image);
if (response.ok) {
const imageBlob = await response.blob();
zip.file(`${imageName}`, imageBlob);
zip.file(imageNames[test], imageBlob);
test++
} else {
console.error(`Erreur de chargement de l'image ${imageName}`);
// console.error(`Erreur de chargement de l'image ${imageName}`);
}
}
@ -324,20 +339,76 @@ const InGame = ({locale, changeLocale}) => {
const [playTurnSound, setPlayTurnSound] = useState(false);
const [soundPreference, setSoundPreference] = useState(true); // utilisateur
const [enteredNumber, setEnteredNumber] = useState(25);
const [enteredNumberIndices, setEnteredNumberIndices] = useState(3);
const [enteredNumber, setEnteredNumber] = useState(user?.nbNodes || 25);
const [enteredNumberIndices, setEnteredNumberIndices] = useState(user?.nbIndices || 3);
//@ts-ignore
const handleNumberChange = (event) => {
if (parseInt(event.target.value)){
setEnteredNumber(parseInt(event.target.value));
}
};
//@ts-ignore
const handleKeyDown = (event) => {
// Vérifier si la touche appuyée est "Entrée"
if (event.key === 'Enter' && user!==null && parseInt(event.target.value)) {
const newNumber = Math.max(20, Math.min(50, parseInt(event.target.value, 10)));
user.nbNodes = newNumber;
setEnteredNumber(newNumber);
}
};
const handleBlur = () => {
if (user!==null){
const newNumber = Math.max(20, Math.min(50, enteredNumber));
user.nbNodes = newNumber;
setEnteredNumber(newNumber);
}
};
//@ts-ignore
const handleNumberIndicesChange = (event) => {
if (parseInt(event.target.value)){
setEnteredNumberIndices(parseInt(event.target.value));
}
};
useEffect(() => {
if (changeGraph){
if (enteredNumber>=20 && enteredNumber<=50 && enteredNumberIndices>=3 && enteredNumberIndices<=6){
console.log(enteredNumber)
console.log(enteredNumberIndices)
manager?.userService.changeNodesIndices(enteredNumber, enteredNumberIndices)
setHistory([]);
setFirstHistory(true)
changeGraph(enteredNumber, enteredNumberIndices)
}
}
else{
setEnteredNumber(user?.nbNodes || 25)
setEnteredNumberIndices(user?.nbIndices || 3)
}
}, [enteredNumber, enteredNumberIndices])
//@ts-ignore
const handleKeyDownIndice = (event) => {
// Vérifier si la touche appuyée est "Entrée"
if (event.key === 'Enter' && user!=null && parseInt(event.target.value)) {
const newNumber = Math.max(3, Math.min(6, parseInt(event.target.value, 10)));
user.nbIndices = newNumber;
setEnteredNumberIndices(newNumber);
}
};
const handleBlurIndice = () => {
if (user!==null){
const newNumber = Math.max(3, Math.min(6, enteredNumberIndices));
setEnteredNumberIndices(newNumber);
user.nbIndices = newNumber;
}
};
const handleSoundPreferenceChange = () => {
@ -389,6 +460,7 @@ const InGame = ({locale, changeLocale}) => {
putGreyBackground={putGreyBackgroud}
putImposssibleGrey={putImposssibleGrey}
handleTurn={handleTurn}
lang={locale}
setChangeGraph={setChangeGraphData}/>
</div>
{playTurnSound && <audio src={turnSound} autoPlay />}
@ -399,7 +471,7 @@ const InGame = ({locale, changeLocale}) => {
backgroundColor: theme.colors.primary,
borderColor: theme.colors.secondary
}}>
Tour : {cptTour}
<FormattedMessage id='turn'/> : {cptTour}
</div>
}
@ -499,7 +571,7 @@ const InGame = ({locale, changeLocale}) => {
backgroundColor: theme.colors.tertiary,
borderColor: theme.colors.secondary
}}>
<img src={Download} alt="indice" height="40"/>
<img src={Tex} alt="indice" height="40"/>
</button>
}
@ -509,7 +581,7 @@ const InGame = ({locale, changeLocale}) => {
backgroundColor: theme.colors.tertiary,
borderColor: theme.colors.secondary
}}>
<img src={Download} alt="indice" height="40"/>
<img src={Pdf} alt="indice" height="40"/>
</button>
}
</div>
@ -527,7 +599,7 @@ const InGame = ({locale, changeLocale}) => {
backdrop={false}
style={{ height: '20%', width: '25%', top: '60vh' }}>
<Offcanvas.Header closeButton>
<Offcanvas.Title>Indice</Offcanvas.Title>
<Offcanvas.Title><FormattedMessage id='indice'/></Offcanvas.Title>
</Offcanvas.Header>
<Offcanvas.Body>
{indice?.ToString(locale)}
@ -540,66 +612,59 @@ const InGame = ({locale, changeLocale}) => {
<Offcanvas show={showS}
onHide={handleCloseS}
placement='top'
style={{height: '60%', width: '30%', left: '70%' }}>
style={{height: '80%', width: '30%', left: '70%' }}>
<Offcanvas.Header closeButton>
<Offcanvas.Title><img src={Param} alt='param'/> Paramètres</Offcanvas.Title>
<Offcanvas.Title><img src={Param} alt='param'/> <FormattedMessage id='param'/></Offcanvas.Title>
</Offcanvas.Header>
<Offcanvas.Body >
<div style={{display: "flex", justifyContent: "center", flexDirection: "column", alignItems: "center"}}>
<label style={{ display:'flex'}}>
<Switch checked={soundPreference} onChange={handleSoundPreferenceChange}/>
<p style={{ marginLeft:'20px'}}>Activer les SFX</p>
<p style={{ marginLeft:'20px'}}><FormattedMessage id='sfx'/></p>
</label>
{IsSolo &&
<div className='nbNodeDiv'>
<label htmlFor="numberInput">Sélectionner le nombre de noeuds (entre 20 et 50) :</label>
<div className='nbNodeDiv' style={{ padding:'20px'}}>
<label htmlFor="numberInput"><FormattedMessage id='param.node'/> :</label>
<div>
<button className='valuebutton' onClick={() => { if (enteredNumber>20) setEnteredNumber(enteredNumber-1)}}
<button className='valuebutton' onClick={() => { if (enteredNumber>20 && user !== null){ setEnteredNumber(enteredNumber-1); user.nbNodes = user.nbNodes-1; setHistory([]); }}}
style={{borderColor:theme.colors.secondary}}> - </button>
<input
// type="number"
style={{textAlign:'center'}}
style={{textAlign:'center', border: 'none', width: '100px'}}
id="numberInput"
disabled
value={enteredNumber}
onChange={handleNumberChange}
min={20}
max={60}/>
<button className='valuebutton' onClick={() => { if (enteredNumber<50) setEnteredNumber(enteredNumber+1)}}
onKeyDown={handleKeyDown} // Ajout de l'événement onKeyDown
onBlur={handleBlur} // Ajout de l'événement onBlur
/>
<button className='valuebutton' onClick={() => { if (enteredNumber<50 && user!==null){ setEnteredNumber(enteredNumber+1); user.nbNodes = user.nbNodes+1 ;setHistory([]); }}}
style={{borderColor:theme.colors.secondary}}> + </button>
</div>
<button onClick={() => {setHistory([]); changeGraph(enteredNumber, enteredNumberIndices)}}
style={{
backgroundColor: theme.colors.tertiary,
borderColor: theme.colors.secondary,
}}>Valider</button>
</div>}
{IsSolo &&
<div className='nbNodeDiv'>
<label htmlFor="numberInput">Sélectionner le nombre d'indices (entre 3 et 6) :</label>
<div className='nbNodeDiv' style={{ padding:'20px'}}>
<label htmlFor="numberInput"><FormattedMessage id='param.clue'/> :</label>
<div>
<button className='valuebutton' onClick={() => { if (enteredNumberIndices>3) setEnteredNumberIndices(enteredNumberIndices-1)}}
<button className='valuebutton' onClick={() => { if (enteredNumberIndices>3 && user!==null){ setEnteredNumberIndices(enteredNumberIndices - 1); user.nbIndices = user.nbIndices-1; setHistory([]); }}}
style={{borderColor:theme.colors.secondary}}> - </button>
<input
// type="number"
style={{textAlign:'center'}}
style={{textAlign:'center', border: 'none', width: '100px'}}
id="numberInput"
disabled
value={enteredNumberIndices}
onChange={handleNumberIndicesChange}
min={3}
max={6}/>
<button className='valuebutton' onClick={() => { if (enteredNumberIndices<6) setEnteredNumberIndices(enteredNumberIndices+1)}}
onKeyDown={handleKeyDownIndice} // Ajout de l'événement onKeyDown
onBlur={handleBlurIndice}/>
<button className='valuebutton' onClick={() => { if (enteredNumberIndices<6 && user!==null){ setEnteredNumberIndices(enteredNumberIndices + 1); user.nbIndices = user.nbIndices+1; setHistory([]); }}}
style={{borderColor:theme.colors.secondary}}> + </button>
</div>
<button onClick={() => {setHistory([]); changeGraph(enteredNumber, enteredNumberIndices)}}
style={{
backgroundColor: theme.colors.tertiary,
borderColor: theme.colors.secondary,
}}>Valider</button>
</div>}
<div className='centerDivH' style={{margin: "20px"}}>
<Button variant="outline-warning" onClick={() => {setHistory([]); changeGraph(enteredNumber, enteredNumberIndices)}}><FormattedMessage id='regenerate'/></Button>
</div>
<Button variant="outline-danger" href={`${basePath}/`}><FormattedMessage id='BackHome'/></Button>
</div>
</Offcanvas.Body>
</Offcanvas>

@ -1,5 +1,6 @@
import React, { useEffect, useState } from 'react';
/* Style */
import './Lobbies.css';
import "../Style/Global.css"
@ -11,7 +12,7 @@ import { socket } from '../SocketConfig';
import JSONParser from '../JSONParser';
import Person from '../model/Person';
import { useNavigationType } from 'react-router-dom';
import { FormattedMessage, useIntl } from 'react-intl';
class LobbyDataProps {
roomNum : string
@ -41,6 +42,7 @@ function Lobbies() {
const [showAvailable, setShowAvailable] = useState(true);
const handleShowAllClick = () => {
setShowAvailable(false);
};
@ -49,7 +51,18 @@ function Lobbies() {
setShowAvailable(true);
};
const handleSetFirst = () => {
setFirst(false);
socket.emit("request lobbies");
};
const handleSetCptNavigation = () => {
cptNavigation++
if (cptNavigation % 2 >= 0 && navigationType.toString() === "POP") {
socket.emit("player quit");
}
};
const filteredLobbies = lobbyData.filter((lobby) =>
lobby.roomNum.toLowerCase().includes(searchTerm.toLowerCase()) ||
lobby.headPlayer.pseudo.toLowerCase().includes(searchTerm.toLowerCase())
@ -58,26 +71,25 @@ function Lobbies() {
const filteredLobbiesToShow = showAvailable
? filteredLobbies.filter((lobby) => lobby.started == false && lobby.nbPlayer < 6) //* retire les lobbies pleins ou commencés
: filteredLobbies;
const setFirstData = (first: boolean) => {
setFirst(first)
}
const navigationType = useNavigationType()
cptNavigation++
if (cptNavigation % 2 == 0){
if (navigationType.toString() == "POP"){
socket.emit("player quit")
}
}
const navigationType = useNavigationType();
handleSetCptNavigation();
if (first){
setFirst(false)
socket.emit("request lobbies")
handleSetFirst();
}
useEffect(() => {
socket.on("request lobbies", (map) => {
const jsonMap = JSON.parse(map)
@ -95,12 +107,16 @@ function Lobbies() {
socket.emit("lobby created")
}
const intl = useIntl();
return(
<div style={{display:'flex', flexDirection:'column', alignItems:'center'}}>
<input
type="text"
className='searchLobby'
placeholder="Rechercher un lobby..."
placeholder={intl.formatMessage({ id: 'placeholder.searchLobby' })}
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
style={{width:'80%', margin:'10px'}}
@ -119,7 +135,7 @@ function Lobbies() {
}}
onClick={handleShowAllClick}
>
Tous
<FormattedMessage id='lobbies.all'/>
</button>
<button
style={{
@ -132,12 +148,12 @@ function Lobbies() {
}}
onClick={handleShowAvailableClick}
>
Disponible
<FormattedMessage id='lobbies.dispo'/>
</button>
</div>
{filteredLobbiesToShow.length === 0 ? (
<button onClick={createLobby} className='ButtonNav' style={{backgroundColor: theme.colors.primary, borderColor: theme.colors.secondary}}>Créer une partie</button>
<button onClick={createLobby} className='ButtonNav' style={{backgroundColor: theme.colors.primary, borderColor: theme.colors.secondary}}><FormattedMessage id='play.create' /></button>
) : (
<div className="lobbyList">
{filteredLobbiesToShow.map((lobby, index) => (

@ -48,6 +48,7 @@ import Overlay from 'react-bootstrap/Overlay';
import { DataSet } from 'vis-network';
import {basePath} from "../AdressSetup"
import { FormattedMessage } from 'react-intl';
let gameStarted = false
@ -193,17 +194,14 @@ function Lobby() {
});
socket.on("room full", () => {
//TODO POP UP pour quand la room est pleine
navigate(`${basePath}/`)
})
socket.on("game started", () => {
//TODO POP UP pour quand la room est pleine
navigate(`${basePath}/`)
})
socket.on("game already started", () => {
//TODO POP UP pour quand la room est pleine
navigate(`${basePath}/`)
})
@ -277,9 +275,9 @@ function Lobby() {
</div>
<div className='NumbDiv'>
{players.length == 6 ? (
<p style={{color:'darkred'}}>6/6 Players</p>
<p style={{color:'darkred'}}>6/6 <FormattedMessage id='lobby.players'/></p>
) : (
<p>{players.length}/6 Players</p>
<p>{players.length}/6 <FormattedMessage id='lobby.players'/></p>
)
}
</div>
@ -308,12 +306,12 @@ function Lobby() {
<div className='lobbyR'
style={{flexDirection:'column',
alignItems:'space-around'}}>
<h3>Bienvenue dans votre lobby !</h3>
<p>Attendez que tous vos amis rejoignent avant de lancer la partie.</p>
<h3><FormattedMessage id='lobby.bienvenue'/></h3>
<p><FormattedMessage id='lobby.wait'/></p>
{/* Bouton pour copier le lien */}
<Button variant="primary" ref={target} onClick={copyGameLink}>
Inviter des amis
</Button>
{/* <Button variant="primary" ref={target} onClick={copyGameLink}>
<FormattedMessage id='lobby.invite'/>
</Button> */}
<Overlay target={target.current} show={show} placement="top">
{({
placement: _placement,
@ -334,13 +332,13 @@ function Lobby() {
...props.style,
}}
>
Lien copié
<FormattedMessage id='lobby.copyLink'/>
</div>
)}
</Overlay>
<div className='nbNodeDiv'>
<label htmlFor="numberInput">Sélectionner le nombre de noeud (entre 20 et 60) :</label>
<label htmlFor="numberInput"> <FormattedMessage id='lobby.nbNode'/> :</label>
<div>
<button className='valuebutton' onClick={() => { if (enteredNumber>20) setEnteredNumber(enteredNumber-1)}}
style={{borderColor:theme.colors.secondary}}> - </button>
@ -366,7 +364,7 @@ function Lobby() {
width: 'auto',
height: 'auto'
}}>
Démarrer la partie !
<FormattedMessage id='lobby.start'/>
</button>
</div>
</div>

@ -31,6 +31,7 @@ import Button from 'react-bootstrap/Button';
import ButtonGroup from 'react-bootstrap/ButtonGroup';
import Lobbies from './Lobbies';
import {basePath} from "../AdressSetup"
import { FormattedMessage } from 'react-intl';
@ -95,7 +96,7 @@ function NewPlay() {
}
function launchMastermind(){
const [networkPerson, choosenPerson, choosenIndices] = GameCreator.CreateGame(3, 30)
const [networkPerson, choosenPerson, choosenIndices] = GameCreator.CreateGame(user?.nbIndices || 3, user?.nbNodes || 25)
setPersonData(choosenPerson)
setPersonNetworkData(networkPerson)
setIndicesData(choosenIndices)
@ -158,7 +159,7 @@ function NewPlay() {
//* Mode facile
//todo différencier les deux
const [networkPerson, choosenPerson, choosenIndices] = GameCreator.CreateGame(3, 30)
const [networkPerson, choosenPerson, choosenIndices] = GameCreator.CreateGame(user?.nbIndices || 3, user?.nbNodes || 25)
setPersonData(choosenPerson)
setPersonNetworkData(networkPerson)
setIndicesData(choosenIndices)
@ -172,7 +173,7 @@ function NewPlay() {
//* Mode facile
//todo différencier les deux
const [networkPerson, choosenPerson, choosenIndices] = GameCreator.CreateGame(3, 30)
const [networkPerson, choosenPerson, choosenIndices] = GameCreator.CreateGame(user?.nbIndices || 3, user?.nbNodes || 25)
setPersonData(choosenPerson)
setPersonNetworkData(networkPerson)
setIndicesData(choosenIndices)
@ -192,7 +193,7 @@ function NewPlay() {
//* Mode difficile
//todo différencier les deux
const [networkPerson, choosenPerson, choosenIndices] = GameCreator.CreateGame(3, 30)
const [networkPerson, choosenPerson, choosenIndices] = GameCreator.CreateGame(user?.nbIndices || 3, user?.nbNodes || 25)
setPersonData(choosenPerson)
setPersonNetworkData(networkPerson)
setIndicesData(choosenIndices)
@ -225,8 +226,8 @@ function NewPlay() {
<div className="leftContainer">
{/* Boutons pour jouer */}
<div className='NewbuttonGroupVertical'>
<button onClick={launchMastermind} className="ButtonNav" style={{backgroundColor: theme.colors.primary, borderColor: theme.colors.secondary}}> Jouer seul </button>
<button ref={target} onClick={launchEngimeJour} className="ButtonNav" style={{backgroundColor: theme.colors.primary, borderColor: theme.colors.secondary}}> Résoudre une énigme</button>
<button onClick={launchMastermind} className="ButtonNav" style={{backgroundColor: theme.colors.primary, borderColor: theme.colors.secondary}}> <FormattedMessage id="play.jouerseul"/> </button>
<button ref={target} onClick={launchEngimeJour} className="ButtonNav" style={{backgroundColor: theme.colors.primary, borderColor: theme.colors.secondary}}> <FormattedMessage id="play.enigme"/> </button>
<Overlay show={showOverlay} target={target.current} placement="bottom" rootClose={true} rootCloseEvent='click' onHide={() => setShowOverlay(false)}>
{({ placement, arrowProps, show: _show, popper, ...props }) => (
<div
@ -239,24 +240,22 @@ function NewPlay() {
}}>
<ButtonGroup aria-label="difficulty">
<Button onClick={handleStartEasyGame}>Facile</Button>
<Button onClick={handleStartMediumGame}>Intermédiaire</Button>
<Button onClick={handleStartHardGame}>Difficile</Button>
<Button onClick={handleStartEasyGame}><FormattedMessage id='play.enigme.easy'/></Button>
<Button onClick={handleStartMediumGame}><FormattedMessage id='play.enigme.medium'/></Button>
<Button onClick={handleStartHardGame}><FormattedMessage id='play.enigme.hard'/></Button>
</ButtonGroup>
</div>
)}
</Overlay>
<button onClick={createLobby} className="ButtonNav" style={{backgroundColor: theme.colors.primary, borderColor: theme.colors.secondary}}> Créer une partie </button>
<button onClick={launchTuto} className="ButtonNav" style={{backgroundColor: theme.colors.primary, borderColor: theme.colors.secondary}}> Tutoriel </button>
{/* <button onClick= {() => navigate("/join")} className="ButtonNav" style={{backgroundColor: theme.colors.primary, borderColor: theme.colors.secondary}}> Rejoindre </button> */}
{/* {goBackRoom != -1 && <button onClick={goBack} className="ButtonNav" style={{backgroundColor: theme.colors.primary, borderColor: theme.colors.secondary}}>Retourner à la partie</button>} */}
<button onClick={goBack} className="ButtonNavRejoin" style={{ display:returnVisibility}}>Retourner à la partie</button>
<button onClick={createLobby} className="ButtonNav" style={{backgroundColor: theme.colors.primary, borderColor: theme.colors.secondary}}> <FormattedMessage id='play.create'/> </button>
<button onClick={launchTuto} className="ButtonNav" style={{backgroundColor: theme.colors.primary, borderColor: theme.colors.secondary}}> <FormattedMessage id='play.tuto'/> </button>
<button onClick={goBack} className="ButtonNavRejoin" style={{ display:returnVisibility}}><FormattedMessage id='play.return'/> </button>
</div>
{/* Lobbies */}
<div style={{border:'solid 1px lightgray', borderRadius:'15px', marginTop:'20px'}}>
<div style={{border:'solid 1px lightgray', borderRadius:'15px', marginTop:'20px', minHeight:'400px'}}>
<Lobbies/>
</div>
</div>

@ -56,6 +56,7 @@ import TutorialGraph from '../Components/TutorialGraph';
import { useAuth } from '../Contexts/AuthContext';
import EasyBot from '../model/EasyBot';
import { set } from 'lodash';
import { FormattedMessage } from 'react-intl';
let cptNavigation = 0
@ -362,7 +363,7 @@ const Tutorial = ({locale, changeLocale}) => {
</Button> */}
<Button variant="primary" onClick={handleShowHelp}>
Aide
<FormattedMessage id='aide'/>
</Button>
<Link to={`${basePath}/info`} target='_blank'>
<button className='button'
@ -404,7 +405,7 @@ const Tutorial = ({locale, changeLocale}) => {
backdrop={false}
style={{ height: '20%', width: '25%', top: '60vh' }}>
<Offcanvas.Header closeButton>
<Offcanvas.Title>Indice</Offcanvas.Title>
<Offcanvas.Title><FormattedMessage id='indice'/></Offcanvas.Title>
</Offcanvas.Header>
<Offcanvas.Body>
{indice?.ToString(locale)}
@ -421,7 +422,7 @@ const Tutorial = ({locale, changeLocale}) => {
size="lg"
style={{ maxHeight: '100vh'}}>
<Modal.Header>
<Modal.Title>Tutoriel</Modal.Title>
<Modal.Title><FormattedMessage id='tutorial.title'/></Modal.Title>
</Modal.Header>
<Modal.Body style={{ display:'flex', justifyContent:'center', alignItems:'center', flexDirection:'column'}}>
@ -429,14 +430,14 @@ const Tutorial = ({locale, changeLocale}) => {
<Card style={{ width: '90%', display:'flex', justifyContent:'center', alignItems:'center', flexDirection:'column'}}>
<Card.Img variant="top" src={detective} style={{width:'300px', height:'300px'}}/>
<Card.Body>
<Card.Title> Bienvenue dans SocialGraph</Card.Title>
<Card.Title> <FormattedMessage id='tuto.title.1'/> </Card.Title>
<Card.Text>
Vous incarnez un détective assoiffé de gloire, confronté à un crime. <br/>
Cependant, d'autres enquêteurs sont également sur le coup, tous cherchant à décrocher le titre de meilleur détective du monde. <br/>
Chacun possède un indice crucial pour identifier le coupable, il va falloir déduire l'indice de vos concurrents si vous souhaitez l'emporter ! <br/>
Interrogez vos concurrents pour obtenir des réponses par oui ou non, mais méfiez-vous, un refus a des conséquences. <br/>
Soyez le premier à déduire les indices des autres et à trouver le coupable pour remporter la reconnaissance tant convoitée. <br />
<i>Si vous avez le moindre doute, cliquer sur le bouton "aide" pour afficher l'étape actuel du tuto</i>
<FormattedMessage id='tuto.txt.1.1'/> <br/>
<FormattedMessage id='tuto.txt.1.2'/> <br/>
<FormattedMessage id='tuto.txt.1.3'/> <br/>
<FormattedMessage id='tuto.txt.1.4'/> <br/>
<FormattedMessage id='tuto.txt.1.5'/> <br/>
<i><FormattedMessage id='tuto.txt.1.6'/></i>
</Card.Text>
</Card.Body>
</Card>
@ -445,11 +446,11 @@ const Tutorial = ({locale, changeLocale}) => {
<Card style={{ width: '90%', display:'flex', justifyContent:'center', alignItems:'center', flexDirection:'column'}}>
<Card.Img variant="top" src={ava} style={{width:'300px', height:'300px'}}/>
<Card.Body>
<Card.Title>Les Suspects</Card.Title>
<Card.Title> <FormattedMessage id='tuto.title.2'/> </Card.Title>
<Card.Text>
Voici comment est représenté un suspect, chaque suspect possède différentes caractéristiques, que ce soit leur nom, âge, sport et leur couleur de cheveux.
<FormattedMessage id='tuto.txt.2.1'/>
<br />
Par exemple, ici, nous avons <b>Ava</b>, qui a <b>40 ans</b>, qui pratique du <b>Basket</b> et du <b>Tennis</b>, qui a les cheveux <b>Roux</b> et qui possède <b>2 amis</b> : Carter et Liam.
<FormattedMessage id='tuto.txt.2.2' /><b>Ava</b><FormattedMessage id='tuto.txt.2.2.1'/><b>40 <FormattedMessage id='age_indice_end'/></b><FormattedMessage id='tuto.txt.2.2.2'/><b><FormattedMessage id='basketball'/></b><FormattedMessage id='tuto.txt.2.2.3'/><b><FormattedMessage id='tennis'/></b><FormattedMessage id='tuto.txt.2.2.4'/><b><FormattedMessage id='redhead'/></b><FormattedMessage id='tuto.txt.2.2.5'/><b>2 <FormattedMessage id='nb_friends_indice_end'/></b> : Carter <FormattedMessage id='and'/> Liam.
</Card.Text>
</Card.Body>
</Card>
@ -459,11 +460,11 @@ const Tutorial = ({locale, changeLocale}) => {
<Card style={{ width: '90%', display:'flex', justifyContent:'center', alignItems:'center', flexDirection:'column'}}>
<Card.Img variant="top" src={indicetxt} style={{width:'300px', height:'auto'}}/>
<Card.Body>
<Card.Title>Les indices</Card.Title>
<Card.Title><FormattedMessage id='tuto.title.3'/></Card.Title>
<Card.Text>
Dans ce jeu, chaque détective possède un indice, qui permet d'identifier une caractéristique du coupable, votre indice est le suivant :
<FormattedMessage id='tuto.txt.3.1'/>
<br />
"<u>Le suspect a entre 20 et 29 ans</u>".
"<u><FormattedMessage id='tuto.txt.3.2'/></u>".
</Card.Text>
</Card.Body>
</Card>
@ -473,11 +474,11 @@ const Tutorial = ({locale, changeLocale}) => {
<Card style={{ width: '90%', display:'flex', justifyContent:'center', alignItems:'center', flexDirection:'column'}}>
<Card.Img variant="top" src={joueurs} style={{width:'auto', height:'300px'}}/>
<Card.Body>
<Card.Title>Les Détectives</Card.Title>
<Card.Title><FormattedMessage id='tuto.title.4'/></Card.Title>
<Card.Text>
Il est possible de voir les détectives sur le côté gauche de l'écran, ils sont représentés par des cercles de couleurs différentes. Le contour carré signifie que ce détective est en pleine réflexion.
<FormattedMessage id='tuto.txt.4.1'/>
<br />
Pour interroger un détective à propos d'un suspect, il suffit de le sélectionner, puis de cliquer sur le suspect que vous souhaitez. Il vous répondra donc ce qu'il pense de ce suspect selon son indice.
<FormattedMessage id='tuto.txt.4.2'/>
</Card.Text>
</Card.Body>
</Card>
@ -487,22 +488,22 @@ const Tutorial = ({locale, changeLocale}) => {
<Card style={{ width: '90%', display:'flex', justifyContent:'center', alignItems:'center', flexDirection:'column'}}>
<Card.Img variant="top" src={rep} style={{width:'300px', height:'300px'}}/>
<Card.Body>
<Card.Title>Les réponses</Card.Title>
<Card.Title><FormattedMessage id='tuto.title.5'/></Card.Title>
<Card.Text>
Les détéctives vous répondrons que par des ronds ou des carrés de leur couleur.
<FormattedMessage id='tuto.txt.5.1'/>
<br />
<ul>
<li>
Un <u>carré</u> signifie que son indice innocente le suspect.
<FormattedMessage id='majUn'/> <u><FormattedMessage id='square'/></u> <FormattedMessage id='tuto.txt.5.2'/>.
</li>
<li>
Un <u>rond</u> signifie que son indice peut incréminer le suspect.
<FormattedMessage id='majUn'/> <u><FormattedMessage id='round'/></u> <FormattedMessage id='tuto.txt.5.3'/>.
</li>
</ul>
Par exemple, ici :<br />
l'indice du détéctive Scooby-Doo (<u>Vert</u>) permet d'innocenter Logan.
<br/>Eleanor peut être suspectée par l'indice du détective Batman (<u>Jaune</u>).
<br/>Evelyn est innocentée par l'indice de <u>3 détéctive différents</u>.
<FormattedMessage id='tuto.txt.5.4'/><br />
<FormattedMessage id='tuto.txt.5.5.1'/>(<u><FormattedMessage id='color.green'/></u>) <FormattedMessage id='tuto.txt.5.5.2'/>.
<br/><FormattedMessage id='tuto.txt.5.6'/> (<u><FormattedMessage id='color.yellow'/></u>).
<br/><FormattedMessage id='tuto.txt.5.7.1'/><u><FormattedMessage id='tuto.txt.5.7.2'/></u>.
</Card.Text>
</Card.Body>
</Card>
@ -520,9 +521,9 @@ const Tutorial = ({locale, changeLocale}) => {
</button>
</Card.Header>
<Card.Body>
<Card.Title>Les règles du jeu</Card.Title>
<Card.Title><FormattedMessage id='tuto.title.6'/></Card.Title>
<Card.Text>
Ce bouton vous mène à la page d'<b>information du jeu</b>, avec toutes les règles du jeu, que ce soit les objectifs, les indices, le déroulement, etc.
<FormattedMessage id='tuto.txt.6.1.1'/><b><FormattedMessage id='tuto.txt.6.1.2'/></b><FormattedMessage id='tuto.txt.6.1.3'/>
</Card.Text>
</Card.Body>
</Card>
@ -540,9 +541,9 @@ const Tutorial = ({locale, changeLocale}) => {
</button>
</Card.Header>
<Card.Body>
<Card.Title>L'indice</Card.Title>
<Card.Title><FormattedMessage id='tuto.title.7'/></Card.Title>
<Card.Text>
Ce bouton vous permet d'afficher votre indice personnel, gardez le secret ! Il s'agit de votre meilleur atout pour gagner.
<FormattedMessage id='tuto.txt.7.1'/>
</Card.Text>
</Card.Body>
</Card>
@ -552,13 +553,13 @@ const Tutorial = ({locale, changeLocale}) => {
<Card style={{ width: '90%', display:'flex', justifyContent:'center', alignItems:'center', flexDirection:'column'}}>
<Card.Img variant="top" src={graph} style={{width:'auto', height:'300px'}}/>
<Card.Body>
<Card.Title>Place à la pratique !</Card.Title>
<Card.Title><FormattedMessage id='tuto.title.8'/></Card.Title>
<Card.Text>
Bien joué ! Vous avez maintenanttoutes les bases d'un veritable détéctive.
<FormattedMessage id='tuto.txt.8.1'/>
<br/>
Vous allez à présent avoir un exercice pratique pour la résolution d'une enquête, au côté de ces très chère Batman et Scooby-Doo.
<FormattedMessage id='tuto.txt.8.2'/>
<br/>
Cliquer sur "Poursuivre" pour commencer votre première partie.
<FormattedMessage id='tuto.txt.8.3'/>
</Card.Text>
</Card.Body>
</Card>
@ -569,11 +570,11 @@ const Tutorial = ({locale, changeLocale}) => {
</Modal.Body>
<Modal.Footer style={{display:'flex'}}>
<div style={{ width:'100%', display:'flex', justifyContent:'start'}}>
<label style={{ color:'gray'}}>Étape {step+1}/7</label>
<label style={{ color:'gray'}}><FormattedMessage id='step'/> {step+1}/7</label>
</div>
{ step != -1 && (<Button variant="primary" onClick={() => setStep(step - 1)}>Précédent</Button>)}
{ step === 6 ? (<Button variant="primary" onClick={handleCloseM}>Poursuivre</Button>) :
<Button variant="primary" onClick={() => setStep(step + 1)}>Suivant</Button>}
{ step != -1 && (<Button variant="primary" onClick={() => setStep(step - 1)}><FormattedMessage id='previous'/></Button>)}
{ step === 6 ? (<Button variant="primary" onClick={handleCloseM}><FormattedMessage id='continue'/></Button>) :
<Button variant="primary" onClick={() => setStep(step + 1)}><FormattedMessage id='next'/></Button>}
</Modal.Footer>
</Modal>
@ -586,25 +587,25 @@ const Tutorial = ({locale, changeLocale}) => {
size="lg"
style={{ maxHeight: '100vh'}}>
<Modal.Header>
<Modal.Title>Tutoriel</Modal.Title>
<Modal.Title><FormattedMessage id='tutorial.title'/></Modal.Title>
</Modal.Header>
<Modal.Body style={{ display:'flex', justifyContent:'center', alignItems:'center', flexDirection:'column'}}>
<Card style={{ width: '100%', display:'flex', justifyContent:'center', alignItems:'center', flexDirection:'column'}}>
<Card.Img variant="top" src={step1} style={{width:'auto', height:'300px'}}/>
<Card.Body>
<Card.Title>Premier pas</Card.Title>
<Card.Title><FormattedMessage id='tuto.title.9'/></Card.Title>
<Card.Text>
Bienvenue dans cette seconde partie, où nous allons apprendre le déroulé d'une veritable enquête.
<FormattedMessage id='tuto.txt.9.1'/>
<br/>
Dans un premier temps, sélectionnez le joueur <b>Scooby-Doo</b> et questionnez le à propos du suspect nommé <b>Violet</b> en cliquant sur cette dernière.
<FormattedMessage id='tuto.txt.9.2.1'/><b>Scooby-Doo</b><FormattedMessage id='tuto.txt.9.2.2'/><b>Violet</b><FormattedMessage id='tuto.txt.9.2.3'/>
</Card.Text>
</Card.Body>
</Card>
</Modal.Body>
<Modal.Footer style={{display:'flex'}}>
<Button variant="primary" onClick={handleCloseTuto2}>Compris !</Button>
<Button variant="primary" onClick={handleCloseTuto2}><FormattedMessage id='compris'/></Button>
</Modal.Footer>
</Modal>
@ -616,18 +617,18 @@ const Tutorial = ({locale, changeLocale}) => {
size="lg"
style={{ maxHeight: '100vh'}}>
<Modal.Header>
<Modal.Title>Tutoriel</Modal.Title>
<Modal.Title><FormattedMessage id='tutorial.title'/></Modal.Title>
</Modal.Header>
<Modal.Body style={{ display:'flex', justifyContent:'center', alignItems:'center', flexDirection:'column'}}>
{step === 0 && (
<Card style={{ width: '100%', display:'flex', justifyContent:'center', alignItems:'center', flexDirection:'column'}}>
<Card.Img variant="top" src={step2} style={{width:'300px', height:'auto'}}/>
<Card.Body>
<Card.Title>Votre premier tour</Card.Title>
<Card.Title><FormattedMessage id='tuto.title.10'/></Card.Title>
<Card.Text>
Super, <u>Violet a été identifié par l'indice de Scooby-Doo</u>, c'est une information essentielle ! Cependant, cela ne signifie <i>pas forcément</i> qu'elle est coupable.
<FormattedMessage id='tuto.txt.10.1.1'/> <u><FormattedMessage id='tuto.txt.10.1.2'/></u><FormattedMessage id='tuto.txt.10.1.3'/><i><FormattedMessage id='tuto.txt.10.1.4'/></i><FormattedMessage id='tuto.txt.10.1.5'/>
<br/>
C'est à présent le tour aux autres joueurs de jouer, regardons ce qu'ils ont fait.
<FormattedMessage id='tuto.txt.10.2'/>
</Card.Text>
</Card.Body>
</Card>
@ -637,15 +638,13 @@ const Tutorial = ({locale, changeLocale}) => {
<Card style={{ width: '100%', display:'flex', justifyContent:'center', alignItems:'center', flexDirection:'column'}}>
<Card.Img variant="top" src={step3} style={{width:'200px', height:'auto'}}/>
<Card.Body>
<Card.Title>Premier tour des autres joueurs</Card.Title>
<Card.Title><FormattedMessage id='tuto.title.11'/></Card.Title>
<Card.Text>
Il semblerait que Scooby-Doo ait lui aussi interrogé Batman à propos de Violet, et que ce dernier ait répondu <b>non</b> par un carré.
Cela signifie que Violet n'est pas coupable, et qu'elle est donc innocente !
<FormattedMessage id='tuto.txt.11.1.1'/><b><FormattedMessage id='non'/></b><FormattedMessage id='tuto.txt.11.1.2'/>
<br/>
Scooby-Doo a donc fait une erreur, en questionnant quelqu'un pouvant innocenter Violet. En guise de <b>punition</b>, il doit, lui aussi, poser un carré sur un autre joueur, révélant aussi plus d'information sur son indice.
Nous savons donc maintenant que l'indice de Scooby-Doo ne permet pas d'identifier Sebastian.
<FormattedMessage id='tuto.txt.11.2.1'/><b><FormattedMessage id='tuto.txt.11.2.2'/></b><FormattedMessage id='tuto.txt.11.2.3'/>
<br/>
Ensuite, Batman a questionné Scooby-Doo à propos de Charlotte, qui est identifié par l'indice de Scooby-Doo.
<FormattedMessage id='tuto.txt.11.3'/>
</Card.Text>
</Card.Body>
</Card>
@ -655,11 +654,11 @@ const Tutorial = ({locale, changeLocale}) => {
<Card style={{ width: '100%', display:'flex', justifyContent:'center', alignItems:'center', flexDirection:'column'}}>
<Card.Img variant="top" src={step4} style={{width:'300px', height:'auto'}}/>
<Card.Body>
<Card.Title>Second tour</Card.Title>
<Card.Title><FormattedMessage id='tuto.title.12'/></Card.Title>
<Card.Text>
Vous remarquez que <u>votre indice identifie lui aussi Charlotte</u>, et si nous demandions à Batman, si ce dernier pense que Charlotte est la coupable ?
<FormattedMessage id='tuto.txt.12.1.1'/><u><FormattedMessage id='tuto.txt.12.1.2'/></u><FormattedMessage id='tuto.txt.12.1.3'/>
<br/>
Cela nous permettrait donc de mettre fin à la partie !
<FormattedMessage id='tuto.txt.12.2'/>
</Card.Text>
</Card.Body>
</Card>
@ -669,11 +668,11 @@ const Tutorial = ({locale, changeLocale}) => {
</Modal.Body>
<Modal.Footer style={{display:'flex'}}>
<div style={{ width:'100%', display:'flex', justifyContent:'start'}}>
<label style={{ color:'gray'}}>Étape {step+1}/3</label>
<label style={{ color:'gray'}}><FormattedMessage id='step'/> {step+1}/3</label>
</div>
{ step != 0 && (<Button variant="primary" onClick={() => setStep(step - 1)}>Précédent</Button>)}
{ step === 2 ? (<Button variant="primary" onClick={handleCloseTuto21}>Fermer</Button>) :
<Button variant="primary" onClick={() => setStep(step + 1)}>Suivant</Button>}
{ step != 0 && (<Button variant="primary" onClick={() => setStep(step - 1)}><FormattedMessage id='previous'/></Button>)}
{ step === 2 ? (<Button variant="primary" onClick={handleCloseTuto21}><FormattedMessage id='close'/></Button>) :
<Button variant="primary" onClick={() => setStep(step + 1)}><FormattedMessage id='next'/></Button>}
</Modal.Footer>
</Modal>
@ -685,26 +684,26 @@ const Tutorial = ({locale, changeLocale}) => {
size="lg"
style={{ maxHeight: '100vh'}}>
<Modal.Header>
<Modal.Title>Tutoriel</Modal.Title>
<Modal.Title><FormattedMessage id='tutorial.title'/></Modal.Title>
</Modal.Header>
<Modal.Body style={{ display:'flex', justifyContent:'center', alignItems:'center', flexDirection:'column'}}>
<Card style={{ width: '100%', display:'flex', justifyContent:'center', alignItems:'center', flexDirection:'column'}}>
<Card.Img variant="top" src={step5} style={{width:'300px', height:'auto'}}/>
<Card.Body>
<Card.Title>La punition</Card.Title>
<Card.Title><FormattedMessage id='tuto.title.13'/></Card.Title>
<Card.Text>
Mince, il semblerait que l'indice de Batman innocente Charlotte, et que vous avez donc commit une erreur, la <b>punition</b> s'applique !
<FormattedMessage id='tuto.txt.13.1.1'/><b><FormattedMessage id='tuto.txt.13.1.2'/></b><FormattedMessage id='tuto.txt.13.1.3'/>
<br/>
Vous devez donc poser un <u>carré sur un autre joueur</u>, révélant ainsi plus d'information sur votre indice.
<FormattedMessage id='tuto.txt.13.2.1'/><u><FormattedMessage id='tuto.txt.13.2.2'/></u><FormattedMessage id='tuto.txt.13.2.3'/>
<br/>
Mais rien n'est joué ! Posons notre carré sur <b>Liam</b> pour cela, sélectionnez directement le suspect désiré.
<FormattedMessage id='tuto.txt.13.3.1'/><b>Liam</b> <FormattedMessage id='tuto.txt.13.3.2'/>
</Card.Text>
</Card.Body>
</Card>
</Modal.Body>
<Modal.Footer style={{display:'flex'}}>
<Button variant="primary" onClick={handleCloseTuto22}>Compris !</Button>
<Button variant="primary" onClick={handleCloseTuto22}><FormattedMessage id='compris'/></Button>
</Modal.Footer>
</Modal>
@ -716,35 +715,35 @@ const Tutorial = ({locale, changeLocale}) => {
size="lg"
style={{ maxHeight: '100vh'}}>
<Modal.Header>
<Modal.Title>End Game</Modal.Title>
<Modal.Title>The End Game</Modal.Title>
</Modal.Header>
<Modal.Body style={{ display:'flex', justifyContent:'center', alignItems:'center', flexDirection:'column'}}>
<Card style={{ width: '100%', display:'flex', justifyContent:'center', alignItems:'center', flexDirection:'column'}}>
<Card.Img variant="top" src={step6} style={{width:'250px', height:'auto'}}/>
<Card.Body>
<Card.Title>La fin du jeu</Card.Title>
<Card.Title><FormattedMessage id='tuto.title.14'/></Card.Title>
<Card.Text>
Ce tour est lui aussi riche en informations !
<FormattedMessage id='tuto.txt.14.1'/>
<br/>
Vous avez à présent assez d'information pour deviner les indices des autres :
<FormattedMessage id='tuto.txt.14.2'/>
<ul>
<li>
Scooby-Doo semble avoir : <i>{indices[1]?.ToString(locale)}</i>.
<FormattedMessage id='tuto.txt.14.3'/><i>{indices[1]?.ToString(locale)}</i>.
</li>
<li>
Batman semble avoir : <i>{indices[2]?.ToString(locale)}</i>.
<FormattedMessage id='tuto.txt.14.4'/><i>{indices[2]?.ToString(locale)}</i>.
</li>
<li>
Et votre indice est : <i>{indices[0]?.ToString(locale)}</i>.
<FormattedMessage id='tuto.txt.14.5'/><i>{indices[0]?.ToString(locale)}</i>.
</li>
</ul>
Vous avez à présent toutes les cartes en main pour deviner qui est le coupable, cliquer sur le bouton <b>Ask Everyone</b>, puis séléctionné un suspect pour émettre une <b>accusation</b> pour deviner, bonne chance !
<FormattedMessage id='tuto.txt.14.6.1'/><b><FormattedMessage id='tuto.txt.14.6.2'/></b><FormattedMessage id='tuto.txt.14.6.3'/><b><FormattedMessage id='tuto.txt.14.6.4'/></b><FormattedMessage id='tuto.txt.14.6.5'/>
</Card.Text>
</Card.Body>
</Card>
</Modal.Body>
<Modal.Footer style={{display:'flex'}}>
<Button variant="primary" onClick={handleCloseTuto3}>Compris !</Button>
<Button variant="primary" onClick={handleCloseTuto3}><FormattedMessage id='compris'/></Button>
</Modal.Footer>
</Modal>
</div>

@ -64,7 +64,6 @@ function generateLatexCode(personsNet : PersonNetwork, choosenPerson : Person, c
person.getFriends().forEach((friend) => {
latexCode += ` \\draw (${person.getId()}) -- (${friend.getId()});\n`;
});
console.log(person.getFriends().length);
});
latexCode += "\\end{tikzpicture}\n";
@ -87,7 +86,7 @@ function generateLatexCode(personsNet : PersonNetwork, choosenPerson : Person, c
latexCode += "\\end{compactitem}\n"
//* Solution
latexCode += "% Solution : " + choosenPerson.getName() + "\n";
latexCode += "Solution : " + choosenPerson.getName() + "\n";
latexCode += "\\end{document}\n"
@ -147,7 +146,6 @@ function generateLatexCodeEnigme(personsNet : PersonNetwork, choosenPerson : Per
person.getFriends().forEach((friend) => {
latexCode += ` \\draw (${person.getId()}) -- (${friend.getId()});\n`;
});
console.log(person.getFriends().length);
});
latexCode += "\\end{tikzpicture}\n";
@ -194,8 +192,14 @@ function generateLatexCodeEnigme(personsNet : PersonNetwork, choosenPerson : Per
latexCode += "\\end{compactitem}\n"
//* Solution
latexCode += "% Solution : " + choosenPerson.getName() + "\n";
latexCode += "Solution : " + choosenPerson.getName() + "\n";
latexCode += "\\begin{compactitem}\n"
choosenIndices.forEach((indices, index) => {
latexCode += `\\item Indice ${index + 1}: ${indices.ToString("fr")}\n`
})
latexCode += "\\end{compactitem}\n"
latexCode += "\\end{document}\n"
return latexCode

@ -26,6 +26,13 @@
"sign_up":" Sign up ",
"log_out":" Log out ",
"indice":"Hint",
"param":"Settings",
"sfx":"Activate sounds",
"aide":"Help",
"majUn":"A",
"join" : "Join",
"create_room" : "Create room",
"play_solo" : "Single player",
@ -44,6 +51,10 @@
"redhead": "Red",
"brown": "Brown",
"oui": "yes",
"non": "no",
"and": "and",
"or": "or",
"or_sport": "or",
@ -68,15 +79,80 @@
"sport_start": "The suspect plays at least",
"sport_end": "",
"navbar.play" : "Play",
"navbar.presentation":"Presentation",
"navbar.info":"Information",
"hard": "Hard",
"medium": "Medium",
"strong": "Strong",
"weak": "Weak",
"none": "None",
"turn" : "Round",
"square":"square",
"round":"round",
"step": "Step",
"previous": "Previous",
"next": "Next",
"continue": "Continue",
"compris": "Understood!",
"close": "Close",
"regenerate":"Regenarte graph",
"BackHome" : "Back to home",
"askeveryone" : "Ask everyone",
"color.green":"Green",
"color.blue":"Blue",
"color.red":"Red",
"color.yellow":"Yellow",
"play.jouerseul": "Play alone",
"play.enigme": "Solve an enigma",
"play.enigme.easy": "Easy",
"play.enigme.medium": "Intermediate",
"play.enigme.hard": "Hard",
"play.create": "Create a game",
"play.tuto": "Tutorial",
"play.return": "Return to game",
"lobbies.all":"All",
"lobbies.dispo":"Disponible",
"placeholder.searchLobby": "Search for a lobby...",
"score.nbPlayed": "Games Played",
"score.best": "Best Score",
"score.moy": "Average Attempts",
"score.NbWin": "Number of Wins",
"score.ratio": "Win/Loss Ratio",
"score.bestTmp": "Best Time",
"score.moyTmp": "Average Time",
"score.nothing": "Nothing for the moment",
"score.titre.easy": "Easy Enigma",
"score.titre.int": "Intermediate Enigma",
"score.titre.hard": "Hard Enigma",
"score.online": "Online",
"score.tab.stat" : "Your Stats",
"score.tab.quoti" : "Daily",
"score.tab.hebdo" : "Weekly",
"lobby.players" : "Players",
"lobby.bienvenue": "Welcome to your lobby!",
"lobby.wait": "Wait for all your friends to join before starting the game.",
"lobby.invite": "Invite friends",
"lobby.copyLink": "Link copied",
"lobby.nbNode": "Select the number of nodes (between 20 and 60)",
"lobby.start": "Start the game!",
"game.yourTurn":"It's your turn !",
"game.wrong":"Wrong choice, put a square !",
"informations" : "Information",
"info.intro.title":"Introduction to the game :",
@ -114,6 +190,11 @@
"hair.chatain":"Brown",
"hair.noir":"Black",
"param.node": "Select the number of nodes (between 20 and 50)",
"param.clue": "Select the number of clues (between 3 and 6)",
"param.valid": "Validate",
"info.composant.sport.title":"Sports",
"info.composant.sport":"The characters' hobbies are represented by five sports respectively :",
"info.composant.baseball":"Baseball",
@ -165,5 +246,112 @@
"info.mdj.enigme.medium": "Intermediate Enigma",
"info.mdj.enigme.medium.txt": "In this game mode, you don't have access to clues, but you have just enough information about some suspects to be able to guess the culprit. This information will help you guess the clues, and the culprit is the suspect for whom all the clues match. If you select the wrong suspect, don't worry! You'll have information about that suspect, making it easier for you to find the culprit. The goal is to find the culprit in the minimum number of guesses.",
"info.mdj.enigme.hard": "Hard Enigma",
"info.mdj.enigme.hard.txt": "This final variant is similar to the intermediate enigma; however, you must find the culprit on the first try, or you lose! It's up to you to play! The goal is to find the culprit in the minimum amount of time."
"info.mdj.enigme.hard.txt": "This final variant is similar to the intermediate enigma; however, you must find the culprit on the first try, or you lose! It's up to you to play! The goal is to find the culprit in the minimum amount of time.",
"tutorial.title": "Tutorial",
"tuto.title.1": "Welcome to SocialGraph!",
"tuto.txt.1.1": "You play as a glory-seeking detective faced with a crime.",
"tuto.txt.1.2": "However, other investigators are also on the case, all seeking the title of the world's best detective.",
"tuto.txt.1.3": "Each has a crucial clue to identify the culprit; you'll need to deduce your competitors' clues if you want to win!",
"tuto.txt.1.4": "Interrogate your competitors to get answers with yes or no, but beware, a refusal has consequences.",
"tuto.txt.1.5": "Be the first to deduce the clues of others and find the culprit to win the coveted recognition.",
"tuto.txt.1.6": "If you have any doubts, click on the 'help' button to display the current tutorial step.",
"tuto.title.2": "The Suspects",
"tuto.txt.2.1": "Here is how a suspect is represented; each suspect has different characteristics, including their name, age, sport, and hair color.",
"tuto.txt.2.2": "For example, here we have ",
"tuto.txt.2.2.1": ", who is ",
"tuto.txt.2.2.2": ", practicing ",
"tuto.txt.2.2.3": " and ",
"tuto.txt.2.2.4": ", has ",
"tuto.txt.2.2.5": " hair, and possesses ",
"tuto.title.3": "The Clues",
"tuto.txt.3.1": "In this game, each detective has a clue that identifies a characteristic of the culprit. Your clue is:",
"tuto.txt.3.2": "The suspect is between 20 and 29 years old.",
"tuto.title.4": "The Detectives",
"tuto.txt.4.1": "It is possible to see the detectives on the left side of the screen, represented by circles of different colors. The square outline means that the detective is in deep thought.",
"tuto.txt.4.2": "To interrogate a detective about a suspect, select the detective, then click on the suspect you want. The detective will respond with what he thinks of this suspect based on his clue.",
"tuto.title.5": "The Responses",
"tuto.txt.5.1": "Detectives will respond to you only with circles or squares of their color.",
"tuto.txt.5.2": " means that their clue clears the suspect.",
"tuto.txt.5.3": " means that their clue may incriminate the suspect.",
"tuto.txt.5.4": "For example, here:",
"tuto.txt.5.5.1": "Scooby-Doo's clue ",
"tuto.txt.5.5.2": "clears Logan.",
"tuto.txt.5.6": "Eleanor can be suspected based on Batman's clue.",
"tuto.txt.5.7.1": "Evelyn is cleared by the clues of ",
"tuto.txt.5.7.2": "3 different detectives.",
"tuto.title.6": "The Rules of the Game",
"tuto.txt.6.1.1": "This button takes you to the game's ",
"tuto.txt.6.1.2": "information page",
"tuto.txt.6.1.3": ", with all the rules of the game, including objectives, clues, flow, etc.",
"tuto.title.7": "The Clue",
"tuto.txt.7.1": "This button allows you to display your personal clue; keep it a secret! It is your best asset to win.",
"tuto.title.8": "Time to Practice!",
"tuto.txt.8.1": "Well done! You now have all the basics of a real detective.",
"tuto.txt.8.2": "You will now have a practical exercise for solving a case, alongside our dear Batman and Scooby-Doo.",
"tuto.txt.8.3": "Click 'Continue' to start your first game.",
"tuto.title.9": "First Steps",
"tuto.txt.9.1": "Welcome to this second part, where we will learn the flow of a real investigation.",
"tuto.txt.9.2.1": "First, select player ",
"tuto.txt.9.2.2": " and question them about the suspect named ",
"tuto.txt.9.2.3": " by clicking on the latter.",
"tuto.title.10": "Your First Turn",
"tuto.txt.10.1.1": "Great, ",
"tuto.txt.10.1.2": "Violet has been identified by Scooby-Doo's clue",
"tuto.txt.10.1.3": ", which is essential information! However, this does not necessarily ",
"tuto.txt.10.1.4": "mean",
"tuto.txt.10.1.5": " that she is guilty.",
"tuto.txt.10.2": "Now, it's the other players' turn to play; let's see what they did.",
"tuto.title.11": "Other Players' First Turn",
"tuto.txt.11.1.1": "It seems that Scooby-Doo also questioned Batman about Violet, and Batman responded with ",
"tuto.txt.11.1.2": "a square. This means Violet is not guilty and is innocent!",
"tuto.txt.11.2.1": "Scooby-Doo made a mistake by questioning someone who could clear Violet. As a ",
"tuto.txt.11.2.2": "punishment",
"tuto.txt.11.2.3": ", he must also place a square on another player, revealing more information about his clue. So now we know that Scooby-Doo's clue does not identify Sebastian.",
"tuto.txt.11.3": "Next, Batman questioned Scooby-Doo about Charlotte, identified by Scooby-Doo's clue.",
"tuto.title.12": "Second Turn",
"tuto.txt.12.1.1": "You notice that ",
"tuto.txt.12.1.2": "your clue also identifies Charlotte",
"tuto.txt.12.1.3": ", so what if we ask Batman if he thinks Charlotte is the culprit?",
"tuto.txt.12.2": "This would allow us to end the game!",
"tuto.title.13": "The Punishment",
"tuto.txt.13.1.1": "Oh no, it seems that Batman's clue clears Charlotte, and you have made a mistake; the ",
"tuto.txt.13.1.2": "punishment",
"tuto.txt.13.1.3": " applies!",
"tuto.txt.13.2.1": "So, you must place a ",
"tuto.txt.13.2.2": "square on another player",
"tuto.txt.13.2.3": ", revealing more information about your clue.",
"tuto.txt.13.3.1": "But all is not lost! Let's place our square on ",
"tuto.txt.13.3.2": "for that, select the desired suspect directly.",
"tuto.title.14": "The End of the Game",
"tuto.txt.14.1": "This turn is also rich in information!",
"tuto.txt.14.2": "You now have enough information to guess the clues of others:",
"tuto.txt.14.3": "Scooby-Doo seems to have:",
"tuto.txt.14.4": "Batman seems to have:",
"tuto.txt.14.5": "And your clue is:",
"tuto.txt.14.6.1": "You now have all the cards in hand to guess who the culprit is. Click the ",
"tuto.txt.14.6.2": "Ask Everyone",
"tuto.txt.14.6.3": " button, then select a suspect to make an ",
"tuto.txt.14.6.4": "accusation",
"tuto.txt.14.6.5": " to guess. Good luck!",
"history.mis": " placed a ",
"à": "to",
"history.cantPose": " can no longer place a square",
"history.NotCoupable": " is not the culprit!"
}

@ -67,6 +67,12 @@
"sport_start": "El sospechoso juega al menos",
"sport_end": "",
"navbar.play" : "Jugar",
"navbar.presentation":"Presentación",
"navbar.info":"Información",
"round":"Vuelta",
"informations": "Información",
"info.intro.title": "Introducción al juego:",
"info.intro.text": "¡Bienvenido a nuestro emocionante juego de deducción, donde la intriga y la travesura se combinan en una emocionante aventura! Sumérgete en un mundo de misterio e intriga, donde cada interacción cuenta y cada pista te acerca a la verdad. Imagina un gráfico complejo donde cada vértice representa a una persona, cada eje una relación, y cada detalle cuenta. Te sumerges en un desafiante reto para descubrir quién entre estas personas es el misterioso asesino. Cada jugador tiene una pista crucial y solo el intercambio estratégico de estas pistas te llevará a resolver el misterio. Explora nuestra página de reglas para entender las complejidades del juego, descubre pistas que pueden guiarte y desarrolla estrategias inteligentes para identificar al culpable. ¡Manipula a tus amigos para ser el primero en descubrir quién es el asesino oculto en el gráfico! ¿Estás listo para aceptar el desafío y desenmascarar al asesino oculto en el gráfico? ¡Que comience la investigación!",

@ -26,6 +26,12 @@
"sign_up":" S'inscrire ",
"log_out":" Se déconnecter ",
"indice":"Indice",
"param":"Paramètres",
"sfx":"Activer les sons",
"aide":"Aide",
"majUn":"Un",
"join" : "Rejoindre",
"create_room" : "Créer une partie",
@ -44,6 +50,10 @@
"redhead": "Roux",
"brown": "Brun",
"oui": "oui",
"non": "non",
"and": "et",
"or": "ou",
"or_sport": "ou du",
@ -67,15 +77,81 @@
"sport_start": "Le suspect pratique au moins du",
"sport_end": "",
"navbar.play" : "Jouer",
"navbar.presentation":"Présentation",
"navbar.info":"Informations",
"hard" : "Difficile",
"medium" : "Intermédiaire",
"strong" : "Fort",
"weak" : "Faible",
"none" : "Aucun",
"turn" : "Tour",
"square":"carré",
"round":"rond",
"step" : "Étape",
"previous" : "Précédent",
"next" : "Suivant",
"continue" : "Poursuivre",
"compris":"Compris !",
"close" : "Fermer",
"askeveryone" : "Demandez à tous",
"regenerate":"Regénérer le graph",
"BackHome" : "Retour à l'accueil",
"color.green":"Vert",
"color.blue":"Bleu",
"color.red":"Rouge",
"color.yellow":"Jaune",
"play.jouerseul": "Mastermind",
"play.enigme": "Résoudre une énigme",
"play.enigme.easy": "Facile",
"play.enigme.medium": "Intermédiaire",
"play.enigme.hard": "Difficile",
"play.create":"Créer une partie",
"play.tuto": "Tutoriel",
"play.return": "Retourner à la partie",
"lobbies.all":"Tous",
"lobbies.dispo":"Disponibles",
"placeholder.searchLobby": "Rechercher un lobby...",
"score.nbPlayed" : "Parties Jouées",
"score.best" : "Best-Score",
"score.moy" : "Moyenne d'essai",
"score.NbWin" : "Nombre de victoire",
"score.ratio" : "Ratio V/D",
"score.bestTmp" : "Meilleur temps",
"score.moyTmp" : "Moyenne de temps",
"score.nothing" : "Rien pour le moment",
"score.titre.easy" : "Énigme facile",
"score.titre.int" : "Énigme intermédiaire",
"score.titre.hard" : "Énigme difficile",
"score.online" : "En ligne",
"score.tab.stat" : "Vos Stats",
"score.tab.quoti" : "Quotidien",
"score.tab.hebdo" : "Hebdomadaire",
"lobby.players" : "Joueurs",
"lobby.bienvenue" : "Bienvenue dans votre lobby !",
"lobby.wait" : "Attendez que tous vos amis rejoignent avant de lancer la partie.",
"lobby.invite" : "Inviter des amis",
"lobby.copyLink" : "Lien copié",
"lobby.nbNode" : "Sélectionner le nombre de noeud (entre 20 et 60) ",
"lobby.start" : "Démarrer la partie !",
"game.yourTurn":"À vous de jouer !",
"game.wrong":"Mauvais choix, posez un carré !",
"informations" : "Informations",
"info.intro.title":"Introduction au jeu :",
@ -113,6 +189,12 @@
"hair.chatain":"Châtain",
"hair.noir":"Noir",
"param.node":"Sélectionner le nombre de noeuds (entre 20 et 50)",
"param.clue":"Sélectionner le nombre d'indices (entre 3 et 6)",
"param.valid":"Valider",
"info.composant.sport.title":"Les Sports",
"info.composant.sport":"Les loisirs des personnages sont représentés par cinq sports respectivement :",
@ -165,5 +247,113 @@
"info.mdj.enigme.medium":"L'énigme intermédiaire",
"info.mdj.enigme.medium.txt":"Dans ce mode de jeu, vous n'avez pas accès au indice, mais vous avez juste assez d'informations sur certains suspects pour pouvoir deviner le coupable. Ces informations vont vous permettre de deviner les indices, et le coupable est le suspect pour lequel tous les indices correspondent. Si jamais vous sélectionnez le mauvais suspect, pas de panique ! Vous aurez les informations relatives à ce dernier, ce qui vous facilitera le travail pour trouver le coupable. L'objectif est donc de trouver le coupable en un minimum de coup.",
"info.mdj.enigme.hard":"L'énigme difficile",
"info.mdj.enigme.hard.txt":"Cette dernière variante est similaire à l'énigme intermédiaire, cependant, il faudra trouver du premier coup sinon, vous aurez perdu ! À vous de jouer ! L'objectif est donc de trouver le coupable en un minimum de temps."
"info.mdj.enigme.hard.txt":"Cette dernière variante est similaire à l'énigme intermédiaire, cependant, il faudra trouver du premier coup sinon, vous aurez perdu ! À vous de jouer ! L'objectif est donc de trouver le coupable en un minimum de temps.",
"tutorial.title":"Tutoriel",
"tuto.title.1":"Bienvenue dans SocialGraph !",
"tuto.txt.1.1":"Vous incarnez un détective assoiffé de gloire, confronté à un crime.",
"tuto.txt.1.2":"Cependant, d'autres enquêteurs sont également sur le coup, tous cherchant à décrocher le titre de meilleur détective du monde.",
"tuto.txt.1.3":"Chacun possède un indice crucial pour identifier le coupable, il va falloir déduire l'indice de vos concurrents si vous souhaitez l'emporter !",
"tuto.txt.1.4":"Interrogez vos concurrents pour obtenir des réponses par oui ou non, mais méfiez-vous, un refus a des conséquences.",
"tuto.txt.1.5":"Soyez le premier à déduire les indices des autres et à trouver le coupable pour remporter la reconnaissance tant convoitée.",
"tuto.txt.1.6":"Si vous avez le moindre doute, cliquer sur le bouton 'aide' pour afficher l'étape actuel du tuto",
"tuto.title.2":"Les Suspects",
"tuto.txt.2.1":"Voici comment est représenté un suspect, chaque suspect possède différentes caractéristiques, que ce soit leur nom, âge, sport et leur couleur de cheveux.",
"tuto.txt.2.2":"Par exemple, ici, nous avons ",
"tuto.txt.2.2.1":", qui a ",
"tuto.txt.2.2.2":", qui pratique du ",
"tuto.txt.2.2.3":" et du ",
"tuto.txt.2.2.4":", qui a les cheveux ",
"tuto.txt.2.2.5":" et qui possède ",
"tuto.title.3":"Les indices",
"tuto.txt.3.1":"Dans ce jeu, chaque détective possède un indice, qui permet d'identifier une caractéristique du coupable, votre indice est le suivant :",
"tuto.txt.3.2":"Le suspect a entre 20 et 29 ans",
"tuto.title.4":"Les Détectives",
"tuto.txt.4.1":"Il est possible de voir les détectives sur le côté gauche de l'écran, ils sont représentés par des cercles de couleurs différentes. Le contour carré signifie que ce détective est en pleine réflexion.",
"tuto.txt.4.2":"Pour interroger un détective à propos d'un suspect, il suffit de le sélectionner, puis de cliquer sur le suspect que vous souhaitez. Il vous répondra donc ce qu'il pense de ce suspect selon son indice.",
"tuto.title.5":"Les réponses",
"tuto.txt.5.1":"Les détéctives vous répondrons que par des ronds ou des carrés de leur couleur.",
"tuto.txt.5.2":" signifie que son indice innocente le suspect",
"tuto.txt.5.3":" signifie que son indice peut incréminer le suspect",
"tuto.txt.5.4":"Par exemple, ici :",
"tuto.txt.5.5.1":"l'indice du détéctive Scooby-Doo ",
"tuto.txt.5.5.2":" permet d'innocenter Logan",
"tuto.txt.5.6":"Eleanor peut être suspectée par l'indice du détective Batman ",
"tuto.txt.5.7.1":"Evelyn est innocentée par l'indice de ",
"tuto.txt.5.7.2":"3 détéctives différents",
"tuto.title.6":"Les règles du jeu",
"tuto.txt.6.1.1":"Ce bouton vous mène à la page d'",
"tuto.txt.6.1.2":"information du jeu",
"tuto.txt.6.1.3":", avec toutes les règles du jeu, que ce soit les objectifs, les indices, le déroulement, etc.",
"tuto.title.7":"L'indice",
"tuto.txt.7.1":"Ce bouton vous permet d'afficher votre indice personnel, gardez le secret ! Il s'agit de votre meilleur atout pour gagner.",
"tuto.title.8":"Place à la pratique !",
"tuto.txt.8.1":"Bien joué ! Vous avez maintenant toutes les bases d'un veritable détéctive.",
"tuto.txt.8.2":"Vous allez à présent avoir un exercice pratique pour la résolution d'une enquête, au côté de ces très chère Batman et Scooby-Doo.",
"tuto.txt.8.3":"Cliquer sur 'Poursuivre' pour commencer votre première partie.",
"tuto.title.9":"Premier pas",
"tuto.txt.9.1":"Bienvenue dans cette seconde partie, où nous allons apprendre le déroulé d'une veritable enquête.",
"tuto.txt.9.2.1":"Dans un premier temps, sélectionnez le joueur ",
"tuto.txt.9.2.2":" et questionnez le à propos du suspect nommé ",
"tuto.txt.9.2.3":" en cliquant sur cette dernière.",
"tuto.title.10":"Votre premier tour",
"tuto.txt.10.1.1":"Super, ",
"tuto.txt.10.1.2":"Violet a été identifié par l'indice de Scooby-Doo",
"tuto.txt.10.1.3":", c'est une information essentielle ! Cependant, cela ne signifie ",
"tuto.txt.10.1.4":"pas forcément",
"tuto.txt.10.1.5":" qu'elle est coupable.",
"tuto.txt.10.2":"C'est à présent le tour aux autres joueurs de jouer, regardons ce qu'ils ont fait.",
"tuto.title.11":"Premier tour des autres joueurs",
"tuto.txt.11.1.1":"Il semblerait que Scooby-Doo ait lui aussi interrogé Batman à propos de Violet, et que ce dernier ait répondu ",
"tuto.txt.11.1.2":" par un carré. Cela signifie que Violet n'est pas coupable, et qu'elle est donc innocente !",
"tuto.txt.11.2.1":"Scooby-Doo a donc fait une erreur, en questionnant quelqu'un pouvant innocenter Violet. En guise de ",
"tuto.txt.11.2.2":"punition",
"tuto.txt.11.2.3":", il doit, lui aussi, poser un carré sur un autre joueur, révélant aussi plus d'information sur son indice.Nous savons donc maintenant que l'indice de Scooby-Doo ne permet pas d'identifier Sebastian.",
"tuto.txt.11.3":"Ensuite, Batman a questionné Scooby-Doo à propos de Charlotte, qui est identifié par l'indice de Scooby-Doo.",
"tuto.title.12":"Second tour",
"tuto.txt.12.1.1":"Vous remarquez que ",
"tuto.txt.12.1.2":"votre indice identifie lui aussi Charlotte",
"tuto.txt.12.1.3":", et si nous demandions à Batman, si ce dernier pense que Charlotte est la coupable ?",
"tuto.txt.12.2":"Cela nous permettrait donc de mettre fin à la partie !",
"tuto.title.13":"La punition",
"tuto.txt.13.1.1":"Mince, il semblerait que l'indice de Batman innocente Charlotte, et que vous avez donc commit une erreur, la ",
"tuto.txt.13.1.2":"punition",
"tuto.txt.13.1.3":" s'applique !",
"tuto.txt.13.2.1":"Vous devez donc poser un ",
"tuto.txt.13.2.2":"carré sur un autre joueur",
"tuto.txt.13.2.3":", révélant ainsi plus d'information sur votre indice.",
"tuto.txt.13.3.1": "Mais rien n'est joué ! Posons notre carré sur ",
"tuto.txt.13.3.2": "pour cela, sélectionnez directement le suspect désiré.",
"tuto.title.14":"La fin du jeu",
"tuto.txt.14.1":"Ce tour est lui aussi riche en informations !",
"tuto.txt.14.2":"Vous avez à présent assez d'information pour deviner les indices des autres : ",
"tuto.txt.14.3":"Scooby-Doo semble avoir : ",
"tuto.txt.14.4":"Batman semble avoir : ",
"tuto.txt.14.5":"Et votre indice est : ",
"tuto.txt.14.6.1":"Vous avez à présent toutes les cartes en main pour deviner qui est le coupable, cliquer sur le bouton ",
"tuto.txt.14.6.2":"Ask Everyone",
"tuto.txt.14.6.3":", puis séléctionné un suspect pour émettre une ",
"tuto.txt.14.6.4":"accusation",
"tuto.txt.14.6.5":" pour deviner, bonne chance !",
"history.mis":" a mis un ",
"à":"à",
"history.cantPose":" ne peut plus poser de carré",
"history.NotCoupable":" n'est pas le coupable !"
}

@ -68,6 +68,13 @@
"sport_start": "O suspeito joga pelo menos",
"sport_end": "",
"navbar.play" : "Jogar",
"navbar.presentation":"Apresentação",
"navbar.info":"Informação",
"round":"ronda",
"informations" : "Informação",
"info.intro.title":"Introdução ao jogo:",
"info.intro.text":"Bem-vindo ao nosso empolgante jogo de dedução, onde intriga e malícia se unem em uma aventura emocionante! Mergulhe em um mundo de mistério e intriga, onde cada interação conta, e cada pista o aproxima da verdade. Imagine um gráfico complexo onde cada vértice representa uma pessoa, cada eixo uma relação, e cada detalhe conta. Você está imerso em um desafio desafiador para descobrir quem, entre esses indivíduos, é o misterioso assassino. Cada jogador tem uma pista crucial, e apenas o compartilhamento estratégico dessas pistas o levará a resolver o mistério. Explore nossa página de regras para entender as complexidades do jogo, descobrir pistas que podem orientá-lo e desenvolver estratégias inteligentes para identificar o culpado. Manipule seus amigos para ser o primeiro a descobrir quem é o assassino escondido no gráfico. Você está pronto para aceitar o desafio e desmascarar o assassino oculto no gráfico? Que a investigação comece!",

@ -68,6 +68,11 @@
"sport_start": "Подозреваемый играет по меньшей мере в",
"sport_end": "",
"navbar.play" : "Разыграть",
"navbar.presentation":"Презентационный",
"navbar.info":"Информация",
"round" : "Раунд",
"informations" : "Информация",
"info.intro.title":"Введение в игру :",

@ -41,6 +41,8 @@ class DbUserService implements IUserService{
nbWins: sessionData.user.onlineStats.nbWins,
ratio: sessionData.user.onlineStats.ratio,
});
currentUser.nbNodes = sessionData.user.nbNodes || 25
currentUser.nbIndices = sessionData.user.nbIndices || 3
return [currentUser, true];
}
@ -76,6 +78,9 @@ class DbUserService implements IUserService{
ratio: 0,
});
guestUser.nbNodes = 25
guestUser.nbIndices = 3
return [guestUser, false];
}
} catch (error) {
@ -148,6 +153,19 @@ class DbUserService implements IUserService{
console.error(error);
}
}
async changeNodesIndices(nbNodes: number, nbIndices: number): Promise<void> {
try {
const result = await SessionService.changeNodesIndices(nbNodes, nbIndices);
if (result) {
console.log("Nodes updated");
} else {
console.log("Nodes not updated");
}
} catch (error) {
console.error(error);
}
}
}
export default DbUserService

@ -2,6 +2,7 @@ import User from "../User";
interface IUserService{
fetchUserInformation(): Promise<[User | null, boolean]>
changeNodesIndices(nbNodes: number, nbIndices: number): Promise<void>
addMastermindStats(pseudo: string, score: number, time: number): Promise<void>
addEasyEnigmaStats(pseudo: string, win: number, time: number): Promise<void>
// addMediumEnigmaStats(pseudo: string, win: number, time: number): Promise<void>

@ -7,6 +7,8 @@ class User extends Player{
public mediumEnigmaStats: any
public hardEnigmaStats: any
public onlineStats: any
public nbNodes: number = 25
public nbIndices: number = 3
constructor(id: string, pseudo: string, profilePicture: string, soloStats: any, easyEnigmaStats: any, mediumEnigmaStats: any, hardEnigmaStats: any, onlineStats: any){
super(id, pseudo, profilePicture || defaultImg)

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 822 B

@ -24,6 +24,34 @@ class SessionService {
}
}
static async changeNodesIndices(nbNodes: number, nbIndices: number) {
try {
const response = await fetch(ADRESSE_DBSERVER + '/session/updateNbNodes', {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
nbNodes,
nbIndices
}),
credentials: 'include',
});
if (response.ok) {
const result = await response.json();
return result;
} else {
const errorResponse = await response.json();
throw new Error(errorResponse.error);
}
} catch (error) {
console.error(error);
throw error;
}
}
static async addMastermindStats(pseudo: string, score: number, time: number){
try {
const response = await fetch(ADRESSE_DBSERVER + '/session/addMastermindStats', {

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save