diff --git a/cryptide_project/src/App.tsx b/cryptide_project/src/App.tsx index 3c50601..736245a 100644 --- a/cryptide_project/src/App.tsx +++ b/cryptide_project/src/App.tsx @@ -33,6 +33,7 @@ import 'bootstrap/dist/css/bootstrap.min.css'; /* Internationnalisation */ import messagesFr from './Translations/fr.json'; import messagesEn from './Translations/en.json'; +import SoloGame from './Pages/SoloGame'; const messages = { fr: messagesFr, @@ -76,8 +77,9 @@ function App() { } /> } /> } /> - } /> + }/> } /> + {/* }/> */} diff --git a/cryptide_project/src/Components/ColoredIndices.tsx b/cryptide_project/src/Components/ColoredIndices.tsx new file mode 100644 index 0000000..e8f8c4a --- /dev/null +++ b/cryptide_project/src/Components/ColoredIndices.tsx @@ -0,0 +1,24 @@ +import React from 'react'; +import { Link } from 'react-router-dom'; +import '../Style/Global.css'; +import { FormattedMessage } from 'react-intl'; + +import { useTheme } from '../Style/ThemeContext'; + +//@ts-ignore +function ColoredIndices({ letter, color}) { + + const theme = useTheme(); + + // const mystyle = { + // backgroundColor: "#0064E0", + // }; + + return ( +
+ Indice Letter +
+ ); +} + +export default ColoredIndices; diff --git a/cryptide_project/src/Components/GraphContainer.tsx b/cryptide_project/src/Components/GraphContainer.tsx index 3bc315a..797c788 100644 --- a/cryptide_project/src/Components/GraphContainer.tsx +++ b/cryptide_project/src/Components/GraphContainer.tsx @@ -26,17 +26,24 @@ interface MyGraphComponentProps { onNodeClick: (shouldShowChoiceBar: boolean) => void; handleShowTurnBar: (shouldShowTurnBar: boolean) => void handleTurnBarTextChange: (newTurnBarText: string) => void + changecptTour: (newcptTour : number) => void + solo : boolean } let lastAskingPlayer = 0 let lastNodeId = -1 let first = true let askedWrong = false +let cptTour: number = 0 -const MyGraphComponent: React.FC = ({onNodeClick, handleShowTurnBar, handleTurnBarTextChange}) => { +const MyGraphComponent: React.FC = ({onNodeClick, handleShowTurnBar, handleTurnBarTextChange, changecptTour, solo}) => { const { indices, indice, person, personNetwork, setNodeIdData, players, askedPersons, setActualPlayerIndexData, room, actualPlayerIndex, turnPlayerIndex, onlyFalse, setOnlyFalseData } = useGame(); + const params = new URLSearchParams(window.location.search); + + + let playerIndex: number = turnPlayerIndex let index = 0 for (let i=0; i = ({onNodeClick, handleS } let thisPlayerIndex = index - + if (first){ first = false - setActualPlayerIndexData(index) - if (playerIndex == thisPlayerIndex){ - handleTurnBarTextChange("À vous de jouer") - handleShowTurnBar(true) - + if (!solo){ + setActualPlayerIndexData(index) + if (playerIndex == thisPlayerIndex){ + handleTurnBarTextChange("À vous de jouer") + handleShowTurnBar(true) + } } - indices.forEach(i => { - console.log(i.ToString("en")) - }); } useEffect(() => { @@ -72,7 +77,6 @@ const MyGraphComponent: React.FC = ({onNodeClick, handleS console.error("Container not found"); return; } - // Charger les données dans le graph const nodes = new DataSet(graph.nodesPerson); @@ -99,142 +103,162 @@ const MyGraphComponent: React.FC = ({onNodeClick, handleS const networkData = { nodes: nodes, edges: graph.edges }; const network = new Network(container, networkData, initialOptions); - - socket.on("asked all", (id) =>{ - const pers = personNetwork.getPersons().find((p) => p.getId() == id) - if (pers!=undefined){ - askedPersons.push(pers) - } - }) - - socket.on("node checked",(id, works, color, newPlayerIndex) => { - const node = nodes.get().find((n) => id == n.id) - if (node!=undefined){ - onNodeClick(false) - playerIndex = newPlayerIndex - if (!node.label.includes(colorToEmoji(color, works))){ - networkData.nodes.update({id: id, label: node.label + colorToEmoji(color, works)}) - } - if (playerIndex === thisPlayerIndex){ - handleTurnBarTextChange("À vous de jouer") - handleShowTurnBar(true) - } - else{ - handleShowTurnBar(false) - } - } - lastAskingPlayer = 0 - lastNodeId = -1 - }) - - socket.on("already asked", (nodeId, askedPlayer) =>{ - console.log("player: " + askedPlayer + " already asked on node " + nodeId) - }) - - socket.on("asked wrong", () =>{ - setOnlyFalseData(true) - askedWrong = true - handleShowTurnBar(true) - handleTurnBarTextChange("Mauvais choix, posez un carré !") - }) - - - socket.on("asked", (nodeId, askingPlayer, askingPlayerIndex) => { - console.log(askingPlayerIndex) - if (askingPlayer.id !== lastAskingPlayer || nodeId !== lastNodeId ){ - lastAskingPlayer = askingPlayer.id - lastNodeId = nodeId - const pers = personNetwork.getPersons().find((p) => p.getId() == nodeId) + if (!solo){ + socket.on("asked all", (id) =>{ + const pers = personNetwork.getPersons().find((p) => p.getId() == id) if (pers!=undefined){ - if (askedPersons.includes(pers)){ - socket.emit("already asked", nodeId, askingPlayer, socket.id) - return + askedPersons.push(pers) + } + }) + + socket.on("node checked",(id, works, color, newPlayerIndex) => { + const node = nodes.get().find((n) => id == n.id) + if (node!=undefined){ + onNodeClick(false) + playerIndex = newPlayerIndex + if (!node.label.includes(colorToEmoji(color, works))){ + networkData.nodes.update({id: id, label: node.label + colorToEmoji(color, works)}) + } + if (playerIndex === thisPlayerIndex){ + handleTurnBarTextChange("À vous de jouer") + handleShowTurnBar(true) } else{ - askedPersons.push(pers) - const node = nodes.get().find((n) => nodeId == n.id) - if (node != undefined && indice != null){ - var tester = IndiceTesterFactory.Create(indice) - let maybe = thisPlayerIndex - playerIndex = playerIndex + 1 - if(playerIndex == players.length){ - playerIndex = 0 - } - if (tester.Works(pers)){ - socket.emit("node checked", nodeId, true, positionToColor(thisPlayerIndex), room, playerIndex) - } - else{ - maybe = maybe - 1 - if(maybe == 0){ - maybe = players.length - 1 + handleShowTurnBar(false) + } + } + lastAskingPlayer = 0 + lastNodeId = -1 + }) + + socket.on("already asked", (nodeId, askedPlayer) =>{ + console.log("player: " + askedPlayer + " already asked on node " + nodeId) + }) + + socket.on("asked wrong", () =>{ + setOnlyFalseData(true) + askedWrong = true + handleShowTurnBar(true) + handleTurnBarTextChange("Mauvais choix, posez un carré !") + }) + + + socket.on("asked", (nodeId, askingPlayer, askingPlayerIndex) => { + console.log(askingPlayerIndex) + if (askingPlayer.id !== lastAskingPlayer || nodeId !== lastNodeId ){ + lastAskingPlayer = askingPlayer.id + lastNodeId = nodeId + const pers = personNetwork.getPersons().find((p) => p.getId() == nodeId) + if (pers!=undefined){ + if (askedPersons.includes(pers)){ + socket.emit("already asked", nodeId, askingPlayer, socket.id) + return + } + else{ + askedPersons.push(pers) + const node = nodes.get().find((n) => nodeId == n.id) + if (node != undefined && indice != null){ + var tester = IndiceTesterFactory.Create(indice) + let maybe = thisPlayerIndex + playerIndex = playerIndex + 1 + if(playerIndex == players.length){ + playerIndex = 0 + } + if (tester.Works(pers)){ + socket.emit("node checked", nodeId, true, positionToColor(thisPlayerIndex), room, playerIndex) + } + else{ + maybe = maybe - 1 + if(maybe == 0){ + maybe = players.length - 1 + } + socket.emit("node checked", nodeId, false, positionToColor(thisPlayerIndex), room, maybe) + socket.emit("asked wrong", askingPlayer, room) } - socket.emit("node checked", nodeId, false, positionToColor(thisPlayerIndex), room, maybe) - socket.emit("asked wrong", askingPlayer, room) } - } - } + } + } } - } - - }) + + }) + } + - - personNetwork.getPersons().forEach(p => { - let a = 0 - for (let i of indices){ - let tester = IndiceTesterFactory.Create(i) - if (tester.Works(p)){ - a++ + + personNetwork.getPersons().forEach(p => { + let a = 0 + for (let i of indices){ + let tester = IndiceTesterFactory.Create(i) + if (tester.Works(p)){ + a++ + } } - } - if (a==indices.length){ - //networkData.nodes.update({id: p.getId(), label: p.getName() + "\n🔵"}) - console.log(p) - } + if (a==indices.length){ + //networkData.nodes.update({id: p.getId(), label: p.getName() + "\n🔵"}) + console.log(p) + } + + }); - }); - - // Gérer le changement entre la physique et le déplacement manuel - network.on("dragging", (params) => { - if (params.nodes.length > 0) { - // Un nœud a été cliqué - initialOptions.physics.enabled = false; - network.setOptions(initialOptions); - } - }); + // Gérer le changement entre la physique et le déplacement manuel + network.on("dragging", (params) => { + if (params.nodes.length > 0) { + // Un nœud a été cliqué + initialOptions.physics.enabled = false; + network.setOptions(initialOptions); + } + }); - network.on("click", (params) => { + network.on("click", async (params) => { if(params.nodes.length > 0){ setNodeIdData(params.nodes[0]) - // Renvoyer un true pour afficher la choice bar - if (askedWrong){ - console.log(askedWrong) - const person = personNetwork?.getPersons().find((p) => p.getId() == params.nodes[0]) - if (person !== undefined && indice !== null){ - const tester = IndiceTesterFactory.Create(indice) - if (!tester.Works(person) && !askedPersons.includes(person)){ - console.log(playerIndex) - playerIndex = thisPlayerIndex + 1 - if(playerIndex == players.length){ - playerIndex = 0 + if (!solo){ + if (askedWrong){ + const person = personNetwork?.getPersons().find((p) => p.getId() == params.nodes[0]) + if (person !== undefined && indice !== null){ + const tester = IndiceTesterFactory.Create(indice) + if (!tester.Works(person) && !askedPersons.includes(person)){ + playerIndex = thisPlayerIndex + 1 + if(playerIndex == players.length){ + playerIndex = 0 + } + socket.emit("node checked", params.nodes[0], false, positionToColor(thisPlayerIndex), room, playerIndex) + askedPersons.push(person) + askedWrong = false } - socket.emit("node checked", params.nodes[0], false, positionToColor(thisPlayerIndex), room, playerIndex) - askedPersons.push(person) - askedWrong = false } } - - } - else if (thisPlayerIndex == playerIndex){ - onNodeClick(true) + else if (thisPlayerIndex == playerIndex){ + onNodeClick(true) + } + else{ + onNodeClick(false) + } } - else{ - onNodeClick(false) + else{ // si solo -> Mastermind + const person = personNetwork?.getPersons().find((p) => p.getId() == params.nodes[0]) //person sélectionnée + if (person != undefined){ + let index = 0; + // indices.forEach(async (i, index) =>{ + for(const i of indices){ + const tester = IndiceTesterFactory.Create(i) + const test = tester.Works(person) + const node = nodes.get().find((n) => params.nodes[0] == n.id) + if (node!=undefined){ + networkData.nodes.update({id: params.nodes[0], label: node.label + colorToEmoji(positionToColor(index), test)}) + await delay(500); + } + index ++; + } + cptTour ++; // On Incrémente le nombre de tour du joueur + changecptTour(cptTour); // On le transmet a la page précédente avec la fonction + } } } + // Renvoyer un true pour afficher la choice bar else{ // Renvoyer un false pour cacher la choice bar onNodeClick(false) @@ -247,6 +271,10 @@ const MyGraphComponent: React.FC = ({onNodeClick, handleS
); + + function delay(ms: number) { + return new Promise(resolve => setTimeout(resolve, ms)); + } } diff --git a/cryptide_project/src/Components/TurnBar.tsx b/cryptide_project/src/Components/TurnBar.tsx index dae6c18..53df6d4 100644 --- a/cryptide_project/src/Components/TurnBar.tsx +++ b/cryptide_project/src/Components/TurnBar.tsx @@ -16,6 +16,6 @@ const TurnBar: React.FC = ({text})=> {

{text}

); - }; - - export default TurnBar; \ No newline at end of file +}; + +export default TurnBar; \ No newline at end of file diff --git a/cryptide_project/src/Pages/InGame.css b/cryptide_project/src/Pages/InGame.css index 9e12155..600710e 100644 --- a/cryptide_project/src/Pages/InGame.css +++ b/cryptide_project/src/Pages/InGame.css @@ -60,6 +60,22 @@ top :50px; } +.nbLaps{ /*nombre de tour*/ + position: absolute; + z-index: 1; + left: 10px; + top :50px; + + margin: 10px 20px; + padding: 20px; + border-radius: 15px; + border: solid 2px; + + font-size: 30px; + color: #fff; +} + + #endgamebutton{ position: absolute; z-index: 1; diff --git a/cryptide_project/src/Pages/InGame.tsx b/cryptide_project/src/Pages/InGame.tsx index db37efe..8a90482 100644 --- a/cryptide_project/src/Pages/InGame.tsx +++ b/cryptide_project/src/Pages/InGame.tsx @@ -10,6 +10,7 @@ import ChoiceBar from '../Components/ChoiceBar'; import ButtonImgNav from '../Components/ButtonImgNav'; import PersonStatus from '../Components/PersonStatus'; import PlayerList from '../Components/PlayerList'; +import TurnBar from '../Components/TurnBar'; /* Icon */ import Leave from "../res/icon/leave.png"; @@ -32,45 +33,62 @@ import { HiLanguage } from 'react-icons/hi2'; import { Nav, NavDropdown } from 'react-bootstrap'; import { FormattedMessage } from 'react-intl'; import Color from '../model/Color'; -import TurnBar from '../Components/TurnBar'; import { useGame } from '../Contexts/GameContext'; //@ts-ignore const InGame = ({locale, changeLocale}) => { - + const theme = useTheme(); - - const [showChoiceBar, setShowChoiceBar] = useState(false); - const [showTurnBar, setShowTurnBar] = useState(false); - const [turnBarText, setTurnBarText] = useState(""); - const handleNodeClick = (shouldShowChoiceBar: boolean) => { - setShowChoiceBar(shouldShowChoiceBar); - }; + const params = new URLSearchParams(window.location.search); + + //* Gestion solo + let IsSolo: boolean = true + const solotmp = params.get('solo'); + if (solotmp == "false"){ + IsSolo=false + } - const handleShowTurnBar = (shouldShowTurnBar: boolean) => { - setShowTurnBar(shouldShowTurnBar); - }; - - const handleTurnBarTextChange = (newTurnBarText: string) =>{ - setTurnBarText(newTurnBarText) - } - - /* 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 [showChoiceBar, setShowChoiceBar] = useState(false); + const [showTurnBar, setShowTurnBar] = useState(false); + const [turnBarText, setTurnBarText] = useState(""); + + const handleNodeClick = (shouldShowChoiceBar: boolean) => { + setShowChoiceBar(shouldShowChoiceBar); + }; + + + const handleShowTurnBar = (shouldShowTurnBar: boolean) => { + setShowTurnBar(shouldShowTurnBar); + }; - const [showS, setShowS] = useState(false); - const handleCloseS = () => setShowS(false); - const handleShowS = () => setShowS(true); + const handleTurnBarTextChange = (newTurnBarText: string) =>{ + setTurnBarText(newTurnBarText) + } + + /* 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); + + //@ts-ignore + const changecptTour = (newcptTour) => { + setcptTour(newcptTour); + }; const handleChange = () => { if (show){ @@ -114,19 +132,31 @@ const InGame = ({locale, changeLocale}) => {
{showTurnBar && }
- +
-
- -
+ }}> + Tour : {cptTour} +
+ ) : ( +
+ +
+ ) + } +
- - - + - - - + +
diff --git a/cryptide_project/src/Pages/SoloGame.css b/cryptide_project/src/Pages/SoloGame.css new file mode 100644 index 0000000..4f2769b --- /dev/null +++ b/cryptide_project/src/Pages/SoloGame.css @@ -0,0 +1,107 @@ +.upperInfo{ + display: flex; + justify-content: center; + flex-direction: column; + align-items: center; + + width: 30%; + + border-radius: 0px 0px 30px 30px; + border: solid; + border-width: 2px 5px; + + background-color: white; + + font-size: 30px; + + top: 20px;; +} + +#mainDiv{ + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; +} + + +.paramDiv{ + z-index: 1; + position: absolute; + top: 10px; + right: 10px; +} + +#graphDiv{ + + display: flex; + flex-direction: row; + + position: absolute; + + top: 0; + left: 0; + right: 0; + bottom: 0; +} + +#bottom-container{ + bottom: 0; + + background-color: white; + padding:20px; + border-radius: 20px 20px 0px 0px; +} + +.nbLaps{ + position: absolute; + z-index: 1; + left: 10px; + top :50px; + + margin: 10px 20px; + padding: 20px; + border-radius: 15px; + border: solid 2px; + + font-size: 30px; + color: #fff; +} + +#endgamebutton{ + position: absolute; + z-index: 1; + bottom: 0; + right: 25%; +} + +.upperInfo, +#bottom-container, +.menuGame { + position: absolute; + z-index: 1; +} + +.menuGame{ + display: flex; + align-items: space-between; + justify-content: end; + flex-direction: column; + + top:30%; + right: 0; +} + +.menuGame Button { + margin: 10px; +} + +.button{ + /*background-color: #85C9C2;*/ + + border: solid 2px #85C9C2; + border-radius: 10px; + + width: 100px; + height: 60px; +} diff --git a/cryptide_project/src/Pages/SoloGame.tsx b/cryptide_project/src/Pages/SoloGame.tsx new file mode 100644 index 0000000..98e5825 --- /dev/null +++ b/cryptide_project/src/Pages/SoloGame.tsx @@ -0,0 +1,236 @@ +import React, { useState } from 'react'; +import Switch from "react-switch"; + +/* Style */ +import "./SoloGame.css" +import {useTheme} from '../Style/ThemeContext' +/* Component */ +import GraphContainer from '../Components/GraphContainer'; +import ChoiceBar from '../Components/ChoiceBar'; +import ButtonImgNav from '../Components/ButtonImgNav'; +import PersonStatus from '../Components/PersonStatus'; +import PlayerList from '../Components/PlayerList'; + +/* Icon */ +import Leave from "../res/icon/leave.png"; +import Param from "../res/icon/param.png"; +import Replay from "../res/icon/replay.png"; +import Info from "../res/icon/infoGreen.png"; +import Check from "../res/icon/checkboxGreen.png"; +import Alpha from "../res/GreekLetters/alphaW.png"; + +/* nav */ +import { Link } from 'react-router-dom'; + +/* Boostrap */ +import Button from 'react-bootstrap/Button'; +import Offcanvas from 'react-bootstrap/Offcanvas'; + +/* Model */ +import Stub from '../model/Stub'; +import { HiLanguage } from 'react-icons/hi2'; +import { Nav, NavDropdown } from 'react-bootstrap'; +import { FormattedMessage } from 'react-intl'; +import Color from '../model/Color'; +import TurnBar from '../Components/TurnBar'; +import { useGame } from '../Contexts/GameContext'; + +//@ts-ignore +const SoloGame = ({locale, changeLocale}) => { + + const theme = useTheme(); + + const [showChoiceBar, setShowChoiceBar] = useState(false); + const [showTurnBar, setShowTurnBar] = useState(false); + + + const handleNodeClick = (shouldShowChoiceBar: boolean) => { + setShowChoiceBar(shouldShowChoiceBar); + }; + + const handleShowTurnBar = (shouldShowTurnBar: boolean) => { + setShowTurnBar(shouldShowTurnBar); + }; + + /* 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 handleChange = () => { + if (show){ + handleClose() + } + else { + handleShow() + } + }; + + // const handleChangeP = () => { + // if (showP){ + // handleCloseP() + // } + // else { + // handleShowP() + // } + // }; + + const handleChangeS = () => { + if (showS){ + handleCloseS() + } + else { + handleShowS() + } + }; + + /* Windows open */ + //@ts-ignore + const openInNewTab = (url) => { //! avec url ==> dangereux + window.open(url); + }; + + const [SwitchEnabled, setSwitchEnabled] = useState(false) + const indices = Stub.GenerateIndice() + const { indice, players } = useGame(); + + + return ( +
+ +
+ {/* */} +
+ +
+ Tour : 5 +
+ +
+ +
+ +
+ + + + {/* */} + + + + + + +
+ + {/* + + Joueurs +

Il y a {players.length} joueurs

+
+ + + +
*/} + + + + Indice + + + {/* Possède les cheveux noir ou joue au basket */} + {indice?.ToString(locale)} + + + + { + //* canva pour les paramètres + } + + + param Paramètres + + + + + + + + +
+ {showChoiceBar && } +
+ {/* +
{/* tmp + +
+ */} +
+ ); +}; + + +export default SoloGame; diff --git a/cryptide_project/src/SocketConfig.ts b/cryptide_project/src/SocketConfig.ts index 2fea1de..81422c9 100644 --- a/cryptide_project/src/SocketConfig.ts +++ b/cryptide_project/src/SocketConfig.ts @@ -1,6 +1,6 @@ import { io } from "socket.io-client"; -const socket = io("http://localhost:3002"); +const socket = io("http://127.20.10.4:3002"); export {socket} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..41b488d --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "Cryptid", + "lockfileVersion": 3, + "requires": true, + "packages": {} +}