Ajout de la page de jeu et de l'affichage graphe

pull/51/head
Baptiste MARCEL 1 year ago
parent 01369648c9
commit 3b9d8f7d4d

@ -20,6 +20,7 @@
"react-router-dom": "^6.18.0",
"react-scripts": "5.0.1",
"typescript": "^5.2.2",
"vis-network": "^9.1.9",
"web-vitals": "^2.1.4"
}
},
@ -16827,6 +16828,23 @@
"node": ">= 0.8"
}
},
"node_modules/vis-network": {
"version": "9.1.9",
"resolved": "https://registry.npmjs.org/vis-network/-/vis-network-9.1.9.tgz",
"integrity": "sha512-Ft+hLBVyiLstVYSb69Q1OIQeh3FeUxHJn0WdFcq+BFPqs+Vq1ibMi2sb//cxgq1CP7PH4yOXnHxEH/B2VzpZYA==",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/visjs"
},
"peerDependencies": {
"@egjs/hammerjs": "^2.0.0",
"component-emitter": "^1.3.0",
"keycharm": "^0.2.0 || ^0.3.0 || ^0.4.0",
"uuid": "^3.4.0 || ^7.0.0 || ^8.0.0 || ^9.0.0",
"vis-data": "^6.3.0 || ^7.0.0",
"vis-util": "^5.0.1"
}
},
"node_modules/w3c-hr-time": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",

