pull/81/head
Baptiste MARCEL 1 year ago
commit 82090c71f5

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 254 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

@ -24,6 +24,7 @@
"cors": "^2.8.5", "cors": "^2.8.5",
"express": "^4.18.2", "express": "^4.18.2",
"express-session": "^1.17.3", "express-session": "^1.17.3",
"file-saver": "^2.0.5",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"mysql": "^2.18.1", "mysql": "^2.18.1",
"react": "^18.2.0", "react": "^18.2.0",
@ -44,6 +45,7 @@
"web-vitals": "^2.1.4" "web-vitals": "^2.1.4"
}, },
"devDependencies": { "devDependencies": {
"@types/file-saver": "^2.0.7",
"@types/react-router-hash-link": "^2.4.9", "@types/react-router-hash-link": "^2.4.9",
"@types/uuid": "^9.0.7" "@types/uuid": "^9.0.7"
} }
@ -4345,6 +4347,12 @@
"@types/send": "*" "@types/send": "*"
} }
}, },
"node_modules/@types/file-saver": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.7.tgz",
"integrity": "sha512-dNKVfHd/jk0SkR/exKGj2ggkB45MAkzvWCaqLUUgkyjITkGNzH8H+yUwr+BLJUBjZOe9w8X3wgmXhZDRg1ED6A==",
"dev": true
},
"node_modules/@types/graceful-fs": { "node_modules/@types/graceful-fs": {
"version": "4.1.9", "version": "4.1.9",
"resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz",
@ -8870,6 +8878,11 @@
"webpack": "^4.0.0 || ^5.0.0" "webpack": "^4.0.0 || ^5.0.0"
} }
}, },
"node_modules/file-saver": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz",
"integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA=="
},
"node_modules/filelist": { "node_modules/filelist": {
"version": "1.0.4", "version": "1.0.4",
"resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz",

@ -18,6 +18,7 @@
"cors": "^2.8.5", "cors": "^2.8.5",
"express": "^4.18.2", "express": "^4.18.2",
"express-session": "^1.17.3", "express-session": "^1.17.3",
"file-saver": "^2.0.5",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"mysql": "^2.18.1", "mysql": "^2.18.1",
"react": "^18.2.0", "react": "^18.2.0",
@ -62,6 +63,7 @@
] ]
}, },
"devDependencies": { "devDependencies": {
"@types/file-saver": "^2.0.7",
"@types/react-router-hash-link": "^2.4.9", "@types/react-router-hash-link": "^2.4.9",
"@types/uuid": "^9.0.7" "@types/uuid": "^9.0.7"
} }

@ -18,7 +18,7 @@ const map = new Map()
// ... le reste de votre configuration du serveur // ... le reste de votre configuration du serveur
server.listen(3002, () => { server.listen(3002, () => {
console.log('Serveur Socket.IO écoutant sur le port 3001'); console.log('Serveur Socket.IO écoutant sur le port 3002');
}); });
io.on('connection', (socket) => { io.on('connection', (socket) => {
@ -54,6 +54,19 @@ io.on('connection', (socket) => {
io.to(room).emit("new player", map.get(room)) io.to(room).emit("new player", map.get(room))
}) })
socket.on("bot deleted", (bot, room) =>{
// map.set(room, map.get(room).filter(player => player.id !== bot.id));
const tab = map.get(room)
for(let i = 0; i<tab.length; i++){
if (tab[i].id === bot.id){
tab.splice(i, 1)
}
}
io.to(room).emit("new player", map.get(room))
})
socket.on("lobby created", () =>{ socket.on("lobby created", () =>{
io.to(socket.id).emit("lobby created", Math.floor(Math.random() * 10000)) io.to(socket.id).emit("lobby created", Math.floor(Math.random() * 10000))
}) })
@ -80,7 +93,7 @@ io.on('connection', (socket) => {
for (let i = 0; i<tab.length; i++){ for (let i = 0; i<tab.length; i++){
if (tab[i].id === socket.id){ if (tab[i].id === socket.id){
tab.splice(i, 1) tab.splice(i, 1)
io.to(k).emit("player left", tab, socket.id) io.to(k).emit("player left", tab, i)
} }
} }
} }
@ -102,8 +115,19 @@ io.on('connection', (socket) => {
io.to(id).emit("put imossible grey") io.to(id).emit("put imossible grey")
}) })
socket.on("opacity activated", (id) => {
io.to(id).emit("opacity activated")
})
socket.on("opacity deactivated", (id) => {
io.to(id).emit("opacity deactivated")
})
socket.on("reset graph", (id) => {
io.to(id).emit("reset graph")
})
socket.on("end game", (winnerIndex, room) =>{ socket.on("end game", (winnerIndex, room) =>{
console.log("endgame")
io.to(room).emit("end game", winnerIndex) io.to(room).emit("end game", winnerIndex)
}) })
}); });

@ -53,4 +53,41 @@ function colorToEmoji(color: string, works: boolean): string{
} }
} }
export {colorToEmoji, positionToColor}
function positionToEmoji(pos: number, works: boolean): string{
if (works){
switch (pos) {
case 0:
return "🔵";
case 1:
return "🟢";
case 2:
return "🟡";
case 3:
return "🟣";
case 4:
return "🔴";
default:
return "🟤";
}
}
else{
switch (pos) {
case 0:
return "🟦";
case 1:
return "🟩";
case 2:
return "🟨";
case 3:
return "🟪";
case 4:
return "🟥";
default:
return "🟫";
}
}
}
export {colorToEmoji, positionToColor, positionToEmoji}

