diff --git a/cryptide_project/DB/socialgraph.db b/cryptide_project/DB/socialgraph.db index 223f093..a2e8950 100644 Binary files a/cryptide_project/DB/socialgraph.db and b/cryptide_project/DB/socialgraph.db differ diff --git a/cryptide_project/server/socket_io/server.js b/cryptide_project/server/socket_io/server.js index ae793dc..1bf3a75 100644 --- a/cryptide_project/server/socket_io/server.js +++ b/cryptide_project/server/socket_io/server.js @@ -25,12 +25,18 @@ io.on('connection', (socket) => { console.log(socket.id); socket.on('network created', (network, person, indices, room, start) =>{ - io.to(room).emit("game created", network, person, indices, start) - map.get(room).started = true - map.get(room).actualPlayer=start - const playerArray = Array.from(map.entries()).map(([key, value]) => ({ key, value })) - const playerJson = JSON.stringify(playerArray); - io.emit("request lobbies", playerJson) + try{ + io.to(room).emit("game created", network, person, indices, start) + map.get(room).started = true + map.get(room).actualPlayer=start + const playerArray = Array.from(map.entries()).map(([key, value]) => ({ key, value })) + const playerJson = JSON.stringify(playerArray); + io.emit("request lobbies", playerJson) + } + catch{ + console.log("error") + } + }); socket.on("give network", (networkPerson, person, indices, start, room, nodes, playerId) => { @@ -145,17 +151,23 @@ io.on('connection', (socket) => { }) socket.on("who plays", (room) => { - if (map.get(room) !== undefined){ - let player = map.get(room).actualPlayer - if (map.get(room).tab[player].type != "User"){ - player = player + 1 - if (player == map.get(room).tab.length){ - player=0 + try{ + if (map.get(room) !== undefined){ + let player = map.get(room).actualPlayer + if (map.get(room).tab[player].type != "User"){ + player = player + 1 + if (player == map.get(room).tab.length){ + player=0 + } } + // console.log(player) + io.to(room).emit("who plays", player, map.get(room).lastWorks) } - // console.log(player) - io.to(room).emit("who plays", player, map.get(room).lastWorks) } + catch{ + + } + }) socket.on("disconnect", () =>{ @@ -216,9 +228,14 @@ io.on('connection', (socket) => { }) socket.on("node checked", (id, works, color, room, playerIndex) =>{ - map.get(room).actualPlayer=playerIndex - map.get(room).lastWorks=works - io.to(room).emit("node checked", id, works, color, playerIndex, socket.id) + try{ + map.get(room).actualPlayer=playerIndex + map.get(room).lastWorks=works + io.to(room).emit("node checked", id, works, color, playerIndex, socket.id) + } + catch{ + console.log("error") + } }) socket.on("put correct background", (id) =>{ diff --git a/cryptide_project/src/App.tsx b/cryptide_project/src/App.tsx index b3fb0a9..886c900 100644 --- a/cryptide_project/src/App.tsx +++ b/cryptide_project/src/App.tsx @@ -43,6 +43,7 @@ import ErrorBoundary from './Error/ErrorBoundary'; import ErrorPage from './Error/ErrorPage'; import DeducCheck from './Pages/DeducCheck'; import {basePath} from "./AdressSetup" +import Tutorial from './Pages/Tutorial'; @@ -68,6 +69,7 @@ function App() { //const location = useLocation(); const hasNavbarVisible = [basePath + "/", basePath + "/login", basePath + "/signup", basePath + "/lobby", basePath + "/endgame", basePath + "/deduc"]//.includes(window.location.pathname); + document.title = "Social Graph"; return ( }> @@ -88,6 +90,7 @@ function App() { } /> }/> } /> + } /> } /> } /> } /> diff --git a/cryptide_project/src/Components/ChoiceBar.tsx b/cryptide_project/src/Components/ChoiceBar.tsx index c4bb3b6..7db97d6 100644 --- a/cryptide_project/src/Components/ChoiceBar.tsx +++ b/cryptide_project/src/Components/ChoiceBar.tsx @@ -19,6 +19,7 @@ const ChoiceBar = () => { async function askEveryone(){ if (nodeId !== null){ + //@ts-ignore const person = personNetwork?.getPersons().find((p) => p.getId() == nodeId) if (person != undefined){ const indiceTester = IndiceTesterFactory.Create(indices[actualPlayerIndex]) diff --git a/cryptide_project/src/Components/GraphContainer.tsx b/cryptide_project/src/Components/GraphContainer.tsx index 1cce9f9..bf76136 100644 --- a/cryptide_project/src/Components/GraphContainer.tsx +++ b/cryptide_project/src/Components/GraphContainer.tsx @@ -41,6 +41,15 @@ interface MyGraphComponentProps { setPlayerIndex: (playerIndex: number) => void importToPdf: boolean setImportToPdf: (imp: boolean) => void + importToJSON: boolean + setImportToJSON: (imp: boolean) => void + + setPutCorrectBackground : (func: () => void) => void + setPutGreyBackground : (func: () => void) => void + setPutImposssibleGrey : (func: () => void) => void + putGreyBackground : () => void + putCorrectBackground : () => void + putImposssibleGrey : () => void } let lastAskingPlayer = 0 @@ -71,7 +80,7 @@ let testTemps = 0 let testFirst = false -const MyGraphComponent: React.FC = ({onNodeClick, handleShowTurnBar, handleTurnBarTextChange, playerTouched, setPlayerTouched, changecptTour, solo, isDaily, isEasy, addToHistory, showLast, setNetwork, setNetworkEnigme, setPlayerIndex, askedWrong, setAskedWrong, importToPdf, setImportToPdf}) => { +const MyGraphComponent: React.FC = ({onNodeClick, handleShowTurnBar, handleTurnBarTextChange, playerTouched, setPlayerTouched, changecptTour, solo, isDaily, isEasy, addToHistory, showLast, setNetwork, setNetworkEnigme, setPlayerIndex, askedWrong, setAskedWrong, importToPdf, setImportToPdf, importToJSON, setImportToJSON, setPutCorrectBackground, setPutGreyBackground, setPutImposssibleGrey, putCorrectBackground, putGreyBackground, putImposssibleGrey}) => { let cptTour: number = 0 //* Gestion du temps : @@ -127,17 +136,17 @@ const MyGraphComponent: React.FC = ({onNodeClick, handleS console.log(playerTouched) if (touchedPlayer == -1){ if (!askedWrongLocal){ - socket.emit("put correct background", socket.id) + putCorrectBackground() } } else if (touchedPlayer < players.length && touchedPlayer>=0){ if(!askedWrongLocal){ - socket.emit("put correct background", socket.id) - socket.emit("put grey background", socket.id, touchedPlayer) + putCorrectBackground() + putGreyBackground() } } else if(touchedPlayer == players.length){ - socket.emit("put imossible grey", socket.id) + putImposssibleGrey() } }, [playerTouched]) @@ -328,6 +337,25 @@ const MyGraphComponent: React.FC = ({onNodeClick, handleS } }, [importToPdf]) + function downloadToJSON(jsonData: any, filename: string) { + const jsonBlob = new Blob([JSON.stringify(jsonData)], {type: 'application/json'}); + const url = URL.createObjectURL(jsonBlob); + const link = document.createElement('a'); + link.download = filename; + link.href = url; + link.click(); + URL.revokeObjectURL(url); + } + + + useEffect(() => { + if (importToJSON){ + setImportToJSON(false) + downloadToJSON(personNetwork, "graph.json") + downloadToJSON(JSON.stringify(indices), "indices.json") + } + }, [importToJSON]) + useEffect(() => { if (personNetwork == null){ return @@ -457,7 +485,6 @@ const MyGraphComponent: React.FC = ({onNodeClick, handleS p.indice=indices[index] p.index=index p.initiateMap(personNetwork) - console.log(p.indice.ToString("fr")) } }) } @@ -468,7 +495,6 @@ const MyGraphComponent: React.FC = ({onNodeClick, handleS bot.indice=indices[i] bot.index=index bot.initiateMap(personNetwork) - console.log(bot.indice.ToString("fr")) } } if (i==playerIndex){ @@ -500,6 +526,7 @@ const MyGraphComponent: React.FC = ({onNodeClick, handleS setPlayerIndex(index) setLastIndex(index) if (actualPlayerIndex==index){ + handleTurnBarTextChange("À vous de jouer") handleShowTurnBar(true) } }) @@ -612,7 +639,8 @@ const MyGraphComponent: React.FC = ({onNodeClick, handleS askedWrongBot=true handleShowTurnBar(true) handleTurnBarTextChange("Mauvais choix, posez un carré !") - socket.emit("put grey background", socket.id, actualPlayerIndex) + touchedPlayer = actualPlayerIndex + putGreyBackgroud() } else{ socket.emit("can't put square", actualPlayerIndex, room) @@ -637,7 +665,7 @@ const MyGraphComponent: React.FC = ({onNodeClick, handleS } else{ handleShowTurnBar(false) - socket.emit("put correct background", socket.id) + putCorrectBackground() } } }) @@ -696,18 +724,22 @@ const MyGraphComponent: React.FC = ({onNodeClick, handleS } } } - - socket.on("put correct background", () =>{ + + const putCorrectBackground = () => { if (personNetwork != null){ for(const person of personNetwork.getPersons()){ networkData.nodes.update({id: person.getId(), color: ColorToHexa(person.getColor())}) } } - }) + }; + + + setPutCorrectBackground(() => putCorrectBackground) - socket.on("put grey background", (player) =>{ + const putGreyBackgroud = () => { if (personNetwork != null){ + const player = touchedPlayer const tab = mapIndexPersons.get(player) if (tab != undefined){ if (player != actualPlayerIndex){ @@ -735,9 +767,11 @@ const MyGraphComponent: React.FC = ({onNodeClick, handleS } } } - }) + }; - socket.on("put imossible grey", ()=>{ + setPutGreyBackground(() => putGreyBackgroud) + + const putGreyImpossible = () => { if (personNetwork != null && indice!=null){ const tabNodes: any = [] const tester = IndiceTesterFactory.Create(indice) @@ -758,7 +792,9 @@ const MyGraphComponent: React.FC = ({onNodeClick, handleS networkData.nodes.update({id: n.id, color: "#808080"}) } } - }) + } + + setPutImposssibleGrey(() => putGreyImpossible) socket.on("end game", (winnerIndex) =>{ if (cptEndgame % 2 == 0){ @@ -815,9 +851,6 @@ const MyGraphComponent: React.FC = ({onNodeClick, handleS 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") socket.off("who plays") navigate(`${basePath}/endgame`) @@ -879,7 +912,7 @@ const MyGraphComponent: React.FC = ({onNodeClick, handleS playerIndex = 0 } socket.emit("node checked", params.nodes[0], false, actualPlayerIndex, room, playerIndex) - socket.emit("put correct background", socket.id) + putCorrectBackground() touchedPlayer=-1 askedPersons.push(person) askedWrongLocal=false @@ -917,7 +950,7 @@ const MyGraphComponent: React.FC = ({onNodeClick, handleS console.log("CE N'EST PAS UN BOT") //@ts-ignore 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) + putCorrectBackground() touchedPlayer=-1 setPlayerTouched(-1) } @@ -951,14 +984,14 @@ const MyGraphComponent: React.FC = ({onNodeClick, handleS } if(!works){ socket.emit("node checked", params.nodes[0], works, playerIndex, room, actualPlayerIndex) - socket.emit("put correct background", socket.id) + putCorrectBackground() socket.emit("asked wrong", players[actualPlayerIndex]) touchedPlayer=-1 setPlayerTouched(-1) return } if (i == players.length - 1){ - socket.emit("put correct background", socket.id) + putCorrectBackground() await delay(1000) socket.emit("end game", actualPlayerIndex, room) return @@ -968,7 +1001,7 @@ const MyGraphComponent: React.FC = ({onNodeClick, handleS } touchedPlayer=-1 setPlayerTouched(-1) - socket.emit("put correct background", socket.id) + putCorrectBackground() await delay(1000) socket.emit("end game", actualPlayerIndex, room) } @@ -977,73 +1010,78 @@ const MyGraphComponent: React.FC = ({onNodeClick, handleS } else{ //@ts-ignore - const person = personNetwork?.getPersons().find((p) => p.getId() == params.nodes[0]) //person sélectionnée - if (person != undefined){ + 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é let index =0 let works = true const statsTime = elapsedTime; for (const i of indices){ const tester = IndiceTesterFactory.Create(i) - const test = tester.Works(person) - //@ts-ignore - const node = nodes.get().find((n) => params.nodes[0] == n.id) + const test = tester.Works(personTest) + //@ts-ignore if (node!=undefined){ - if (!node.label.includes(positionToEmoji(index, test))){ - networkData.nodes.update({id: params.nodes[0], label: node.label + positionToEmoji(index, test)}) - await delay(500) - if(!test){ - works = false - } - if (index == indices.length - 1 && works){ + 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)}) + await delay(500); + } + index++ + } + if (person !== null && person.getId() === params.nodes[0]){ + if (user!=null){ + setWinnerData(user) + setNetworkDataData(networkData) + } + cptTour ++; + setNbCoupData(cptTour) - if (user!=null){ - setWinnerData(user) - setNetworkDataData(networkData) - } - cptTour ++; - setNbCoupData(cptTour) - - try{ - console.log("time: " + testTemps) - if(user && isLoggedIn){ - if(solo){ - if(isDaily){ - // TODO: verif difficulté et add les stats - // TODO: verif pour facile et difficile, si réussi en one shot ou non - if(isEasy){ - manager.userService.addEasyEnigmaStats(user.pseudo, 1, testTemps - 0.5); - } - else{ - manager.userService.addHardEnigmaStats(user.pseudo, 1, testTemps - 0.5); - } - } - else{ - // add stats mastermind - if(user && user.mastermindStats){ - manager.userService.addMastermindStats(user.pseudo, cptTour, testTemps - 0.5); - } - } - } + try{ + console.log("time: " + testTemps) + if(user && isLoggedIn){ + if(solo){ + if(isDaily){ + // TODO: verif difficulté et add les stats + // TODO: verif pour facile et difficile, si réussi en one shot ou non + if(isEasy){ + manager.userService.addEasyEnigmaStats(user.pseudo, 1, testTemps - 0.5); + } + else{ + manager.userService.addHardEnigmaStats(user.pseudo, 1, testTemps - 0.5); } } - catch(error){ - console.log(error); + else{ + // add stats mastermind + if(user && user.mastermindStats){ + manager.userService.addMastermindStats(user.pseudo, cptTour, testTemps - 0.5); + } } - testFirst = true - setElapsedTime(0) - endgame = true - navigate(`${basePath}/endgame?solo=true&daily=${isDaily}`) - } + } + } + else{ + // add stats mastermind + if(user && user.mastermindStats){ + manager.userService.addMastermindStats(user.pseudo, cptTour, elapsedTime); + } } + testFirst = true + setElapsedTime(0) + endgame = true + navigate(`${basePath}/endgame?solo=true&daily=${isDaily}`) + } + catch(error){ + console.log(error); } - index++ + navigate(`${basePath}/endgame?solo=true&daily=${isDaily}`) + } + else{ + addToHistory(personTest.getName() + " n'est pas le coupable !"); //TODO préciser le nombre d'indice qu'il a de juste + cptTour ++; // On Incrémente le nombre de tour du joueur + const tour = cptTour+1; + addToHistory("<----- [Tour " + tour +"/"+networkData.nodes.length + "] ----->"); + changecptTour(cptTour); // On le transmet a la page précédente avec la fonction } - addToHistory(person.getName() + " n'est pas le coupable !"); //TODO préciser le nombre d'indice qu'il a de juste - - cptTour ++; // On Incrémente le nombre de tour du joueur - const tour = cptTour+1; - addToHistory("<----- [Tour " + tour +"/"+networkData.nodes.length + "] ----->"); - changecptTour(cptTour); // On le transmet a la page précédente avec la fonction } } } @@ -1065,12 +1103,6 @@ const MyGraphComponent: React.FC = ({onNodeClick, handleS function delay(ms: number): Promise { return new Promise(resolve => setTimeout(resolve, ms)); } - - function putGreyBackgroud(index: number){ - /* - - */ - } } diff --git a/cryptide_project/src/Components/PersonStatus.tsx b/cryptide_project/src/Components/PersonStatus.tsx index 54b2139..d562dc0 100644 --- a/cryptide_project/src/Components/PersonStatus.tsx +++ b/cryptide_project/src/Components/PersonStatus.tsx @@ -37,7 +37,7 @@ const PersonStatus: React.FC = ({img = Person, state= Person, img = BotImg } - const [buffer, setBuffer] = useState("") + const [buffer, setBuffer] = useState('50%') const [touchedPlayer, setTouchedPlayer] = useState(-2) useEffect(() =>{ @@ -48,10 +48,10 @@ const PersonStatus: React.FC = ({img = Person, state= Person, useEffect(() => { if (playerIndex===index){ - setBuffer('solid 3px green') + setBuffer('5px') } else{ - setBuffer('') + setBuffer('50%') } }, [playerIndex]) @@ -70,8 +70,8 @@ const PersonStatus: React.FC = ({img = Person, state= Person, onTouch(); }; const circleStyle: React.CSSProperties = { - backgroundColor: touchedPlayer == index && showCircle ? 'gold' : positionToColor(index), // Changement de la couleur en fonction de la condition - borderRadius: '50%', + backgroundColor: positionToColor(index), // Changement de la couleur en fonction de la condition + borderRadius: buffer, width: '80px', height: '80px', display: 'flex', @@ -83,8 +83,8 @@ const PersonStatus: React.FC = ({img = Person, state= Person, const circleStyleInt: React.CSSProperties = { - backgroundColor:'white', - borderRadius: '50%', + backgroundColor: touchedPlayer == index && showCircle ? 'lightblue' : 'white', + borderRadius: buffer, width: '70px', height: '70px', display: 'flex', @@ -111,8 +111,8 @@ const PersonStatus: React.FC = ({img = Person, state= Person, {/* */} -
-
{actualPlayerIndex !== index ? (name.substring(0, name.length - 2).length > 7 ? name.substring(0, name.length - 2).substring(0, 7) + '...' : name) : 'vous'}
+
+
{actualPlayerIndex !== index ? (name.length > 18 ? name.substring(0, 15) + '...' : name) : 'vous'}
); diff --git a/cryptide_project/src/Components/PlayerList.tsx b/cryptide_project/src/Components/PlayerList.tsx index 856d73d..ef2f5dc 100644 --- a/cryptide_project/src/Components/PlayerList.tsx +++ b/cryptide_project/src/Components/PlayerList.tsx @@ -5,6 +5,8 @@ import Player from '../model/Player'; import { useTheme } from '../Style/ThemeContext'; import PersonStatus from './PersonStatus'; import Person from '../res/img/Person.png' +import BotImg from '../res/img/bot.png' + import { socket } from '../SocketConfig'; @@ -16,13 +18,15 @@ interface PlayerListProps { setPlayerTouched: (newPlayerTouch: number) => void; playerIndex: number askedWrong: boolean + greyForEveryone: () => void } -const PlayerList: React.FC = ({ players, playerTouched, setPlayerTouched, playerIndex, askedWrong}) => { +const PlayerList: React.FC = ({ players, playerTouched, setPlayerTouched, playerIndex, askedWrong, greyForEveryone}) => { const theme = useTheme(); function askEveryone(){ if (!askedWrong){ + greyForEveryone() setPlayerTouched(players.length) } } @@ -34,12 +38,10 @@ const PlayerList: React.FC = ({ players, playerTouched, setPlay //@ts-ignore players.map((player, index) => ( //player.id!=socket.id && - void + showLast: boolean + setPlayerIndex: (playerIndex: number) => void + handleShowTurnBar: (bool: boolean) => void + handleTurnBarTextChange: (text: string) => void + addToHistory: (text: string) => void + setPlayerTouched: (playerIndex: number) => void + playerTouched: number + tutoStep: number + setTutoStep: (step: number) => void + setGreyForEveryone: (func: () => void) => void + displayModalstep: (step: number) => void; +} + +let lastNodes: NodePerson[] = [] +let firstIndex = true +let first = true +let touchedPlayer = -1 +let stepTuto = -1 + + + + +const TutorialGraph: React.FC = ({showLast, setNetwork, setPlayerIndex, handleShowTurnBar, handleTurnBarTextChange, addToHistory, setPlayerTouched, playerTouched, tutoStep, setTutoStep, setGreyForEveryone, displayModalstep}) => { + let cptTour: number = 0 + + //* Gestion du temps : + let initMtn = 0 + + const {isLoggedIn, user, manager} = useAuth(); + const {setIndiceData, setIndicesData, setActualPlayerIndexData, setWinnerData, setPlayersData, setNetworkDataData, setPersonData} = useGame(); + const params = new URLSearchParams(window.location.search); + + const navigate = useNavigate(); + const [lastIndex, setLastIndex] = useState(-1) + + if (first){ + first = false + setActualPlayerIndexData(0) + handleTurnBarTextChange("C'est à vous de jouer !") + handleShowTurnBar(true) + } + + + useEffect(() =>{ + touchedPlayer=playerTouched + }, [playerTouched]) + + useEffect(() => { + stepTuto = tutoStep + if(stepTuto===1){ + handleShowTurnBar(true) + } + }, [tutoStep]) + + + useEffect(() => { + const tab: NodePerson[] = [] + for(const n of lastNodes.reverse()){ + + } + lastNodes = tab + if (showLast){ + socket.emit("opacity activated", socket.id) + } + else{ + socket.emit("opacity deactivated", socket.id) + } + + }, [showLast]) + + let playerIndex: number = 0 + + if (firstIndex){ + firstIndex=false + setPlayerIndex(playerIndex) + } + let index = 0 + + useEffect(() => { + + + let jsonGraph = require("../tuto/graph.json") + let jsonIndice = require("../tuto/indices.json") + + const personNetwork = JSONParser.JSONToNetwork(JSON.stringify(jsonGraph)) + const indices = JSONParser.JSONToIndices(jsonIndice) + + setIndiceData(indices[0]) + if (personNetwork == null){ + return + } + const graph = GraphCreator.CreateGraph(personNetwork) + + const nodes = new DataSet(graph.nodesPerson); + + setIndicesData(indices) + setPersonData(personNetwork.getPersons()[4]) + + let n = graph.nodesPerson; + let e = graph.edges; + const graphState = { n, e }; + + // Sauvegarder l'état dans localStorage + localStorage.setItem('graphState', JSON.stringify(graphState)); + + const container = document.getElementById('graph-container'); + if (!container) { + console.error("Container not found"); + return; + } + // Charger les données dans le graph + + // Configuration des options du Graphe + const initialOptions = { + + layout: { + improvedLayout: true, + hierarchical: { + enabled: false, + direction: 'LR', // LR (Left to Right) ou autre selon votre préférence + sortMethod: 'hubsize' + }, + randomSeed: 3 + }, + physics: { + enabled: true, + barnesHut: { + gravitationalConstant: -1000, + springConstant: 0.001, + springLength: 100 + }, + solver: "repulsion", + repulsion: { + nodeDistance: 100 // Put more distance between the nodes. + } + } + }; + + const networkData = { nodes: nodes, edges: graph.edges }; + const network = new Network(container, networkData, initialOptions); + network.stabilize(); + setNetwork(network) + + const myFunctionInsideEffect = () => { + if (stepTuto === 3){ + const tabGrey = [0, 1, 2, 3, 5, 6, 7, 8, 9] + for (const i of tabGrey){ + nodes.update({id: i, color: "#808080"}) + } + } + }; + + setGreyForEveryone(() => myFunctionInsideEffect); + + + network.on("click", async (params) => { + + if(params.nodes.length > 0){ + } + }); + + network.on("dragging", (params) => { + if (params.nodes.length > 0) { + // Un nœud a été cliqué + initialOptions.physics.enabled = false; + network.setOptions(initialOptions); + setNetwork(network) + } + }); + + network.on("click", async (params) => { + if(params.nodes.length > 0){ + if (stepTuto === 0 && touchedPlayer === 1){ + const node = nodes.get().find((n: NodePerson) => n.id === params.nodes[0]) + + if (node === undefined)return; + if (node.id === 7){ + nodes.update({id: node.id, label: node.label + positionToEmoji(1, true)}) + handleShowTurnBar(false) + setPlayerIndex(1) + setPlayerTouched(-1) + await delay(500) + const node2 = nodes.get().find((n: NodePerson) => n.id === params.nodes[0]) + if (node2 === undefined)return; + nodes.update({id: node.id, label: node2.label + positionToEmoji(2, false)}) + await delay(500) + const node3 = nodes.get().find((n: NodePerson) => n.id === 8) + if (node3 === undefined)return; + nodes.update({id: node3.id, label: node3.label + positionToEmoji(1, false)}) + setPlayerIndex(2) + await delay(500) + const node4 = nodes.get().find((n: NodePerson) => n.id === 0) + if (node4 === undefined)return; + nodes.update({id: node4.id, label: node4.label + positionToEmoji(1, true)}) + setPlayerIndex(0) + setTutoStep(1) + + displayModalstep(1); + } + } + else if(stepTuto === 1 && touchedPlayer === 2){ + const node = nodes.get().find((n: NodePerson) => n.id === params.nodes[0]) + if (node === undefined){ + return; + } + if (node.id === 0){ + nodes.update({id: node.id, label: node.label + positionToEmoji(2, false)}) + setPlayerTouched(-1) + displayModalstep(2); + handleTurnBarTextChange("Mauvais choix, posez un carré !") + const tabGrey = [7, 0, 4, 1, 8] + for (const id of tabGrey){ + const node = nodes.get().find((n: NodePerson) => n.id === id) + if (node === undefined)return; + nodes.update({id: node.id, color: "#808080"}) + } + setTutoStep(2) + } + } + else if(stepTuto === 2){ + const node = nodes.get().find((n: NodePerson) => n.id === params.nodes[0]) + if (node === undefined)return; + if (node.id === 9){ + const tabColor = [7, 0, 4, 1, 8] + nodes.update({id: node.id, label: node.label + positionToEmoji(0, false)}) + for(const id of tabColor){ + const pers = personNetwork.getPersons().find((p: Person) => p.getId() === id) + if (pers !== undefined){ + nodes.update({id: id, color: ColorToHexa(pers.getColor())}) + } + } + handleShowTurnBar(false) + setPlayerIndex(1) + await delay(500) + const node2 = nodes.get().find((n: NodePerson) => n.id === 4) + if (node2 === undefined)return; + nodes.update({id: node2.id, label: node2.label + positionToEmoji(2, true)}) + setPlayerIndex(2) + await delay(500) + const node3 = nodes.get().find((n: NodePerson) => n.id === 3) + if (node3 === undefined)return; + nodes.update({id: node3.id, label: node3.label + positionToEmoji(0, false)}) + await delay(500) + const node4 = nodes.get().find((n: NodePerson) => n.id === 1) + if (node4 === undefined)return; + nodes.update({id: node4.id, label: node4.label + positionToEmoji(2, false)}) + setPlayerIndex(0) + handleTurnBarTextChange("A vous de jouer !") + handleShowTurnBar(true) + setTutoStep(3) + displayModalstep(3); + } + } + else if(stepTuto === 3 && touchedPlayer === 3){ + const node = nodes.get().find((n: NodePerson) => n.id === params.nodes[0]) + if (node === undefined)return; + if (node.id === 4){ + nodes.update({id: node.id, label: node.label + positionToEmoji(0, true)}) + setPlayerTouched(-1) + await delay(500) + const node2 = nodes.get().find((n: NodePerson) => n.id === 4) + if (node2 === undefined)return; + nodes.update({id: node2.id, label: node2.label + positionToEmoji(1, true)}) + await delay(500) + + for(const person of personNetwork.getPersons()){ + nodes.update({id: person.getId(), color: ColorToHexa(person.getColor())}) + } + if (user != null){ + const winner = user; + setNetworkDataData(networkData) + setActualPlayerIndexData(-1) + setLastIndex(-1) + setPlayerTouched(-1) + setWinnerData(winner) + first = true + navigate(`${basePath}/endgame`) + } + } + } + } + else{ + setPlayerTouched(-1) + } + }); + + + }, []); // Le tableau vide signifie que cela ne s'exécutera qu'une fois après le premier rendu + + return ( + <> +
+ + ); + + function delay(ms: number): Promise { + return new Promise(resolve => setTimeout(resolve, ms)); + } + +} + + + +export default TutorialGraph; \ No newline at end of file diff --git a/cryptide_project/src/Pages/EndGame.tsx b/cryptide_project/src/Pages/EndGame.tsx index 2f5c76b..3e72f2c 100644 --- a/cryptide_project/src/Pages/EndGame.tsx +++ b/cryptide_project/src/Pages/EndGame.tsx @@ -146,15 +146,13 @@ function EndGame() {
*/}
- {losingPlayers.map((player, index) => ( -
- {player.id !== winner?.id && ( -
- {}} index={index} playerIndex={-2} showCircle={false} askedWrong={false}/> - {!indicenull && (
{indices[players.findIndex((p) => p.id == player?.id)].ToString("fr")}
)} -
- )} -
+ {players.map((player, index) => ( + player.id !== winner?.id && ( +
+ {}} index={index} playerIndex={-2} showCircle={false} askedWrong={false}/> + {!indicenull && (
{indices[players.findIndex((p) => p.id == player?.id)].ToString("fr")}
)} +
+ ) ))}
diff --git a/cryptide_project/src/Pages/InGame.tsx b/cryptide_project/src/Pages/InGame.tsx index 9a5b1d1..65314a4 100644 --- a/cryptide_project/src/Pages/InGame.tsx +++ b/cryptide_project/src/Pages/InGame.tsx @@ -97,6 +97,28 @@ const InGame = ({locale, changeLocale}) => { const [showLast, setShowLast] = useState(false) const [askedWrong, setAskedWrong] = useState(false) const [importToPdf, setImportToPdf] = useState(false) + const [importToJSON, setImportToJSON] = useState(false) + + const [putCorrectBackground, setPutCorrectBackground] = useState<() => void>(() => {}); + const [putGreyBackgroud, setPutGreyBackground] = useState<() => void>(() => {}); + const [putImposssibleGrey, setPutImposssibleGrey] = useState<() => void>(() => {}); + + + const setPutCorrectBackgroundData = (func: () => void) => { + setPutCorrectBackground(func) + } + + const setPutGreyBackgroundData = (func: () => void) => { + setPutGreyBackground(func) + } + + const setPutImposssibleGreyData = (func: () => void) => { + setPutImposssibleGrey(func) + } + + const setImportToJSONData = (imp: boolean) => { + setImportToJSON(imp) + } const setImportToPdfData = (imp: boolean) => { setImportToPdf(imp) @@ -306,7 +328,15 @@ const InGame = ({locale, changeLocale}) => { askedWrong={askedWrong} setAskedWrong={setAskedWrongData} importToPdf={importToPdf} - setImportToPdf={setImportToPdfData}/> + setImportToPdf={setImportToPdfData} + importToJSON={importToJSON} + setImportToJSON={setImportToJSONData} + setPutCorrectBackground={setPutCorrectBackgroundData} + setPutGreyBackground={setPutGreyBackgroundData} + setPutImposssibleGrey={setPutImposssibleGreyData} + putCorrectBackground={putCorrectBackground} + putGreyBackground={putGreyBackgroud} + putImposssibleGrey={putImposssibleGrey}/> @@ -442,7 +472,7 @@ const InGame = ({locale, changeLocale}) => { { !IsSolo &&
- + {}}/>
} diff --git a/cryptide_project/src/Pages/Lobby.tsx b/cryptide_project/src/Pages/Lobby.tsx index c6f412b..df747cd 100644 --- a/cryptide_project/src/Pages/Lobby.tsx +++ b/cryptide_project/src/Pages/Lobby.tsx @@ -66,11 +66,17 @@ function Lobby() { const room = params.get('room'); function addBot(){ - socket.emit("lobby joined", room, new EasyBot("botId" + Math.floor(Math.random() * 1000), "Bot" + Math.floor(Math.random() * 100), "").toJson()) + let json = require("../res/botNames.json") + const tabNames = [...json.names] + let name = tabNames[Math.floor(Math.random() * tabNames.length)] + while (players.find((p) => p.pseudo === name) != undefined){ + name = tabNames[Math.floor(Math.random() * tabNames.length)] + } + socket.emit("lobby joined", room, new EasyBot(name, name, "").toJson()) } //* nb Node - const [enteredNumber, setEnteredNumber] = useState(20); + const [enteredNumber, setEnteredNumber] = useState(25); //@ts-ignore const handleNumberChange = (event) => { @@ -213,23 +219,25 @@ function Lobby() { function StartGame(){ - const [networkPerson, choosenPerson, choosenIndices] = GameCreator.CreateGame(players.length, enteredNumber) - setPersonData(choosenPerson) - setPersonNetworkData(networkPerson) - setIndicesData(choosenIndices) - let users = players.filter((p) => p instanceof User) - let u = users[Math.floor(Math.random() * users.length)] - let start = players.findIndex((p) => p.id == u.id) - if (start == -1){ - start = 0 + if (players.length > 2){ + const [networkPerson, choosenPerson, choosenIndices] = GameCreator.CreateGame(players.length, enteredNumber) + setPersonData(choosenPerson) + setPersonNetworkData(networkPerson) + setIndicesData(choosenIndices) + let users = players.filter((p) => p instanceof User) + let u = users[Math.floor(Math.random() * users.length)] + let start = players.findIndex((p) => p.id == u.id) + if (start == -1){ + start = 0 + } + socket.emit('network created', JSON.stringify(networkPerson, null, 2), JSON.stringify(choosenPerson), JSON.stringify(choosenIndices), room, start); } - socket.emit('network created', JSON.stringify(networkPerson, null, 2), JSON.stringify(choosenPerson), JSON.stringify(choosenIndices), room, start); } const copyGameLink = () => { setShow(!show) - const gameLink = "http://172.20.10.4:3000/lobby?room="+ room; + const gameLink = basePath + "/lobby?room="+ room; navigator.clipboard.writeText(gameLink) .then(() => { console.log('Lien copié avec succès !'); @@ -240,7 +248,7 @@ function Lobby() { }; const textAreaRef = useRef(null); - const linkToCopy = "http://172.20.10.4:3000/lobby?room="+ room + const linkToCopy = basePath + "/lobby?room="+ room const handleCopyClick = () => { setShow(!show) if(textAreaRef.current != null){ @@ -345,7 +353,7 @@ function Lobby() { onChange={handleNumberChange} min={20} max={60}/> - diff --git a/cryptide_project/src/Pages/NewPlay.tsx b/cryptide_project/src/Pages/NewPlay.tsx index 9b3544a..27e2153 100644 --- a/cryptide_project/src/Pages/NewPlay.tsx +++ b/cryptide_project/src/Pages/NewPlay.tsx @@ -110,6 +110,10 @@ function NewPlay() { else setShowOverlay(true) } + + function launchTuto(){ + navigate(`${basePath}/tutorial`); + } useEffect(() => { @@ -221,7 +225,11 @@ function NewPlay() { + + {/* */} + {/* {goBackRoom != -1 && } */} + {/* Lobbies */} diff --git a/cryptide_project/src/Pages/Tutorial.tsx b/cryptide_project/src/Pages/Tutorial.tsx new file mode 100644 index 0000000..e326850 --- /dev/null +++ b/cryptide_project/src/Pages/Tutorial.tsx @@ -0,0 +1,757 @@ +import React, { useState, useEffect } from 'react'; +import Switch from "react-switch"; +import {saveAs} from "file-saver" + +/* Style */ +import "./InGame.css" +import {useTheme} from '../Style/ThemeContext' +/* Component */ +import GraphContainer from '../Components/GraphContainer'; +import PlayerList from '../Components/PlayerList'; +import TurnBar from '../Components/TurnBar'; + +/* Icon */ +import Param from "../res/icon/param.png"; +import Info from "../res/icon/infoGreen.png"; +import Check from "../res/icon/checkboxGreen.png"; +import MGlass from "../res/icon/magnifying-glass.png"; +import Reset from "../res/icon/reset.png"; +import Oeye from "../res/icon/eye.png"; +import Ceye from "../res/icon/hidden.png"; +import ImgBot from "../res/img/bot.png"; + +import ava from "../res/img/tuto/tuto-ava.png"; +import indicetxt from "../res/img/tuto/tuto-indiceTxt.png" +import rep from "../res/img/tuto/tuto-rep.png"; +import joueurs from "../res/img/tuto/tuto-joueurs.png"; +import graph from "../res/img/tuto/tuto-graph.png"; + +import step1 from "../res/img/tuto/tuto2-1.png"; +import step2 from "../res/img/tuto/tuto2-2.png"; +import step3 from "../res/img/tuto/tuto2-3.png"; +import step4 from "../res/img/tuto/tuto2-4.png"; +import step5 from "../res/img/tuto/tuto2-5.png"; +import step6 from "../res/img/tuto/tuto2-6.png"; + +/* nav */ +import { Link, Navigate, useNavigate, useNavigationType } from 'react-router-dom'; + +/* Boostrap */ +import Offcanvas from 'react-bootstrap/Offcanvas'; +import Modal from 'react-bootstrap/Modal'; +import Card from 'react-bootstrap/Card'; +import Button from 'react-bootstrap/Button'; + +/* Model */ +import Stub from '../model/Stub'; +import { useGame } from '../Contexts/GameContext'; +import { socket } from '../SocketConfig'; +import { Network } from 'vis-network'; +import {generateLatexCode, generateLatexCodeEnigme} from '../Script/LatexScript'; +import Pair from '../model/Pair'; +import Indice from '../model/Indices/Indice'; +import {basePath} from "../AdressSetup" +import TutorialGraph from '../Components/TutorialGraph'; +import { useAuth } from '../Contexts/AuthContext'; +import EasyBot from '../model/EasyBot'; +import { set } from 'lodash'; + + +let cptNavigation = 0 + +//@ts-ignore +const Tutorial = ({locale, changeLocale}) => { + const {personNetwork, person, indices, players, setPlayersData, indice, actualPlayerIndex} = useGame() + const {user} = useAuth() + + + const theme = useTheme(); + + const navigate = useNavigate() + + const [greyForEveryone, setGreyForEveryone] = useState<() => void>(() => {}); + + const setGreyForEveryoneData = (func: () => void) => { + setGreyForEveryone(func) + } + + const navigationType = useNavigationType() + cptNavigation++ + if (cptNavigation % 2 == 0){ + if (navigationType.toString() == "POP"){ + socket.emit("player quit") + navigate(`${basePath}/`) + } + } + + //* Historique + const [history, setHistory] = useState([]); + const [showLast, setShowLast] = useState(false) + const [askedWrong, setAskedWrong] = useState(false) + const [importToPdf, setImportToPdf] = useState(false) + const [importToJSON, setImportToJSON] = useState(false) + const [tutoStep, setTutoStep] = useState(0) + + const setTutoStepData = (step: number) => { + setTutoStep(step) + } + + const setImportToJSONData = (imp: boolean) => { + setImportToJSON(imp) + } + + const setImportToPdfData = (imp: boolean) => { + setImportToPdf(imp) + } + + // Fonction pour ajouter un élément à l'historique + const addToHistory = (message: string) => { + setHistory(prevHistory => [...prevHistory, message]); + }; + + const setShowLastData = () =>{ + setLastVisible(!showLast); + setShowLast(!showLast); + } + + const setAskedWrongData = (askedWrong: boolean) => { + setAskedWrong(askedWrong) + } + + useEffect(() => { + const historyContainer = document.getElementById('history-container'); + if (historyContainer) { + historyContainer.scrollTop = historyContainer.scrollHeight; + } + }, [history]); + + useEffect(() => { + if (user == null){ + return + } + setPlayersData([user, new EasyBot("Scooby-Doo", "Scooby-Doo", ImgBot), new EasyBot("Batman", "Batman", ImgBot)]) + }, []) + + + + const [showChoiceBar, setShowChoiceBar] = useState(false); + const [showTurnBar, setShowTurnBar] = useState(false); + const [turnBarText, setTurnBarText] = useState(""); + const [playerTouched, setPlayerTouched] = useState(-2) + const [playerIndex, setPlayerIndex] = useState(-2) + + + const [network, setNetwork] = useState(null) + const [networkEnigme, setNetworkEnigme] = useState[]> | null>(null) + + const setNetworkData = (network: Network) => { + setNetwork(network) + } + + const setNetworkEnigmeData = (networkEnigme: Map[]>) => { + setNetworkEnigme(networkEnigme) + } + + const handleNodeClick = (shouldShowChoiceBar: boolean) => { + setShowChoiceBar(shouldShowChoiceBar); + }; + + const handleSetPlayerTouched = (newPlayerTouched: number) => { + setPlayerTouched(newPlayerTouched); + }; + + + const handleShowTurnBar = (shouldShowTurnBar: boolean) => { + setShowTurnBar(shouldShowTurnBar); + }; + + const handleTurnBarTextChange = (newTurnBarText: string) =>{ + setTurnBarText(newTurnBarText) + } + + const setPlayerIndexData = (playerIndex: number) => { + setPlayerIndex(playerIndex) + } + + + const resetGraph = () => { + setisLoading(true); + socket.emit("reset graph", socket.id) + setTimeout(() => { + setisLoading(false); + }, 2000); + } + + /* offcanvas */ + //? 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 ? + const [show, setShow] = useState(false); + const handleClose = () => setShow(false); + const handleShow = () => setShow(true); + + const [showP, setShowP] = useState(false); + const handleCloseP = () => setShowP(false); + const handleShowP = () => setShowP(true); + + const [showS, setShowS] = useState(false); + const handleCloseS = () => setShowS(false); + const handleShowS = () => setShowS(true); + + const [cptTour, setcptTour] = useState(0); + + const [LastVisible, setLastVisible] = useState(false); + + const [isLoading, setisLoading] = useState(false); + + + //@ts-ignore + const changecptTour = (newcptTour) => { + setcptTour(newcptTour); + }; + + const handleChange = () => { + if (show){ + handleClose() + } + else { + handleShow() + } + }; + + const handleChangeS = () => { + if (showS){ + handleCloseS() + } + else { + handleShowS() + } + }; + + const eye = LastVisible ? Oeye : Ceye; //icon que l'on affiche pour l'oeil : fermé ou ouvert. + + /* Windows open */ + //@ts-ignore + const openInNewTab = (url) => { //! avec url ==> dangereux + window.open(url); + }; + + const [SwitchEnabled, setSwitchEnabled] = useState(false) + const allIndices = Stub.GenerateIndice() + + const nbPlayer = players.length; + const navdeduc = 'deduc?actualId=' + actualPlayerIndex + '&nbPlayer=' + nbPlayer; + + + + //* gestion demo */ + const [showM, setShowM] = useState(false); + const [showTuto2, setShowTuto2] = useState(false); + const [showTuto21, setShowTuto21] = useState(false); + const [showTuto22, setShowTuto22] = useState(false); + const [showTuto3, setShowTuto3] = useState(false); + + const handleCloseM = () => { + setShowM(false); + handleShowHelp() + } + const handleShowM = () => setShowM(true); + + const handleCloseHelp = () => { + switch(tutoStep){ + case 0: + setShowTuto2(false); + break; + case 1: + setShowTuto21(false); + break; + case 2: + setShowTuto22(false); + break; + case 3: + setShowTuto3(false); + break; + } + } + const handleShowHelp = () => { + switch(tutoStep){ + case 0: + setShowTuto2(true); + break; + case 1: + setShowTuto21(true); + break; + case 2: + setShowTuto22(true); + break; + case 3: + setShowTuto3(true); + break; + } + } + + + const handleCloseTuto2 = () => setShowTuto2(false); + const handleShowTuto2 = () => setShowTuto2(true); + + const handleCloseTuto21 = () => setShowTuto21(false); + const handleShowTuto21 = () => setShowTuto21(true); + + const handleCloseTuto22 = () => setShowTuto22(false); + const handleShowTuto22 = () => setShowTuto22(true); + + const handleCloseTuto3 = () => setShowTuto3(false); + const handleShowTuto3 = () => setShowTuto3(true); + + + const [step, setStep] = useState(-1); + + //@ts-ignore + const displayModalstep = (step: number) => { + //* for step 2 + setStep(0); // remise a 0 de step + switch(step) { + case 1: + setShowTuto21(true); + break; + case 2: + setShowTuto22(true); + break; + case 3: + setShowTuto3(true); + break; + } + + } + + useEffect(() => { + handleShowM(); + }, []) + + return ( +
+ {showTurnBar && } +
+ +
+ +
+ {history.map((item, index) => ( +
{item}
+ ))} +
+ + +
+ {/* + */} + + + + + + + + + +
+ + +
+ +
+ + + + + Indice + + + {indice?.ToString(locale)} + + + + + + + + Tutoriel + + + + {step === -1 && ( + + + + Bienvenue dans SocialGraph + + Vous incarnez un détective assoiffé de gloire, confronté à un crime.
+ Cependant, d'autres enquêteurs sont également sur le coup, tous cherchant à décrocher le titre de meilleur détective du monde.
+ 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 !
+ Interrogez vos concurrents pour obtenir des réponses par oui ou non, mais méfiez-vous, un refus a des conséquences.
+ Soyez le premier à déduire les indices des autres et à trouver le coupable pour remporter la reconnaissance tant convoitée.
+ Si vous avez le moindre doute, cliquer sur le bouton "aide" pour afficher l'étape actuel du tuto +
+
+
+ )} + {step === 0 && ( + + + + Les Suspects + + 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. +
+ Par exemple, ici, nous avons Ava, qui a 40 ans, qui pratique du Basket et du Tennis, qui a les cheveux Roux et qui possède 2 amis. +
+
+
+ )} + + {step === 1 && ( + + + + Les indices + + Dans ce jeu, chaque détective possède un indice, qui permet d'identifier une caractéristique du coupable, votre indice est le suivant : +
+ "Le suspect a entre 20 et 29 ans". +
+
+
+ )} + + {step === 3 && ( + + + + Les Détectives + + 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. +
+ 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. +
+
+
+ )} + + {step === 4 && ( + + + + Les réponses + + Les détéctives vous répondrons que par des ronds ou des carrés de leur couleur. +
+
    +
  • + Un carré signifie que son indice innocente le suspect. +
  • +
  • + Un rond signifie que son indice peut incréminer le suspect. +
  • +
+ Par exemple, ici :
+ l'indice du détéctive Scooby-Doo (Vert) permet d'innocenter Logan. +
Eleanor peut être suspectée par l'indice du détective Batman (Jaune). +
Evelyn est innocentée par l'indice de 3 détéctive différents. +
+
+
+ )} + + {step === 5 && ( + + + + + + Les règles du jeu + + Ce bouton vous mène à la page d'information du jeu, avec toutes les règles du jeu, que ce soit les objectifs, les indices, le déroulement, etc. + + + + )} + + {step === 2 && ( + + + + + + L'indice + + Ce bouton vous permet d'afficher votre indice personnel, gradez le secret ! Il s'agit de votre meilleur atout pour gagner. + + + + )} + + {step === 6 && ( + + + + Place à la pratique ! + + Bien joué ! Vous avez maintenanttoutes les bases d'un veritable détéctive. +
+ 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. +
+ Cliquer sur "Poursuivre" pour commencer votre première partie. +
+
+
+ )} + + + +
+ +
+ +
+ {/* */} + { step != 0 && ()} + { step === 6 ? () : + } + +
+
+ + + + Tutoriel + + + + + + + Premier pas + + Bienvenue dans cette seconde partie, où nous allons apprendre le déroulé d'une veritable enquête. +
+ Dans un premier temps, sélectionnez le joueur Scooby-Doo et questionnez le à propos du suspect nommé Violet en cliquant sur cette dernière. +
+
+
+ +
+ + + +
+ + + + Tutoriel + + + {step === 0 && ( + + + + Votre premier tour + + Super, Violet a été identifié par l'indice de Scooby-Doo, c'est une information essentielle ! Cependant, cela ne signifie pas forcément qu'elle est coupable. +
+ C'est à présent le tour aux autres joueurs de jouer, regardons ce qu'ils ont fait. +
+
+
+ )} + + {step === 1 && ( + + + + Premier tour des autres joueurs + + Il semblerait que Scooby-Doo ait lui aussi interrogé Batman à propos de Violet, et que ce dernier ait répondu non par un carré. + Cela signifie que Violet n'est pas coupable, et qu'elle est donc innocente ! +
+ Scooby-Doo a donc fait une erreur, en questionnant quelqu'un pouvant innocenter Violet. En guise de punition, 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. +
+ Ensuite, Batman a questionné Scooby-Doo à propos de Charlotte, qui est identifié par l'indice de Scooby-Doo. +
+
+
+ )} + + {step === 2 && ( + + + + Second tour + + Vous remarquez que votre indice identifie lui aussi Charlotte, et si nous demandions à Batman, si ce dernier pense que Charlotte est la coupable ? +
+ Cela nous permettrait donc de mettre fin à la partie ! +
+
+
+ )} + + +
+ +
+ +
+ { step != 0 && ()} + { step === 2 ? () : + } +
+
+ + + + Tutoriel + + + + + + + La punition + + Mince, il semblerait que l'indice de Batman innocente Charlotte, et que vous avez donc commit une erreur, la punition s'applique ! +
+ Vous devez donc poser un carré sur un autre joueur, révélant ainsi plus d'information sur votre indice. +
+ Mais rien n'est joué ! Posons notre carré sur Liam pour cela, sélectionnez directement le suspect désiré. +
+
+
+
+ + + +
+ + + + End Game + + + + + + La fin du jeu + + Ce tour est lui aussi riche en informations ! +
+ Vous avez à présent assez d'information pour deviner les indices des autres : +
    +
  • + Scooby-Doo semble avoir : {indices[1]?.ToString(locale)}. +
  • +
  • + Batman semble avoir : {indices[2]?.ToString(locale)}. +
  • +
  • + Et votre indice est : {indices[0]?.ToString(locale)}. +
  • +
+ Vous avez à présent toutes les cartes en main pour deviner qui est le coupable, cliquer sur le bouton Ask Everyone, puis séléctionné un suspect pour émettre une accusation pour deviner, bonne chance ! +
+
+
+
+ + + +
+
+ ); + }; + + +export default Tutorial; diff --git a/cryptide_project/src/model/Graph/Edge.ts b/cryptide_project/src/model/Graph/Edge.ts index 92d0816..07f7311 100644 --- a/cryptide_project/src/model/Graph/Edge.ts +++ b/cryptide_project/src/model/Graph/Edge.ts @@ -2,6 +2,7 @@ class Edge{ public from: number public to: number + public color: string = "black" constructor(from: number, to: number){ this.from = from diff --git a/cryptide_project/src/res/botNames.json b/cryptide_project/src/res/botNames.json new file mode 100644 index 0000000..e7f7b11 --- /dev/null +++ b/cryptide_project/src/res/botNames.json @@ -0,0 +1,22 @@ +{ + "names": [ + "Sherlock Holmes", + "Inspecteur Gadget", + "Scooby-Doo", + "Marple", + "Spocky", + "Phoenix", + "Batman", + "James Bond", + "Sherlockio", + "Verra", + "Hercule Poirot", + "Colombo", + "MacGyver", + "Lupin", + "D. Conan", + "Pr. Layton", + "Dr. Watson" + ] + } + \ No newline at end of file diff --git a/cryptide_project/src/res/img/tuto/tuto-ava.png b/cryptide_project/src/res/img/tuto/tuto-ava.png new file mode 100644 index 0000000..2ca4ec2 Binary files /dev/null and b/cryptide_project/src/res/img/tuto/tuto-ava.png differ diff --git a/cryptide_project/src/res/img/tuto/tuto-graph.png b/cryptide_project/src/res/img/tuto/tuto-graph.png new file mode 100644 index 0000000..f9e04d7 Binary files /dev/null and b/cryptide_project/src/res/img/tuto/tuto-graph.png differ diff --git a/cryptide_project/src/res/img/tuto/tuto-indice.png b/cryptide_project/src/res/img/tuto/tuto-indice.png new file mode 100644 index 0000000..60e93af Binary files /dev/null and b/cryptide_project/src/res/img/tuto/tuto-indice.png differ diff --git a/cryptide_project/src/res/img/tuto/tuto-indiceTxt.png b/cryptide_project/src/res/img/tuto/tuto-indiceTxt.png new file mode 100644 index 0000000..de79616 Binary files /dev/null and b/cryptide_project/src/res/img/tuto/tuto-indiceTxt.png differ diff --git a/cryptide_project/src/res/img/tuto/tuto-info.png b/cryptide_project/src/res/img/tuto/tuto-info.png new file mode 100644 index 0000000..5bee543 Binary files /dev/null and b/cryptide_project/src/res/img/tuto/tuto-info.png differ diff --git a/cryptide_project/src/res/img/tuto/tuto-joueurs.png b/cryptide_project/src/res/img/tuto/tuto-joueurs.png new file mode 100644 index 0000000..74450df Binary files /dev/null and b/cryptide_project/src/res/img/tuto/tuto-joueurs.png differ diff --git a/cryptide_project/src/res/img/tuto/tuto-rep.png b/cryptide_project/src/res/img/tuto/tuto-rep.png new file mode 100644 index 0000000..93c172d Binary files /dev/null and b/cryptide_project/src/res/img/tuto/tuto-rep.png differ diff --git a/cryptide_project/src/res/img/tuto/tuto-tada.png b/cryptide_project/src/res/img/tuto/tuto-tada.png new file mode 100644 index 0000000..c9e2f9b Binary files /dev/null and b/cryptide_project/src/res/img/tuto/tuto-tada.png differ diff --git a/cryptide_project/src/res/img/tuto/tuto2-1.png b/cryptide_project/src/res/img/tuto/tuto2-1.png new file mode 100644 index 0000000..e62f185 Binary files /dev/null and b/cryptide_project/src/res/img/tuto/tuto2-1.png differ diff --git a/cryptide_project/src/res/img/tuto/tuto2-2.png b/cryptide_project/src/res/img/tuto/tuto2-2.png new file mode 100644 index 0000000..5147f1a Binary files /dev/null and b/cryptide_project/src/res/img/tuto/tuto2-2.png differ diff --git a/cryptide_project/src/res/img/tuto/tuto2-3.png b/cryptide_project/src/res/img/tuto/tuto2-3.png new file mode 100644 index 0000000..77ebf30 Binary files /dev/null and b/cryptide_project/src/res/img/tuto/tuto2-3.png differ diff --git a/cryptide_project/src/res/img/tuto/tuto2-4.png b/cryptide_project/src/res/img/tuto/tuto2-4.png new file mode 100644 index 0000000..73de848 Binary files /dev/null and b/cryptide_project/src/res/img/tuto/tuto2-4.png differ diff --git a/cryptide_project/src/res/img/tuto/tuto2-5.png b/cryptide_project/src/res/img/tuto/tuto2-5.png new file mode 100644 index 0000000..ba6be6e Binary files /dev/null and b/cryptide_project/src/res/img/tuto/tuto2-5.png differ diff --git a/cryptide_project/src/res/img/tuto/tuto2-6.png b/cryptide_project/src/res/img/tuto/tuto2-6.png new file mode 100644 index 0000000..ad7c0a7 Binary files /dev/null and b/cryptide_project/src/res/img/tuto/tuto2-6.png differ diff --git a/cryptide_project/src/tuto/graph.json b/cryptide_project/src/tuto/graph.json new file mode 100644 index 0000000..1690f7c --- /dev/null +++ b/cryptide_project/src/tuto/graph.json @@ -0,0 +1 @@ +{"persons":[{"id":0,"name":"Charlotte","age":25,"color":2,"sports":[4],"friends":[{"id":4,"name":"Sophia","age":20,"color":4,"sports":[1,3]},{"id":3,"name":"Aurora","age":19,"color":0,"sports":[4,2]},{"id":7,"name":"Violet","age":24,"color":2,"sports":[3]},{"id":5,"name":"Alice","age":68,"color":3,"sports":[0]}]},{"id":1,"name":"Carter","age":20,"color":1,"sports":[1,0],"friends":[{"id":4,"name":"Sophia","age":20,"color":4,"sports":[1,3]},{"id":2,"name":"Ava","age":40,"color":3,"sports":[2,3]}]},{"id":2,"name":"Ava","age":40,"color":3,"sports":[2,3],"friends":[{"id":1,"name":"Carter","age":20,"color":1,"sports":[1,0]},{"id":9,"name":"Liam","age":19,"color":4,"sports":[0]}]},{"id":3,"name":"Aurora","age":19,"color":0,"sports":[4,2],"friends":[{"id":4,"name":"Sophia","age":20,"color":4,"sports":[1,3]},{"id":0,"name":"Charlotte","age":25,"color":2,"sports":[4]},{"id":8,"name":"Sebastian","age":13,"color":0,"sports":[1]},{"id":9,"name":"Liam","age":19,"color":4,"sports":[0]},{"id":6,"name":"Benjamin","age":52,"color":1,"sports":[0,2,4]}]},{"id":4,"name":"Sophia","age":20,"color":4,"sports":[1,3],"friends":[{"id":3,"name":"Aurora","age":19,"color":0,"sports":[4,2]},{"id":0,"name":"Charlotte","age":25,"color":2,"sports":[4]},{"id":1,"name":"Carter","age":20,"color":1,"sports":[1,0]}]},{"id":5,"name":"Alice","age":68,"color":3,"sports":[0],"friends":[{"id":0,"name":"Charlotte","age":25,"color":2,"sports":[4]},{"id":6,"name":"Benjamin","age":52,"color":1,"sports":[0,2,4]}]},{"id":6,"name":"Benjamin","age":52,"color":1,"sports":[0,2,4],"friends":[{"id":3,"name":"Aurora","age":19,"color":0,"sports":[4,2]},{"id":5,"name":"Alice","age":68,"color":3,"sports":[0]}]},{"id":7,"name":"Violet","age":24,"color":2,"sports":[3],"friends":[{"id":0,"name":"Charlotte","age":25,"color":2,"sports":[4]}]},{"id":8,"name":"Sebastian","age":13,"color":0,"sports":[1],"friends":[{"id":3,"name":"Aurora","age":19,"color":0,"sports":[4,2]}]},{"id":9,"name":"Liam","age":19,"color":4,"sports":[0],"friends":[{"id":2,"name":"Ava","age":40,"color":3,"sports":[2,3]},{"id":3,"name":"Aurora","age":19,"color":0,"sports":[4,2]}]}]} \ No newline at end of file diff --git a/cryptide_project/src/tuto/indices.json b/cryptide_project/src/tuto/indices.json new file mode 100644 index 0000000..3e14a36 --- /dev/null +++ b/cryptide_project/src/tuto/indices.json @@ -0,0 +1 @@ +"[{\"type\":\"AgeIndice\",\"id\":5,\"minimum\":20,\"maximum\":29},{\"type\":\"SportIndice\",\"id\":24,\"sports\":[2,3]},{\"type\":\"ColorEdgesIndice\",\"id\":27,\"neighborsColors\":[0]}]" \ No newline at end of file