@ -14,6 +14,7 @@
"react-router-dom": "^6.18.0",
"react-scripts": "5.0.1",
"typescript": "^5.2.2",
"vis-network": "^9.1.9",
"web-vitals": "^2.1.4"
},
"scripts": {

@ -9,6 +9,7 @@ import Login from './Pages/LoginForm';
import SignUp from './Pages/SignUpForm';
import Play from './Pages/Play';
import Lobby from './Pages/Lobby';
import InGame from './Pages/InGame';
/* Component */
import AppNavbar from './Components/NavBar';
@ -62,6 +63,7 @@ function App() {
<Route path="/signup" element={<SignUp />} />
<Route path="/play" element={<Play/>} />
<Route path="/lobby" element={<Lobby/>} />
<Route path="/game" element={<InGame/>} />
</Routes>
</BrowserRouter>
</IntlProvider>

@ -0,0 +1,10 @@
#graph-container {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
background-color: #f5f5f5;
padding: 20px;
box-sizing: border-box;
}

@ -0,0 +1,237 @@
import React, { useEffect } from "react";
import { DataSet, Network} from "vis-network/standalone/esm/vis-network";
import "./GraphContainer.css";
const NB_SPORTS = 3;
const MIN_AGE = 20;
const MAX_AGE = 100;
const COLORS = ["blanc", "noir", "jaune", "chocolat"];
const SPORTS = ["foot", "tennis", "rugby", "basket"];
const NAMES = ["Fabien", "Mélyssa", "Kéké", "David", "Elisa", "Karina", "Fatima", "Pintrand", "Pif", "Nathan", "Thomas", "Carreau", "Léo", "Hélicoptère", "Tank"]
class Person {
id: number = 0;
name: string;
age: number;
color: string;
sport: string[];
friends: Person[] = [];
constructor(name: string, age: number, color: string, sport: string[]) {
this.name = name;
this.age = age;
this.color = color;
this.sport = sport || [];
}
getAge() {
return this.age;
}
setAge(age: number) {
this.age = age;
}
addFriend(person: Person) {
// Si la personne n'est pas déjà dans la liste d'amis
// et qu'il a pas déjà 5 amis ou plus
// alors on l'ajoute
if (!this.friends.includes(person) && this.friends.length < 5 && person.friends.length < 5) {
this.friends.push(person);
person.addFriend(this);
}
}
getFriends() {
return this.friends;
}
equals(person: Person) {
return this.age === person.age &&
this.color === person.color &&
this.sportsEquals(person);
}
sportsEquals(person:Person) {
return this.sport.length === person.sport.length &&
this.sport.every(sport => person.sport.includes(sport));
}
toString() {
return `Person(id = ${this.id}, age=${this.age}, color=${this.color}, sport=${this.sport}, friends=${this.friends.length})`;
}
}
// Génère un élément aléatoire d'un tableau
function getRandomElement(array: any[]) {
return array[Math.floor(Math.random() * array.length)];
}
// Génère un nombre aléatoire entre min et max
function getRandomNumber(min: number, max: number) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
// Génère une personne avec un age, une couleur et une liste de sports
function generatePerson(possibleNames: string[], possibleSports: string[], existingPeople: Person[]) {
// Génère un age entre 20 et 100 ans
const age = getRandomNumber(MIN_AGE, MAX_AGE);
const color = getRandomElement(COLORS);
const sports = [];
let name = "";
// Génère un nombre de sports entre 1 et NB_SPORTS
const nbSports = getRandomNumber(1, NB_SPORTS);
for (let i = 0; i < nbSports; i++) {
// Gestion des sports
// Si il n'y a plus de sports possibles, on reprend la liste de base
if (possibleSports.length === 0) {
possibleSports = SPORTS.slice();
}
// Génère un sport aléatoire
// Si le sport est déjà dans la liste, on recommence
const sport = getRandomElement(possibleSports);
if (sports.indexOf(sport) === -1) {
possibleSports.splice(possibleSports.indexOf(sport), 1);
sports.push(sport);
} else {
i--;
}
// Gestion des prénoms
// Si il n'y a plus de prénoms possibles, on reprend la liste de base
if (possibleNames.length === 0) {
possibleNames = NAMES.slice();
}
// Génère un prénom aléatoire et le supprime de la liste de prénom disponible
name = getRandomElement(possibleNames);
possibleNames.splice(possibleNames.indexOf(name), 1);
}
const newPerson = new Person(name, age, color, sports);
// Vérifie si la personne n'est pas déjà dans la liste
// Si déjà dans la liste, on recommence
// if (existingPeople.some(person => person.equals(newPerson))) {
// return generatePerson(possibleSports, existingPeople);
// }
return newPerson;
}
function generatePeople(nbPeople: number) {
const people = [];
let possibleSports = SPORTS.slice();
let possibleNames = NAMES.slice();
for (let i = 0; i < nbPeople; i++) {
const person = generatePerson(possibleNames, possibleSports, people);
person.id += i;
people.push(person);
}
return people;
}
// Ajouter des amis aléatoirement entre une liste de personnes
function addFriends(people: Person[]) {
people.forEach(person => {
// const nbFriends = getRandomNumber(0, people.length - 1);
const nbFriends = getRandomNumber(1, 5);
for (let i = 0; i < nbFriends; i++) {
let friend = getRandomElement(people);
// S'assurer que l'ami généré aléatoirement est différent de la personne
while (friend === person) {
friend = getRandomElement(people);
}
person.addFriend(friend);
}
});
}
const people = generatePeople(40);
addFriends(people);
const MyGraphComponent = () => {
useEffect(() => {
const container = document.getElementById('graph-container');
if (!container) {
console.error("Container not found");
return;
}
// Création du réseau
const persons: any[] = [];
const edges: any[] = [];
people.forEach(person => {
const visPerson = {id: person.id, label: person.name};
persons.push(visPerson);
person.friends.forEach(friend => {
// Eviter le double sens des relations
if (edges.some(edge => edge.from === friend.id && edge.to === person.id || edge.from === person.id && edge.to === friend.id)) {
return;
}
edges.push({from: person.id, to: friend.id});
});
});
// Charger les données dans le graph
const nodes = new DataSet(persons);
// Configuration des options du Graphe
const initialOptions = {
nodes: {
shape: 'circle',
size: 30,
font: {
size: 20
},
},
layout: {
improvedLayout: true,
hierarchical: {
enabled: false,
direction: 'LR', // LR (Left to Right) ou autre selon votre préférence
sortMethod: 'hubsize'
}
},
physics: {
enabled: true,
barnesHut: {
gravitationalConstant: -1000,
springConstant: 0.001,
springLength: 100
}
}
};
const networkData = { nodes: nodes, edges: edges };
const network = new Network(container, networkData, initialOptions);
// Gérer le changement entre la physique et le déplacement manuel
let physicsEnabled = true;
network.on("dragging", (params) => {
if (params.nodes.length > 0) {
// Un nœud a été cliqué
initialOptions.physics.enabled = false;
network.setOptions(initialOptions);
}
});
}, []); // Le tableau vide signifie que cela ne s'exécutera qu'une fois après le premier rendu
return (
<>
<div id="graph-container"/>
</>
);
};
export default MyGraphComponent;

@ -0,0 +1,8 @@
import React from "react";
import GraphContainer from "../Components/GraphContainer";
export default function InGame() {
return (
<GraphContainer />
);
}

@ -39,7 +39,7 @@ function Lobby() {
}
</ul>
<center>
<ButtonImgNav dest='/' img={cible} text=' À la chasse !'/> {/* page de baptiste ici */}
<ButtonImgNav dest='/game' img={cible} text=' À la chasse !'/> {/* page de baptiste ici */}
</center>
</div>
</div>

@ -0,0 +1,36 @@
import {
Network,
Options,
Data,
Edge,
Node
} from "vis-network/standalone/esm/vis-network";
import React, { useState, useLayoutEffect, useRef } from "react";
export interface UseVisNetworkOptions {
options: Options;
nodes: Node[];
edges: Edge[];
}
export default (props: UseVisNetworkOptions) => {
const { edges, nodes, options } = props;
const [network, addNetwork] = useState<Network | null>(null);
const ref = useRef<HTMLDivElement>(null);
const data: Data = { nodes, edges };
useLayoutEffect(() => {
if (ref.current) {
const instance = new Network(ref.current, data, options);
addNetwork(instance);
}
return () => network?.destroy();
}, []);
return {
network,
ref
};
};
Loading…
Cancel
Save