@ -1,27 +1,16 @@
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { DataSet, Network} from "vis-network/standalone/esm/vis-network"; import { DataSet, Network} from "vis-network/standalone/esm/vis-network";
import EdgesCreator from "../model/EdgesCreator";
import GraphCreator from "../model/Graph/GraphCreator"; import GraphCreator from "../model/Graph/GraphCreator";
import IndiceChooser from "../model/IndiceChooser";
import SportIndice from "../model/Indices/SportIndice";
import NetworkGenerator from "../model/NetworkGenerator";
import Sport from "../model/Sport";
import Stub from "../model/Stub";
import "./GraphContainer.css"; import "./GraphContainer.css";
import NodePerson from "../model/Graph/NodePerson";
import IndiceTesterFactory from "../model/Factory/IndiceTesterFactory"; import IndiceTesterFactory from "../model/Factory/IndiceTesterFactory";
import GameCreator from "../model/GameCreator";
import io from 'socket.io-client';
import JSONParser from "../JSONParser";
import PersonNetwork from "../model/PersonsNetwork";
import Person from "../model/Person"; import Person from "../model/Person";
import Indice from "../model/Indices/Indice";
import { Navigate, useLocation, useNavigate } from "react-router-dom"; import { Navigate, useLocation, useNavigate } from "react-router-dom";
import { useGame } from "../Contexts/GameContext"; import { useGame } from "../Contexts/GameContext";
import { socket } from "../SocketConfig" import { socket } from "../SocketConfig"
import { colorToEmoji, positionToColor } from "../ColorHelper"; import { colorToEmoji, positionToColor, positionToEmoji } from "../ColorHelper";
import { ColorToHexa } from "../model/EnumExtender"; import { ColorToHexa } from "../model/EnumExtender";
import Bot from "../model/Bot"; import Bot from "../model/Bot";
import NodePerson from "../model/Graph/NodePerson";
interface MyGraphComponentProps { interface MyGraphComponentProps {
@ -33,24 +22,25 @@ interface MyGraphComponentProps {
changecptTour: (newcptTour : number) => void changecptTour: (newcptTour : number) => void
addToHistory: (message : string) => void addToHistory: (message : string) => void
solo : boolean solo : boolean
setNetwork: (network: Network) => void
showLast: boolean
} }
let lastAskingPlayer = 0 let lastAskingPlayer = 0
let lastNodeId = -1 let lastNodeId = -1
let first = true let first = true
let askedWrong = false let askedWrong = false
let solo: boolean = true
let mapIndexPersons: Map<number, Person[]> = new Map<number, Person[]>() let mapIndexPersons: Map<number, Person[]> = new Map<number, Person[]>()
let touchedPlayer = -1 let touchedPlayer = -1
let botIndex = -1 let botIndex = -1
let askedWrongBot = false let askedWrongBot = false
let botTurnToCube = false
let lastSocketId= "" let lastSocketId= ""
let firstLap = true let firstLap = true
let cptHistory = 0 let cptHistory = 0
let lastNodes: NodePerson[] = []
const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick, handleShowTurnBar, handleTurnBarTextChange, playerTouched, setPlayerTouched, changecptTour, solo, addToHistory}) => { const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick, handleShowTurnBar, handleTurnBarTextChange, playerTouched, setPlayerTouched, changecptTour, solo, addToHistory, showLast, setNetwork}) => {
let cptTour: number = 0 let cptTour: number = 0
const { indices, indice, person, personNetwork, setNodeIdData, players, askedPersons, setActualPlayerIndexData, room, actualPlayerIndex, turnPlayerIndex, setTurnPlayerIndexData, setWinnerData } = useGame(); const { indices, indice, person, personNetwork, setNodeIdData, players, askedPersons, setActualPlayerIndexData, room, actualPlayerIndex, turnPlayerIndex, setTurnPlayerIndexData, setWinnerData } = useGame();
@ -78,6 +68,25 @@ let cptTour: number = 0
} }
}, [playerTouched]) }, [playerTouched])
useEffect(() => {
const tab: NodePerson[] = []
for(const n of lastNodes.reverse()){
if (!tab.find((node) => node.id == n.id)){
tab.push(n)
if (tab.length > players.length * 2) break
}
}
lastNodes = tab
if (showLast){
socket.emit("opacity activated", socket.id)
}
else{
socket.emit("opacity deactivated", socket.id)
}
}, [showLast])
let playerIndex: number = turnPlayerIndex let playerIndex: number = turnPlayerIndex
let index = 0 let index = 0
for (let i=0; i<players.length; i++){ for (let i=0; i<players.length; i++){
@ -86,7 +95,6 @@ let cptTour: number = 0
break break
} }
} }
let thisPlayerIndex = index
useEffect(() =>{ useEffect(() =>{
if (actualPlayerIndex==0){ if (actualPlayerIndex==0){
@ -121,6 +129,13 @@ let cptTour: number = 0
} }
if(!works){ if(!works){
socket.emit("node checked", personIndex, works, playerIndex, room, nextPlayerIndex) socket.emit("node checked", personIndex, works, playerIndex, room, nextPlayerIndex)
const ind = bot.placeSquare(personNetwork, players)
console.log(lastIndex + " pose carré sur " + personNetwork.getPersons()[ind].getName())
playerIndex = lastIndex + 1
if(playerIndex == players.length){
playerIndex = 0
}
socket.emit("node checked", ind, false, lastIndex, room, playerIndex)
return return
} }
playerIndex ++ playerIndex ++
@ -179,6 +194,7 @@ let cptTour: number = 0
if (first){ if (first){
first = false first = false
if (!solo){ if (!solo){
for(let i = 0; i<indices.length; i++){ for(let i = 0; i<indices.length; i++){
mapIndexPersons.set(i, []) mapIndexPersons.set(i, [])
@ -192,7 +208,7 @@ let cptTour: number = 0
}) })
} }
setActualPlayerIndexData(index) setActualPlayerIndexData(index)
if (playerIndex == thisPlayerIndex){ if (playerIndex == actualPlayerIndex){
handleTurnBarTextChange("À vous de jouer") handleTurnBarTextChange("À vous de jouer")
handleShowTurnBar(true) handleShowTurnBar(true)
} }
@ -215,13 +231,15 @@ let cptTour: number = 0
// Configuration des options du Graphe // Configuration des options du Graphe
const initialOptions = { const initialOptions = {
layout: { layout: {
improvedLayout: true, improvedLayout: true,
hierarchical: { hierarchical: {
enabled: false, enabled: false,
direction: 'LR', // LR (Left to Right) ou autre selon votre préférence direction: 'LR', // LR (Left to Right) ou autre selon votre préférence
sortMethod: 'hubsize' sortMethod: 'hubsize'
} },
//randomSeed: 2
}, },
physics: { physics: {
enabled: true, enabled: true,
@ -233,10 +251,11 @@ let cptTour: number = 0
} }
}; };
const networkData = { nodes: nodes, edges: graph.edges }; const networkData = { nodes: nodes, edges: graph.edges };
const network = new Network(container, networkData, initialOptions); const network = new Network(container, networkData, initialOptions);
setNetwork(network)
if (!solo){ if (!solo){
socket.on("asked all", (id) =>{ socket.on("asked all", (id) =>{
const pers = personNetwork.getPersons().find((p) => p.getId() == id) const pers = personNetwork.getPersons().find((p) => p.getId() == id)
@ -245,10 +264,29 @@ let cptTour: number = 0
} }
}) })
socket.on("opacity activated", () => {
nodes.forEach(node => {
if (!lastNodes.find((n) => n.id == node.id)){
networkData.nodes.update({id: node.id, opacity: 0.2})
}
});
})
socket.on("opacity deactivated", () => {
nodes.forEach(node => {
networkData.nodes.update({id: node.id, opacity: 1})
});
})
socket.on("reset graph", () => {
initialOptions.physics.enabled = true
network.setOptions(initialOptions)
})
socket.on("node checked",(id, works, askedIndex, newPlayerIndex, socketId) => { socket.on("node checked",(id, works, askedIndex, newPlayerIndex, socketId) => {
console.log(newPlayerIndex)
const node = nodes.get().find((n) => id == n.id) const node = nodes.get().find((n) => id == n.id)
if (node!=undefined){ if (node!=undefined){
onNodeClick(false) onNodeClick(false)
playerIndex = newPlayerIndex playerIndex = newPlayerIndex
if (mapIndexPersons.get(askedIndex)?.find((p) => p.getId() == id) == undefined){ if (mapIndexPersons.get(askedIndex)?.find((p) => p.getId() == id) == undefined){
@ -267,14 +305,15 @@ let cptTour: number = 0
} }
if (!node.label.includes(colorToEmoji(positionToColor(askedIndex), works))){ if (!node.label.includes(colorToEmoji(positionToColor(askedIndex), works))){
networkData.nodes.update({id: id, label: node.label + colorToEmoji(positionToColor(askedIndex), works)}) networkData.nodes.update({id: id, label: node.label + positionToEmoji(askedIndex, works)})
cptHistory++ cptHistory++
if (cptHistory % 2 == 0){ if (cptHistory % 2 == 0){
addToHistory(players[askedIndex].name + " à mis un " + colorToEmoji(positionToColor(askedIndex), works)) lastNodes.push(node)
addToHistory(players[askedIndex].name + " à mis un " + positionToEmoji(askedIndex, works) + " à " + personNetwork.getPersons()[id].getName())
} }
} }
if (playerIndex === thisPlayerIndex){ if (playerIndex === actualPlayerIndex){
handleTurnBarTextChange("À vous de jouer") handleTurnBarTextChange("À vous de jouer")
handleShowTurnBar(true) handleShowTurnBar(true)
} }
@ -297,7 +336,7 @@ let cptTour: number = 0
askedWrongBot=true askedWrongBot=true
handleShowTurnBar(true) handleShowTurnBar(true)
handleTurnBarTextChange("Mauvais choix, posez un carré !") handleTurnBarTextChange("Mauvais choix, posez un carré !")
socket.emit("put grey background", socket.id, thisPlayerIndex) socket.emit("put grey background", socket.id, actualPlayerIndex)
}) })
@ -316,16 +355,16 @@ let cptTour: number = 0
const node = nodes.get().find((n) => nodeId == n.id) const node = nodes.get().find((n) => nodeId == n.id)
if (node != undefined && indice != null){ if (node != undefined && indice != null){
var tester = IndiceTesterFactory.Create(indice) var tester = IndiceTesterFactory.Create(indice)
let maybe = thisPlayerIndex let maybe = actualPlayerIndex
if (tester.Works(pers)){ if (tester.Works(pers)){
playerIndex = playerIndex + 1 playerIndex = playerIndex + 1
if(playerIndex == players.length){ if(playerIndex == players.length){
playerIndex = 0 playerIndex = 0
} }
socket.emit("node checked", nodeId, true, thisPlayerIndex, room, playerIndex) socket.emit("node checked", nodeId, true, actualPlayerIndex, room, playerIndex)
} }
else{ else{
maybe = thisPlayerIndex - 1 maybe = actualPlayerIndex - 1
if(maybe == 0){ if(maybe == 0){
maybe = players.length - 1 maybe = players.length - 1
} }
@ -337,7 +376,7 @@ let cptTour: number = 0
} }
} }
if (index != undefined){ if (index != undefined){
socket.emit("node checked", nodeId, false, thisPlayerIndex, room, index) socket.emit("node checked", nodeId, false, actualPlayerIndex, room, index)
socket.emit("asked wrong", askingPlayer, room) socket.emit("asked wrong", askingPlayer, room)
} }
@ -369,7 +408,7 @@ let cptTour: number = 0
if (personNetwork != null){ if (personNetwork != null){
const tab = mapIndexPersons.get(player) const tab = mapIndexPersons.get(player)
if (tab != undefined){ if (tab != undefined){
if (player != thisPlayerIndex){ if (player != actualPlayerIndex){
for(const person of personNetwork.getPersons().filter((p) => tab.includes(p))){ for(const person of personNetwork.getPersons().filter((p) => tab.includes(p))){
networkData.nodes.update({id: person.getId(), color: "#808080"}) networkData.nodes.update({id: person.getId(), color: "#808080"})
} }
@ -392,7 +431,7 @@ let cptTour: number = 0
const node = nodes.get().find((n) => pers.getId() == n.id) const node = nodes.get().find((n) => pers.getId() == n.id)
if (node != undefined){ if (node != undefined){
for(let i=0; i<players.length; i++){ for(let i=0; i<players.length; i++){
if (node.label.includes(colorToEmoji(positionToColor(i), false)) || !tester.Works(pers)){ if (node.label.includes(positionToEmoji(i, false)) || !tester.Works(pers)){
tabNodes.push(node) tabNodes.push(node)
break break
} }
@ -407,7 +446,28 @@ let cptTour: number = 0
}) })
socket.on("end game", (winnerIndex) =>{ socket.on("end game", (winnerIndex) =>{
setNodeIdData(-1)
setActualPlayerIndexData(-1)
setLastIndex(-1)
setPlayerTouched(-1)
setWinnerData(players[winnerIndex]) setWinnerData(players[winnerIndex])
first = true
cptHistory = 0
askedWrong=false
askedWrongBot=false
socket.off("end game")
socket.off("asked all")
socket.off("opacity activated")
socket.off("opacity deactivated")
socket.off("reset graph")
socket.off("node checked")
socket.off("already asked")
socket.off("asked wrong")
socket.off("asked")
socket.off("put correct background")
socket.off("put grey background")
socket.off("put imossible grey")
navigate("/endgame") navigate("/endgame")
}) })
@ -435,6 +495,7 @@ let cptTour: number = 0
// Un nœud a été cliqué // Un nœud a été cliqué
initialOptions.physics.enabled = false; initialOptions.physics.enabled = false;
network.setOptions(initialOptions); network.setOptions(initialOptions);
setNetwork(network)
} }
}); });
@ -449,11 +510,11 @@ let cptTour: number = 0
if (person !== undefined && indice !== null){ if (person !== undefined && indice !== null){
const tester = IndiceTesterFactory.Create(indice) const tester = IndiceTesterFactory.Create(indice)
if (!tester.Works(person) && !askedPersons.includes(person)){ if (!tester.Works(person) && !askedPersons.includes(person)){
playerIndex = thisPlayerIndex + 1 playerIndex = actualPlayerIndex + 1
if(playerIndex == players.length){ if(playerIndex == players.length){
playerIndex = 0 playerIndex = 0
} }
socket.emit("node checked", params.nodes[0], false, thisPlayerIndex, room, playerIndex) socket.emit("node checked", params.nodes[0], false, actualPlayerIndex, room, playerIndex)
socket.emit("put correct background", socket.id) socket.emit("put correct background", socket.id)
touchedPlayer=-1 touchedPlayer=-1
askedPersons.push(person) askedPersons.push(person)
@ -474,10 +535,12 @@ let cptTour: number = 0
nextPlayerIndex = 0 nextPlayerIndex = 0
} }
socket.emit("node checked", params.nodes[0], true, touchedPlayer, room, nextPlayerIndex) socket.emit("node checked", params.nodes[0], true, touchedPlayer, room, nextPlayerIndex)
setPlayerTouched(-1)
} }
else{ else{
socket.emit("node checked", params.nodes[0], false, touchedPlayer, room, actualPlayerIndex) socket.emit("node checked", params.nodes[0], false, touchedPlayer, room, actualPlayerIndex)
socket.emit("asked wrong", players[actualPlayerIndex]) socket.emit("asked wrong", players[actualPlayerIndex])
setPlayerTouched(-1)
} }
} }
} }
@ -486,8 +549,9 @@ let cptTour: number = 0
console.log(touchedPlayer) console.log(touchedPlayer)
socket.emit("ask player", params.nodes[0], players[touchedPlayer].id, players.find((p) => p.id === socket.id, actualPlayerIndex)) socket.emit("ask player", params.nodes[0], players[touchedPlayer].id, players.find((p) => p.id === socket.id, actualPlayerIndex))
socket.emit("put correct background", socket.id) socket.emit("put correct background", socket.id)
touchedPlayer=-1
setPlayerTouched(-1)
} }
touchedPlayer=-1
} }
} }
else if(playerIndex == actualPlayerIndex && touchedPlayer==players.length){ else if(playerIndex == actualPlayerIndex && touchedPlayer==players.length){
@ -516,9 +580,11 @@ let cptTour: number = 0
socket.emit("node checked", params.nodes[0], true, playerIndex, room, actualPlayerIndex) socket.emit("node checked", params.nodes[0], true, playerIndex, room, actualPlayerIndex)
} }
if(!works){ if(!works){
socket.emit("node checked", params.nodes[0], works, playerIndex, room, nextPlayerIndex) socket.emit("node checked", params.nodes[0], works, playerIndex, room, actualPlayerIndex)
socket.emit("put correct background", socket.id) socket.emit("put correct background", socket.id)
socket.emit("asked wrong", players[actualPlayerIndex])
touchedPlayer=-1 touchedPlayer=-1
setPlayerTouched(-1)
return return
} }
if (i == players.length - 1){ if (i == players.length - 1){
@ -531,6 +597,7 @@ let cptTour: number = 0
i++ i++
} }
touchedPlayer=-1 touchedPlayer=-1
setPlayerTouched(-1)
socket.emit("put correct background", socket.id) socket.emit("put correct background", socket.id)
await delay(1000) await delay(1000)
socket.emit("end game", actualPlayerIndex, room) socket.emit("end game", actualPlayerIndex, room)
@ -548,8 +615,8 @@ let cptTour: number = 0
const test = tester.Works(person) const test = tester.Works(person)
const node = nodes.get().find((n) => params.nodes[0] == n.id) const node = nodes.get().find((n) => params.nodes[0] == n.id)
if (node!=undefined){ if (node!=undefined){
if (!node.label.includes(colorToEmoji(positionToColor(index), test))){ if (!node.label.includes(positionToEmoji(index, test))){
networkData.nodes.update({id: params.nodes[0], label: node.label + colorToEmoji(positionToColor(index), test)}) networkData.nodes.update({id: params.nodes[0], label: node.label + positionToEmoji(index, test)})
await delay(500) await delay(500)
if(!test){ if(!test){
works = false works = false

@ -1,31 +1,69 @@
import React from 'react'; import React from 'react';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
/* img */
import BotPDP from '../res/img/bot.png';
import PersonPDP from '../res/img/Person.png';
import Trash from '../res/icon/trash.png';
/* style */
import '../Style/Global.css'; import '../Style/Global.css';
import Bot from '../res/img/bot.png';
/* Boostrap */ /* Boostrap */
import ToggleButton from 'react-bootstrap/ToggleButton'; import ToggleButton from 'react-bootstrap/ToggleButton';
import ToggleButtonGroup from 'react-bootstrap/ToggleButtonGroup'; import ToggleButtonGroup from 'react-bootstrap/ToggleButtonGroup';
import Button from 'react-bootstrap/Button';
/* model */
import Player from '../model/Player';
import Bot from '../model/Bot';
/* server */
import { socket } from '../SocketConfig';
interface MyPlayerItemListProps {
player : Player,
room : string | null
}
//@ts-ignore //@ts-ignore
function PlayerItemList({ pdp, name, id}) { const PlayerItemList:React.FC<MyPlayerItemListProps> =({ player, room }) => {
const isBot = pdp === Bot; // const isBot = pdp === Bot;
let pdp;
const isBot = player instanceof Bot;
isBot ? pdp = BotPDP : pdp = PersonPDP;
const delBot = () => {
if (isBot && room != null) {
console.log(room);
socket.emit("bot deleted", player, room);
}
};
return ( return (
<div className='item-horizontal-div-container'> <div className='item-horizontal-div-container'>
<div className='item-horizontal-div'> <div className='item-horizontal-div'>
<img src={pdp} alt='player-image' height='100' width='100' /> <div>
<h4>{name}</h4> <img src={pdp} alt='player-image' height='100' width='100' />
<h4>{player.name}</h4>
</div>
{isBot && (
<Button className='suprButton' onClick={delBot} variant="danger">
<img src={Trash} alt='Trash-icon' height='30' width='30' />
</Button>
)}
</div> </div>
{isBot && ( {isBot && (
<ToggleButtonGroup type='radio' name={`options-${id}`} defaultValue={1}> <ToggleButtonGroup type='radio' name={`options-${player.id}`} defaultValue={1}>
<ToggleButton id={`tbg-radio-1-${id}`} value={1}> <ToggleButton id={`tbg-radio-1-${player.id}`} value={1}>
Facile Facile
</ToggleButton> </ToggleButton>
<ToggleButton id={`tbg-radio-2-${id}`} value={2}> <ToggleButton id={`tbg-radio-2-${player.id}`} value={2}>
Intermédiaire Intermédiaire
</ToggleButton> </ToggleButton>
<ToggleButton id={`tbg-radio-3-${id}`} value={3}> <ToggleButton id={`tbg-radio-3-${player.id}`} value={3}>
Fort Fort
</ToggleButton> </ToggleButton>
</ToggleButtonGroup> </ToggleButtonGroup>

@ -32,7 +32,7 @@ const ScoreBoard: React.FC<{ Player: PlayerProps }> = ({ Player }) => {
// <div className='LeaderBoardiv'> // <div className='LeaderBoardiv'>
<div className='LeaderBoardiv'> <div className='LeaderBoardiv'>
<Tabs style={{width:"100%"}} <Tabs style={{width:"100%"}}
defaultActiveKey="profile" defaultActiveKey="daily"
id="ScoreBoard" id="ScoreBoard"
className="mb-3"> className="mb-3">
<Tab eventKey="perso" title="Vos Stats" disabled = { !Player.pseudo.startsWith("Guest_") ? false : true}> <Tab eventKey="perso" title="Vos Stats" disabled = { !Player.pseudo.startsWith("Guest_") ? false : true}>

@ -29,6 +29,7 @@ interface GameContextProps {
setRoomData: (newRoom: string) => void; setRoomData: (newRoom: string) => void;
setOnlyFalseData: (newOnlyFalse: boolean) => void setOnlyFalseData: (newOnlyFalse: boolean) => void
setWinnerData: (winner: Player) => void setWinnerData: (winner: Player) => void
reset: () => void
} }
const GameContext = createContext<GameContextProps | undefined>(undefined); const GameContext = createContext<GameContextProps | undefined>(undefined);
@ -101,8 +102,22 @@ export const GameProvider: React.FC<GameProviderProps> = ({ children }) => {
setWinner(winner) setWinner(winner)
} }
const reset = () => {
setIndices([])
setActualPlayerIndex(-1)
setAskedPersons([])
setPlayers([])
setPerson(null)
setPersonNetwork(null)
setRoom("")
setWinner(null)
setTurnPlayerIndex(-1)
setNodeId(-1)
setIndice(null)
}
return ( return (
<GameContext.Provider value={{ indices, setIndicesData, indice, setIndiceData, person, setPersonData, personNetwork, setPersonNetworkData, players, setPlayersData, nodeId, setNodeIdData, askedPersons, setAskedPersonsData, actualPlayerIndex, setActualPlayerIndexData, turnPlayerIndex, setTurnPlayerIndexData, room, setRoomData, onlyFalse, setOnlyFalseData, winner, setWinnerData }}> <GameContext.Provider value={{ indices, setIndicesData, indice, setIndiceData, person, setPersonData, personNetwork, setPersonNetworkData, players, setPlayersData, nodeId, setNodeIdData, askedPersons, setAskedPersonsData, actualPlayerIndex, setActualPlayerIndexData, turnPlayerIndex, setTurnPlayerIndexData, room, setRoomData, onlyFalse, setOnlyFalseData, winner, setWinnerData, reset }}>
{children} {children}
</GameContext.Provider> </GameContext.Provider>
); );

@ -33,10 +33,50 @@
align-items: center; align-items: center;
} }
.playerContainer { .playersContainer {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
padding-left: "5px"; /* 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{
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);
}

@ -26,6 +26,12 @@ import { useGame } from '../Contexts/GameContext';
function EndGame() { function EndGame() {
const {reset} = useGame()
const resetAll = () => {
reset()
}
const {winner, person, players, indices} =useGame() const {winner, person, players, indices} =useGame()
console.log(winner) console.log(winner)
let indice = indices[0] let indice = indices[0]
@ -34,7 +40,17 @@ function EndGame() {
indice = indices[index] indice = indices[index]
} }
let losingPlayers;
if (winner != null) {
losingPlayers = players.filter(player => player.id !== winner.id);
} else {
losingPlayers = players;
}
const theme = useTheme(); const theme = useTheme();
return ( return (
<div> <div>
<div className="head"> <div className="head">
@ -44,28 +60,25 @@ function EndGame() {
</header> </header>
</div> </div>
<div className='winner'> <div className='winner'>
<img src={Person} width='300' height='300'/> <img src={Person} width='250' height='250'/>
<h3>{indice.ToString("fr")}</h3> <h3 className='indiceDisplay'>{indices[players.findIndex((p) => p.id == winner?.id)].ToString("fr")}</h3>
</div> </div>
<div className='bottom'> <div className='bottom'>
<div className='centerDivH'> <div className='centerDivH' onClick={resetAll}>
<BigButtonNav dest="/play" img={Leave}/> <BigButtonNav dest="/play" img={Leave}/>
</div> </div>
<ul className='centerDivH'> <div className="losingPlayersContainer">
{ {losingPlayers.map((player, index) => (
players.map((player, index) => ( <div className="playerContainer" key={index}>
<div className="playerContainer"> {player.id !== winner?.id && (
{player.id!=winner?.id && <div>
<> <PersonStatus img={Person} state={Person} key={index} name={player.name} playerTouched={1} setPlayerTouched={() => {}} index={index} showCircle={false}/>
<PersonStatus img={Person} state={Person} key={index} name={player.name} playerTouched={1} setPlayerTouched={() => {}} index={index} showCircle={false}/> <h6 className='indiceDisplay'>{indices[players.findIndex((p) => p.id == player?.id)].ToString("fr")}</h6>
<h5 style={{width: 50}}>{indices[players.findIndex((p) => p.id == player?.id)].ToString("fr")}</h5> </div>
</> )}
}
</div> </div>
)) ))}
} </div>
</ul>
<div className='centerDivH'> <div className='centerDivH'>
<BigButtonNav dest="/lobby" img={Replay}/> <BigButtonNav dest="/lobby" img={Replay}/>
</div> </div>

@ -32,6 +32,22 @@
right: 10px; right: 10px;
} }
.opacityDiv{
z-index: 1;
position: absolute;
top: 100px;
right: 10px;
}
.resetDiv{
right: 10px;
display: flex;
justify-content: center;
align-items: center;
}
#graphDiv{ #graphDiv{
display: flex; display: flex;

@ -1,5 +1,6 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import Switch from "react-switch"; import Switch from "react-switch";
import {saveAs} from "file-saver"
/* Style */ /* Style */
import "./InGame.css" import "./InGame.css"
@ -20,6 +21,10 @@ import Info from "../res/icon/infoGreen.png";
import Check from "../res/icon/checkboxGreen.png"; import Check from "../res/icon/checkboxGreen.png";
import Alpha from "../res/GreekLetters/alphaW.png"; import Alpha from "../res/GreekLetters/alphaW.png";
import MGlass from "../res/icon/magnifying-glass.png"; import MGlass from "../res/icon/magnifying-glass.png";
import Download from "../res/icon/download.png"
import Reset from "../res/icon/reset.png";
import Oeye from "../res/icon/eye.png";
import Ceye from "../res/icon/hidden.png";
/* nav */ /* nav */
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
@ -31,12 +36,16 @@ import Offcanvas from 'react-bootstrap/Offcanvas';
/* Model */ /* Model */
import Stub from '../model/Stub'; import Stub from '../model/Stub';
import { HiLanguage } from 'react-icons/hi2'; import { HiLanguage } from 'react-icons/hi2';
import { Nav, NavDropdown } from 'react-bootstrap'; import { Nav, NavDropdown, Spinner } from 'react-bootstrap';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import Color from '../model/Color'; import Color from '../model/Color';
import { useGame } from '../Contexts/GameContext'; import { useGame } from '../Contexts/GameContext';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { NavLink } from 'react-router-dom'; import { NavLink } from 'react-router-dom';
import { last } from 'lodash';
import { socket } from '../SocketConfig';
import { Network } from 'vis-network';
import generateLatexCode from '../Script/LatexScript';
//@ts-ignore //@ts-ignore
const InGame = ({locale, changeLocale}) => { const InGame = ({locale, changeLocale}) => {
@ -55,12 +64,18 @@ const InGame = ({locale, changeLocale}) => {
//* Historique //* Historique
const [history, setHistory] = useState<string[]>([]); const [history, setHistory] = useState<string[]>([]);
const [showLast, setShowLast] = useState(false)
// Fonction pour ajouter un élément à l'historique // Fonction pour ajouter un élément à l'historique
const addToHistory = (message: string) => { const addToHistory = (message: string) => {
setHistory(prevHistory => [...prevHistory, message]); setHistory(prevHistory => [...prevHistory, message]);
}; };
const setShowLastData = () =>{
setLastVisible(!showLast);
setShowLast(!showLast);
}
useEffect(() => { useEffect(() => {
const historyContainer = document.getElementById('history-container'); const historyContainer = document.getElementById('history-container');
if (historyContainer) { if (historyContainer) {
@ -69,13 +84,19 @@ const InGame = ({locale, changeLocale}) => {
}, [history]); }, [history]);
const {personNetwork, person, indices} = useGame()
const [showChoiceBar, setShowChoiceBar] = useState(false); const [showChoiceBar, setShowChoiceBar] = useState(false);
const [showTurnBar, setShowTurnBar] = useState(false); const [showTurnBar, setShowTurnBar] = useState(false);
const [turnBarText, setTurnBarText] = useState(""); const [turnBarText, setTurnBarText] = useState("");
const [playerTouched, setPlayerTouched] = useState(-2) const [playerTouched, setPlayerTouched] = useState(-2)
const [network, setNetwork] = useState<Network | null>(null)
const setNetworkData = (network: Network) => {
setNetwork(network)
}
const handleNodeClick = (shouldShowChoiceBar: boolean) => { const handleNodeClick = (shouldShowChoiceBar: boolean) => {
setShowChoiceBar(shouldShowChoiceBar); setShowChoiceBar(shouldShowChoiceBar);
}; };
@ -93,6 +114,24 @@ const InGame = ({locale, changeLocale}) => {
setTurnBarText(newTurnBarText) setTurnBarText(newTurnBarText)
} }
const generateTEX = () => {
if (network != null && personNetwork != null && person != null){
const tex = generateLatexCode(personNetwork, person, indices, network)
const blob = new Blob([tex], { type: 'application/x-latex;charset=utf-8' });
// Utiliser FileSaver pour télécharger le fichier
saveAs(blob, 'socialGraph.tex');
}
}
const resetGraph = () => {
setisLoading(true);
socket.emit("reset graph", socket.id)
setTimeout(() => {
setisLoading(false);
}, 2000);
}
/* offcanvas */ /* offcanvas */
//? faire une fonction pour close et show en fonction de l'etat du canva ? //? faire une fonction pour close et show en fonction de l'etat du canva ?
//? comment faire pour eviter la recopie de tout le code a chaque canvas boostrap ? //? comment faire pour eviter la recopie de tout le code a chaque canvas boostrap ?
@ -110,6 +149,11 @@ const InGame = ({locale, changeLocale}) => {
const [cptTour, setcptTour] = useState(0); const [cptTour, setcptTour] = useState(0);
const [LastVisible, setLastVisible] = useState(false);
const [isLoading, setisLoading] = useState(false);
//@ts-ignore //@ts-ignore
const changecptTour = (newcptTour) => { const changecptTour = (newcptTour) => {
setcptTour(newcptTour); setcptTour(newcptTour);
@ -142,6 +186,11 @@ const InGame = ({locale, changeLocale}) => {
} }
}; };
const changeVisibility = () => {
setLastVisible(!LastVisible);
}
const eye = LastVisible ? Oeye : Ceye; //icon que l'on affiche pour l'oeil : fermé ou ouvert.
/* Windows open */ /* Windows open */
//@ts-ignore //@ts-ignore
const openInNewTab = (url) => { //! avec url ==> dangereux const openInNewTab = (url) => { //! avec url ==> dangereux
@ -149,7 +198,7 @@ const InGame = ({locale, changeLocale}) => {
}; };
const [SwitchEnabled, setSwitchEnabled] = useState(false) const [SwitchEnabled, setSwitchEnabled] = useState(false)
const indices = Stub.GenerateIndice() const allIndices = Stub.GenerateIndice()
const { indice, players } = useGame(); const { indice, players } = useGame();
@ -164,7 +213,9 @@ const InGame = ({locale, changeLocale}) => {
addToHistory={addToHistory} addToHistory={addToHistory}
solo={IsSolo} solo={IsSolo}
setPlayerTouched={handleSetPlayerTouched} setPlayerTouched={handleSetPlayerTouched}
playerTouched={playerTouched}/> playerTouched={playerTouched}
setNetwork={setNetworkData}
showLast={showLast}/>
</div> </div>
@ -195,7 +246,33 @@ const InGame = ({locale, changeLocale}) => {
</button> </button>
</div> </div>
<div className='menuGame'> <div className='menuGame'>
<div className='resetDiv'>
<button className='button'
style={{
backgroundColor: theme.colors.tertiary,
borderColor: theme.colors.secondary
}}
onClick={resetGraph}>
{
isLoading ? (
<Spinner animation="grow" />
)
: (
<img src={Reset} alt="paramètres" height='40'/>
)
}
</button>
</div>
{/* <Link to='/info#indice-possible' target='_blank'> {/* <Link to='/info#indice-possible' target='_blank'>
//? redirection impossible apparament (securité des navigateur //? redirection impossible apparament (securité des navigateur
*/} */}
@ -229,6 +306,22 @@ const InGame = ({locale, changeLocale}) => {
}}> }}>
<img src={MGlass} alt="indice" height="40"/> <img src={MGlass} alt="indice" height="40"/>
</button> </button>
<button className='button' onClick={setShowLastData}
style={{
backgroundColor: theme.colors.tertiary,
borderColor: theme.colors.secondary
}}>
<img src={ eye } alt="indice" height="40"/>
</button>
<button className='button' onClick={generateTEX}
style={{
backgroundColor: theme.colors.tertiary,
borderColor: theme.colors.secondary
}}>
<img src={Download} alt="indice" height="40"/>
</button>
</div> </div>
{/* {/*
@ -243,10 +336,12 @@ const InGame = ({locale, changeLocale}) => {
</Offcanvas.Body> </Offcanvas.Body>
</Offcanvas> </Offcanvas>
*/} */}
<div className='playerlistDiv'>
<PlayerList players={players} setPlayerTouched={handleSetPlayerTouched} playerTouched={playerTouched} />
</div>
{ !IsSolo &&
<div className='playerlistDiv'>
<PlayerList players={players} setPlayerTouched={handleSetPlayerTouched} playerTouched={playerTouched} />
</div>
}
<Offcanvas show={show} <Offcanvas show={show}
onHide={handleClose} onHide={handleClose}

@ -27,7 +27,7 @@
.player-board{ .player-board{
height: 100%; height: 100%;
width: max-content; width: 800px;
background-color: rgb(243, 241, 235); background-color: rgb(243, 241, 235);
border-radius: 20px; border-radius: 20px;

@ -45,6 +45,10 @@ function Lobby() {
socket.emit("lobby joined", room, new EasyBot("botId" + Math.floor(Math.random() * 1000), "Bot" + Math.floor(Math.random() * 100)).toJson()) socket.emit("lobby joined", room, new EasyBot("botId" + Math.floor(Math.random() * 1000), "Bot" + Math.floor(Math.random() * 100)).toJson())
} }
// function delBot(selectedBot: Bot){
// }
useEffect(() => { useEffect(() => {
if (first){ if (first){
first=false first=false
@ -81,6 +85,8 @@ function Lobby() {
setIndicesData(choosenIndices) setIndicesData(choosenIndices)
first = true first = true
gameStarted = true gameStarted = true
socket.off("player left")
socket.off("new player")
navigate('/game?solo=false'); navigate('/game?solo=false');
}); });
@ -92,25 +98,12 @@ function Lobby() {
setPlayersData(tmpTab) setPlayersData(tmpTab)
}) })
socket.on("player left", (tab, socketId) => { socket.on("player left", (tab, i) => {
if (gameStarted){ const tmpTab: Player[] = []
const i = players.findIndex((p) => p.id == socketId) for (const p of tab){
if (i != undefined){ tmpTab.push(JSONParser.JSONToPlayer(p))
let player = players[i]
player = new EasyBot("125", "BOT125")
if (player instanceof Bot){
player.indice = indices[i]
}
}
}
else{
const tmpTab: Player[] = []
for (const p of tab){
tmpTab.push(JSONParser.JSONToPlayer(p))
}
setPlayersData(tmpTab)
} }
const index = players setPlayersData(tmpTab)
}) })
const [codeShowed, setCodeShowed] = useState(true); const [codeShowed, setCodeShowed] = useState(true);
@ -140,7 +133,8 @@ function Lobby() {
</div> </div>
{/* //! voir pour la gestion avec un liste, utilisateur avec le "+ (vous)" et les pdp avec les lettres grecs (?)*/} {/* //! voir pour la gestion avec un liste, utilisateur avec le "+ (vous)" et les pdp avec les lettres grecs (?)*/}
{players.map((player, index) => ( {players.map((player, index) => (
<PlayerItemList key={player.id} pdp={PersonImg} name={player.name} id={player.id}/> // <PlayerItemList key={player.id} pdp={PersonImg} name={player.name} id={player.id}/>
<PlayerItemList key={player.id} player={player} room={room}/>
))} ))}
<div className='centerButton'> <div className='centerButton'>
<button className='button' onClick={addBot} <button className='button' onClick={addBot}

@ -0,0 +1,95 @@
import PersonNetwork from "../model/PersonsNetwork";
import Person from "../model/Person";
import GenerateNetwork from "../model/NetworkGenerator";
import NetworkGenerator from "../model/NetworkGenerator";
import fs from 'fs';
import Stub from "../model/Stub";
import GameCreator from "../model/GameCreator";
import Indice from "../model/Indices/Indice";
import { ColorToString, SportToString } from "../model/EnumExtender";
import GraphCreator from "../model/Graph/GraphCreator";
import { DataSet, Network } from "vis-network";
function generateLatexCode(personsNet : PersonNetwork, choosenPerson : Person, choosenIndices : Indice[], network: Network): string {
let latexCode = "";
//*Setup
latexCode += "\\documentclass[11pt]{article}\n"
latexCode += "\\usepackage{fullpage}\n"
latexCode += "\\usepackage{times}\n"
latexCode += "\\usepackage{tikz}\n"
latexCode += "\\usepackage{paralist}\n"
latexCode += "\\usepackage{geometry}\n"
latexCode += "\\usetikzlibrary {shapes.multipart}\n"
latexCode += "\\geometry{margin=0.5cm}\n"
latexCode += "\\newcommand{\\Basketball}{\\includegraphics[width=.5cm]{ballon-de-basket.png}}\n"
latexCode += "\\newcommand{\\Football}{\\includegraphics[width=.4cm]{ballon-de-foot.png}}\n"
latexCode += "\\newcommand{\\Bowling}{\\includegraphics[width=.5cm]{bowling.png}}\n"
latexCode += "\\newcommand{\\Baseball}{\\includegraphics[width=.5cm]{baseball.png}}\n"
latexCode += "\\newcommand{\\Tennis}{\\includegraphics[width=.5cm]{tennis.png}}\n"
//** Header
latexCode+= "\\begin{document}\n"
latexCode+= "\\thispagestyle{empty}\n"
latexCode+= "Voici le graphe de SocialGraphe\n"
latexCode+= "\\begin{center}\n"
latexCode+= "\\begin{tikzpicture}[scale=.17]\n"
personsNet.getPersons().forEach((person, index) => {
var nodesData = network.getPositions();
// Obtenir les coordonnées du nœud
const nodeId = person.getId().toString();
const position = nodesData[nodeId];
if (position) {
const x = (position.x / 9).toFixed(2); // Arrondir à 2 décimales
const y = (position.y / 9).toFixed(2);
latexCode += ` \\node[draw, circle split, align=center] (${person.getId()}) at (${x},${y}) { ${person.getName()} \\\\ ${person.getAge()} \\nodepart{lower}`;
latexCode += `${ColorToString(person.getColor(), "fr")} \\\\`
person.getSports().forEach((sport) => { latexCode += ` \\${SportToString(sport, 'fr')}{}` });
latexCode += "};\n";
} else {
console.error(`Les coordonnées du nœud ${nodeId} ne sont pas disponibles.`);
}
});
personsNet.getPersons().forEach((person) => {
person.getFriends().forEach((friend) => {
latexCode += ` \\draw (${person.getId()}) -- (${friend.getId()});\n`;
});
console.log(person.getFriends().length);
});
latexCode += "\\end{tikzpicture}\n";
latexCode += "\\end{center}\n";
//* Zone d'énoncé :
latexCode += "\n\n\\paragraph{Première énigme}\n"
latexCode += "Trouver qui est le coupable avec les indices suivants.\n"
latexCode += "\\begin{compactitem}\n"
choosenIndices.forEach((indice, index) => {
latexCode += `\\item Indice ${index + 1} : ${indice.ToString('fr')}.\n`
})
latexCode += "\\end{compactitem}\n"
//* Solution
latexCode += "% Solution : " + choosenPerson.getName() + "\n";
latexCode += "\\end{document}\n"
return latexCode
}
export default generateLatexCode

@ -1,6 +1,6 @@
import { io } from "socket.io-client"; import { io } from "socket.io-client";
const socket = io("http://172.20.10.4:3002"); const socket = io("http://localhost:3002");
export {socket} export {socket}

@ -22,12 +22,32 @@
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
justify-content: space-between;
background-color:#fff; background-color:#fff;
border-radius: 15px; border-radius: 15px;
width: 500px; width: 500px;
margin: 10px 20px; margin: 10px 20px;
} }
.item-horizontal-div div{
display: flex;
align-items: center;
}
.delButtonDiv{
display: flex;
justify-content: end;
}
.suprButton{
margin: auto 50px;
border: solid 1px darkred;
border-radius: 10px;
background-color: red;
}
.statusDiv{ .statusDiv{
/* background-color: #A7E2DC; */ /* background-color: #A7E2DC; */
border-radius: 15px; border-radius: 15px;

@ -1,7 +1,7 @@
// theme.js // theme.js
const theme = { const theme = {
colors: { colors: {
primary: '#7AA3F4', primary: '#0064E0',
secondary: '#0052B8', secondary: '#0052B8',
tertiary: '#7aa3f4', //* Pour les boutons de l'interface. tertiary: '#7aa3f4', //* Pour les boutons de l'interface.
text: '#fff' text: '#fff'

@ -43,11 +43,11 @@
"and": "and", "and": "and",
"or": "or", "or": "or",
"or_sport": "and/or", "or_sport": "or",
"age_indice_start": "The suspect is between", "age_indice_start": "The suspect is between",
"age_indice_more_start": "The suspect is older than or", "age_indice_more_start": "The suspect is at least",
"age_indice_end": "years old", "age_indice_end": "years old",
"color_edges_start": "The suspect has at least one friend with", "color_edges_start": "The suspect has at least one friend with",

@ -43,10 +43,10 @@
"and": "et", "and": "et",
"or": "ou", "or": "ou",
"or_sport": "et/ou du", "or_sport": "ou du",
"age_indice_start": "Le suspect a entre", "age_indice_start": "Le suspect a entre",
"age_indice_more_start": "Le suspect a ou a plus de", "age_indice_more_start": "Le suspect a au moins",
"age_indice_end": "ans", "age_indice_end": "ans",
"color_edges_start": "Le suspect a au moins un ami avec les cheveux", "color_edges_start": "Le suspect a au moins un ami avec les cheveux",

@ -74,6 +74,7 @@ class EdgesCreator{
} }
CreateAllEdges(personNetwork: PersonNetwork, choosenPerson: Person, indices: Indice[]){ CreateAllEdges(personNetwork: PersonNetwork, choosenPerson: Person, indices: Indice[]){
const nbTryConnex = 10
const test = new Map<number, number>() const test = new Map<number, number>()
const tabEdgesSize: number[] = [] const tabEdgesSize: number[] = []
for (let i = 0; i<personNetwork.getPersons().length / 4; i++){ for (let i = 0; i<personNetwork.getPersons().length / 4; i++){
@ -100,6 +101,48 @@ class EdgesCreator{
this.CreateNotWorkingEdge(personNetwork, p, choosenPerson, indices, test) this.CreateNotWorkingEdge(personNetwork, p, choosenPerson, indices, test)
} }
}); });
let [isConnected, connectedNodes, unconnectedNodes] = personNetwork.getConnectivityDetails()
let i = 0
while(!isConnected){
if (i==nbTryConnex){
return
}
for(const pers of unconnectedNodes){
let canBreak = false
for(const newFriend of connectedNodes){
if (pers != newFriend && newFriend!=choosenPerson){
let testEdgeWork1 = 0
let testEdgeWork2 = 0
const p1 = cloneDeep(pers);
const personEdge = cloneDeep(newFriend);
p1.addFriend(personEdge)
personEdge.addFriend(p1)
indices.forEach((indice) => {
const tester = IndiceTesterFactory.Create(indice)
if (tester.Works(p1)){
testEdgeWork1 ++
}
if (tester.Works(personEdge)){
testEdgeWork2 ++
}
});
if (testEdgeWork1 < indices.length && testEdgeWork2 < indices.length){
pers.addFriend(newFriend)
newFriend.addFriend(pers)
canBreak = true
break
}
}
}
if (canBreak){
break
}
}
[isConnected, connectedNodes, unconnectedNodes] = personNetwork.getConnectivityDetails()
i++
}
} }
} }

@ -0,0 +1,11 @@
class NodeColor{
public background: string
public border: string
constructor(color: string, border: string){
this.background=color
this.border=border
}
}
export default NodeColor

@ -8,6 +8,8 @@ class NodePerson{
public color: string public color: string
public font: Font public font: Font
public shape: string public shape: string
public shadow: boolean = true
public opacity: number = 1
constructor(id: number, label: string, color: Color, font: Font, shape: string){ constructor(id: number, label: string, color: Color, font: Font, shape: string){
this.id=id this.id=id

@ -27,7 +27,7 @@ class NetworkGenerator{
} }
*/ */
for(let i = 0; i < nbPerson/3; i++){ for(let i = 0; i < nbPerson/3; i++){
const nombreAleatoire = Math.floor(Math.random() * 9) + 12; const nombreAleatoire = Math.floor(Math.random() * 8) + 12;
tabAdo.push(nombreAleatoire) tabAdo.push(nombreAleatoire)
} }
for(let i = 0; i < nbPerson/3; i++){ for(let i = 0; i < nbPerson/3; i++){
@ -35,7 +35,7 @@ class NetworkGenerator{
tabAdulte.push(nombreAleatoire) tabAdulte.push(nombreAleatoire)
} }
for(let i = 0; i < nbPerson/3; i++){ for(let i = 0; i < nbPerson/3; i++){
const nombreAleatoire = Math.floor(Math.random() * 30) + 30; const nombreAleatoire = Math.floor(Math.random() * 40) + 30;
tabVieux.push(nombreAleatoire) tabVieux.push(nombreAleatoire)
} }
@ -53,7 +53,10 @@ class NetworkGenerator{
} }
let sports = [] let sports = []
for (let j = 0; j < 3; j++){ for (let j = 0; j < 3; j++){
if (tmpTabSport.length == 0) tmpTabSport = [...tabSports] if (tmpTabSport.length == 0){
tmpTabSport = [...tabSports]
break
}
const rand = Math.floor(Math.random() * tmpTabSport.length) const rand = Math.floor(Math.random() * tmpTabSport.length)
if (tmpTabSport[rand] != Sport.AUCUN){ if (tmpTabSport[rand] != Sport.AUCUN){
sports.push(tmpTabSport[rand]) sports.push(tmpTabSport[rand])

@ -18,6 +18,41 @@ class PersonNetwork{
addPerson(person: Person){ addPerson(person: Person){
this.persons.push(person) this.persons.push(person)
} }
private dfs(startNode: Person, visited: Set<number>) {
visited.add(startNode.getId());
for (const friend of startNode.getFriends()) {
if (!visited.has(friend.getId())) {
this.dfs(friend, visited);
}
}
}
getConnectivityDetails(): [boolean, Person[], Person[]] {
if (this.persons.length === 0) {
// Si la liste de personnes est vide, le graphe est considéré comme connexe.
return [true, [], []]
}
const visited: Set<number> = new Set();
const connectedNodes: Person[] = [];
// Commencez la recherche en profondeur à partir du premier nœud du réseau.
this.dfs(this.persons[0], visited);
// Obtenez les nœuds connectés.
for (const person of this.persons) {
if (visited.has(person.getId())) {
connectedNodes.push(person);
}
}
// Obtenez les nœuds non connectés.
const unconnectedNodes: Person[] = this.persons.filter(person => !visited.has(person.getId()));
return [unconnectedNodes.length === 0, connectedNodes, unconnectedNodes];
}
} }
export default PersonNetwork export default PersonNetwork

@ -8,4 +8,3 @@ enum Sport {
} }
export default Sport export default Sport

@ -14,14 +14,13 @@ class Stub{
let indice = new NbEdgesIndice(1, 2) let indice = new NbEdgesIndice(1, 2)
let indice1 = new NbEdgesIndice(2, 3) let indice1 = new NbEdgesIndice(2, 3)
let indice2 = new NbEdgesIndice(3, 4) let indice2 = new NbEdgesIndice(3, 4)
let ageIndice = new AgeIndice(4, 0, 14) let ageIndice = new AgeIndice(4, 12, 19)
let ageIndice1 = new AgeIndice(5, 15, 19) let ageIndice1 = new AgeIndice(5, 20, 29)
let ageIndice2 = new AgeIndice(6, 20, 29) let ageIndice2 = new AgeIndice(6, 30, 100000)
let ageIndice3 = new AgeIndice(7, 30, 100000)
let indices: Indice[] = [indice, indice1, indice2, ageIndice, ageIndice1, ageIndice2, ageIndice3] let indices: Indice[] = [indice, indice1, indice2, ageIndice, ageIndice1, ageIndice2]
let test = 8 let test = 7
for (let i: Color=0; i<5; i++){ for (let i: Color=0; i<5; i++){
for (let j: Color=0; j<5; j++){ for (let j: Color=0; j<5; j++){
if (j==i){ if (j==i){
@ -50,13 +49,8 @@ class Stub{
//* Nombre de sport //* Nombre de sport
for (let i=1; i<3; i++){ for (let i=1; i<3; i++){
for (let j=0; j<3; j++){ indices.push(new NbSportIndice(test, [i]))
if (j==i){ test++
continue
}
indices.push(new NbSportIndice(test, [i, j]))
test++
}
} }
return indices return indices

Binary file not shown.

After

Width:  |  Height:  |  Size: 386 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

@ -2225,6 +2225,11 @@
"@types/qs" "*" "@types/qs" "*"
"@types/serve-static" "*" "@types/serve-static" "*"
"@types/file-saver@^2.0.7":
"integrity" "sha512-dNKVfHd/jk0SkR/exKGj2ggkB45MAkzvWCaqLUUgkyjITkGNzH8H+yUwr+BLJUBjZOe9w8X3wgmXhZDRg1ED6A=="
"resolved" "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.7.tgz"
"version" "2.0.7"
"@types/graceful-fs@^4.1.2": "@types/graceful-fs@^4.1.2":
"integrity" "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==" "integrity" "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ=="
"resolved" "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz" "resolved" "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz"
@ -6770,6 +6775,11 @@ fast-glob@^3.2.9, fast-glob@^3.3.0:
"loader-utils" "^2.0.0" "loader-utils" "^2.0.0"
"schema-utils" "^3.0.0" "schema-utils" "^3.0.0"
"file-saver@^2.0.5":
"integrity" "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA=="
"resolved" "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz"
"version" "2.0.5"
"filelist@^1.0.4": "filelist@^1.0.4":
"integrity" "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==" "integrity" "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q=="
"resolved" "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz" "resolved" "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz"

@ -0,0 +1,3 @@
\relax
\@writefile{toc}{\contentsline {paragraph}{Première énigme}{2}{}\protected@file@percent }
\gdef \@abspage@last{2}

Binary file not shown.

@ -0,0 +1,132 @@
\documentclass[11pt]{article}
\usepackage{fullpage}
\usepackage{times}
\usepackage{tikz}
\usepackage{paralist}
\usetikzlibrary {shapes.multipart}
\newcommand{\Basketball}{\includegraphics[width=.5cm]{ballon-de-basket.png}}
\newcommand{\Football}{\includegraphics[width=.4cm]{ballon-de-foot.png}}
\newcommand{\Bowling}{\includegraphics[width=.5cm]{bowling.png}}
\newcommand{\Baseball}{\includegraphics[width=.5cm]{baseball.png}}
\newcommand{\Tennis}{\includegraphics[width=.5cm]{tennis.png}}
\begin{document}
\thispagestyle{empty}
Voici le graphe de SocialGraphe
\begin{center}
\begin{tikzpicture}[scale=.9]
\node[draw, circle split] (0) at (0,0) { Alexander \nodepart{lower} \Football{} \Bowling{}};
\node[draw, circle split] (1) at (4,0) { Wyatt \nodepart{lower} \Baseball{} \Tennis{}};
\node[draw, circle split] (2) at (8,0) { Mia \nodepart{lower} \Basketball{}};
\node[draw, circle split] (3) at (12,0) { William \nodepart{lower} \Baseball{} \Football{}};
\node[draw, circle split] (4) at (16,0) { Zoey \nodepart{lower} \Basketball{} \Bowling{} \Tennis{}};
\node[draw, circle split] (5) at (0,4) { Isabella \nodepart{lower} \Tennis{}};
\node[draw, circle split] (6) at (4,4) { Abigail \nodepart{lower} \Baseball{}};
\node[draw, circle split] (7) at (8,4) { Savannah \nodepart{lower} \Bowling{} \Basketball{} \Football{}};
\node[draw, circle split] (8) at (12,4) { Peyton \nodepart{lower} \Football{}};
\node[draw, circle split] (9) at (16,4) { Alice \nodepart{lower} \Tennis{} \Baseball{}};
\node[draw, circle split] (10) at (0,8) { Sophia \nodepart{lower} \Bowling{} \Basketball{} \Bowling{}};
\node[draw, circle split] (11) at (4,8) { Layla \nodepart{lower} \Tennis{} \Baseball{} \Football{}};
\node[draw, circle split] (12) at (8,8) { Ava \nodepart{lower} \Basketball{}};
\node[draw, circle split] (13) at (12,8) { Harper \nodepart{lower} \Bowling{}};
\node[draw, circle split] (14) at (16,8) { Sebastian \nodepart{lower} \Tennis{} \Basketball{} \Baseball{}};
\node[draw, circle split] (15) at (0,12) { Michael \nodepart{lower} \Football{}};
\node[draw, circle split] (16) at (4,12) { Natalie \nodepart{lower} \Bowling{} \Football{} \Baseball{}};
\node[draw, circle split] (17) at (8,12) { Penelope \nodepart{lower} \Basketball{}};
\node[draw, circle split] (18) at (12,12) { Lily \nodepart{lower} \Tennis{} \Tennis{}};
\node[draw, circle split] (19) at (16,12) { Eleanor \nodepart{lower} \Football{}};
\node[draw, circle split] (20) at (0,16) { Henry \nodepart{lower} \Bowling{} \Basketball{}};
\node[draw, circle split] (21) at (4,16) { Claire \nodepart{lower} \Baseball{} \Basketball{}};
\node[draw, circle split] (22) at (8,16) { Caleb \nodepart{lower} \Baseball{}};
\node[draw, circle split] (23) at (12,16) { Charlotte \nodepart{lower} \Bowling{} \Football{} \Tennis{}};
\node[draw, circle split] (24) at (16,16) { Luke \nodepart{lower} \Football{}};
\node[draw, circle split] (25) at (0,20) { Connor \nodepart{lower} \Baseball{} \Tennis{}};
\node[draw, circle split] (26) at (4,20) { Aiden \nodepart{lower} \Basketball{} \Bowling{} \Tennis{}};
\node[draw, circle split] (27) at (8,20) { Aurora \nodepart{lower} \Football{}};
\node[draw, circle split] (28) at (12,20) { Nathan \nodepart{lower} \Bowling{} \Baseball{}};
\node[draw, circle split] (29) at (16,20) { Aurora \nodepart{lower} \Basketball{}};
\draw (0) -- (11);
\draw (0) -- (13);
\draw (0) -- (18);
\draw (1) -- (13);
\draw (1) -- (24);
\draw (2) -- (22);
\draw (2) -- (16);
\draw (2) -- (9);
\draw (2) -- (6);
\draw (3) -- (4);
\draw (3) -- (20);
\draw (4) -- (28);
\draw (4) -- (3);
\draw (5) -- (17);
\draw (5) -- (15);
\draw (5) -- (24);
\draw (6) -- (2);
\draw (7) -- (17);
\draw (7) -- (24);
\draw (7) -- (22);
\draw (7) -- (11);
\draw (8) -- (25);
\draw (8) -- (21);
\draw (8) -- (24);
\draw (8) -- (11);
\draw (9) -- (2);
\draw (10) -- (25);
\draw (10) -- (26);
\draw (10) -- (27);
\draw (11) -- (0);
\draw (11) -- (7);
\draw (11) -- (8);
\draw (12) -- (20);
\draw (12) -- (27);
\draw (13) -- (0);
\draw (13) -- (1);
\draw (14) -- (15);
\draw (15) -- (5);
\draw (15) -- (14);
\draw (15) -- (20);
\draw (15) -- (17);
\draw (16) -- (2);
\draw (16) -- (26);
\draw (17) -- (5);
\draw (17) -- (7);
\draw (17) -- (15);
\draw (17) -- (20);
\draw (18) -- (0);
\draw (19) -- (23);
\draw (20) -- (3);
\draw (20) -- (12);
\draw (20) -- (15);
\draw (20) -- (17);
\draw (21) -- (8);
\draw (22) -- (2);
\draw (22) -- (7);
\draw (22) -- (23);
\draw (23) -- (19);
\draw (23) -- (22);
\draw (24) -- (1);
\draw (24) -- (5);
\draw (24) -- (7);
\draw (24) -- (8);
\draw (25) -- (8);
\draw (25) -- (10);
\draw (26) -- (10);
\draw (26) -- (16);
\draw (26) -- (29);
\draw (27) -- (10);
\draw (27) -- (12);
\draw (28) -- (4);
\draw (29) -- (26);
\end{tikzpicture}
\end{center}
\paragraph{Première énigme}
Trouver qui est le coupable avec les indices suivants.
\begin{compactitem}
\item Indice 1 : Le suspect pratique au moins du Baseball et/ou du Basketball .
\item Indice 2 : Le suspect pratique 2 ou 1 sport(s).
\item Indice 3 : Le suspect a les cheveux Roux ou Blond .
\item Indice 4 : Le suspect a au moins un ami avec les cheveux Roux .
\end{compactitem}
% Solution : Nathan
\end{document}

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Loading…
Cancel
Save