From 58c3ec79ed3c0f0d34314e4fafa63e862cf42ee8 Mon Sep 17 00:00:00 2001 From: Thomas Chazot Date: Mon, 20 Nov 2023 11:59:00 +0100 Subject: [PATCH] =?UTF-8?q?Fin=20du=20bot=20facile=20+=20normalement=20ce?= =?UTF-8?q?=20sera=20tr=C3=A8s=20simple=20d'impl=C3=A9menter=20le=20bot=20?= =?UTF-8?q?avanc=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cryptide_project/server/server.js | 13 +- .../src/Components/GraphContainer.tsx | 182 ++++++++++++++++-- .../src/Components/PersonStatus.tsx | 1 - cryptide_project/src/Pages/Lobby.tsx | 19 +- cryptide_project/src/model/Bot.ts | 21 +- cryptide_project/src/model/EasyBot.ts | 90 ++++++++- .../src/model/NetworkGenerator.ts | 2 +- cryptide_project/src/model/Pair.ts | 15 ++ 8 files changed, 303 insertions(+), 40 deletions(-) create mode 100644 cryptide_project/src/model/Pair.ts diff --git a/cryptide_project/server/server.js b/cryptide_project/server/server.js index 3c1c3ec..8fbe62a 100644 --- a/cryptide_project/server/server.js +++ b/cryptide_project/server/server.js @@ -24,8 +24,8 @@ server.listen(3002, () => { io.on('connection', (socket) => { console.log(socket.id); - socket.on('network created', (network, person, indices, room) =>{ - io.to(room).emit("game created", network, person, indices, Math.floor(Math.random() * map.get(room).length)) + socket.on('network created', (network, person, indices, room, start) =>{ + io.to(room).emit("game created", network, person, indices, start) }); socket.on("lobby joined", (room, player) =>{ @@ -62,8 +62,8 @@ io.on('connection', (socket) => { io.to(askingPlayer.id).emit("already asked", nodeId, askedPlayer) }) - socket.on("ask player", (nodeId, playerId, askingPlayer, askingPlayerIndex) =>{ - io.to(playerId).emit("asked", nodeId, askingPlayer, askingPlayerIndex) + socket.on("ask player", (nodeId, playerId, askingPlayer) =>{ + io.to(playerId).emit("asked", nodeId, askingPlayer) }) socket.on("asked all 1by1", (id, playerId) =>{ @@ -80,15 +80,14 @@ io.on('connection', (socket) => { for (let i = 0; i{ - console.log(playerIndex) - io.to(room).emit("node checked", id, works, color, playerIndex) + io.to(room).emit("node checked", id, works, color, playerIndex, socket.id) }) socket.on("put correct background", (id) =>{ diff --git a/cryptide_project/src/Components/GraphContainer.tsx b/cryptide_project/src/Components/GraphContainer.tsx index 21932f1..eb1af59 100644 --- a/cryptide_project/src/Components/GraphContainer.tsx +++ b/cryptide_project/src/Components/GraphContainer.tsx @@ -41,15 +41,20 @@ let askedWrong = false let solo: boolean = true let mapIndexPersons: Map = new Map() let touchedPlayer = -1 +let botIndex = -1 +let askedWrongBot = false +let botTurnToCube = false +let lastSocketId= "" const MyGraphComponent: React.FC = ({onNodeClick, handleShowTurnBar, handleTurnBarTextChange, playerTouched, setPlayerTouched, changecptTour, solo}) => { let cptTour: number = 0 - const { indices, indice, person, personNetwork, setNodeIdData, players, askedPersons, setActualPlayerIndexData, room, actualPlayerIndex, turnPlayerIndex, setWinnerData } = useGame(); + const { indices, indice, person, personNetwork, setNodeIdData, players, askedPersons, setActualPlayerIndexData, room, actualPlayerIndex, turnPlayerIndex, setTurnPlayerIndexData, setWinnerData } = useGame(); const params = new URLSearchParams(window.location.search); const navigate = useNavigate(); + const [lastIndex, setLastIndex] = useState(-1) useEffect(() =>{ @@ -69,7 +74,6 @@ let cptTour: number = 0 socket.emit("put imossible grey", socket.id) } }, [playerTouched]) - let playerIndex: number = turnPlayerIndex let index = 0 @@ -80,7 +84,95 @@ let cptTour: number = 0 } } let thisPlayerIndex = index - + + useEffect(() =>{ + if (actualPlayerIndex==0){ + const bot = players[lastIndex] + if(bot instanceof Bot && botIndex != lastIndex){ + botIndex = lastIndex + if (personNetwork!=null){ + const [choosedPlayerIndex, personIndex] = bot.playRound(personNetwork, players) + const person = personNetwork.getPersons().find((p) => p.getId() == personIndex) + if (choosedPlayerIndex == players.length && person != undefined){ + console.log(lastIndex + " All in sur => " + personNetwork.getPersons().find((p) => p.getId() == personIndex)?.getName()) + let nextPlayerIndex = lastIndex + 1 + if (nextPlayerIndex == players.length){ + nextPlayerIndex = 0 + } + let playerIndex = lastIndex + 1 + let i = 0 + socket.emit("node checked", personIndex, true, lastIndex, room, lastIndex) + while(playerIndex != lastIndex){ + i++ + if (playerIndex == players.length){ + playerIndex = 0 + } + const tester = IndiceTesterFactory.Create(indices[playerIndex]) + const works = tester.Works(person) + socket.emit("asked all 1by1", person.getId(), players[playerIndex].id) + if (i==players.length){ + socket.emit("node checked", personIndex, works, playerIndex, room, nextPlayerIndex) + } + else{ + socket.emit("node checked", personIndex, works, playerIndex, room, lastIndex) + } + if(!works){ + socket.emit("node checked", personIndex, works, playerIndex, room, nextPlayerIndex) + return + } + playerIndex ++ + } + socket.emit("end game", lastIndex, room) + } + else{ + if (person!=undefined){ + if (players[choosedPlayerIndex] instanceof Bot){ + console.log("BOT") + const tester = IndiceTesterFactory.Create(indices[choosedPlayerIndex]) + const works = tester.Works(person) + if (works){ + playerIndex = lastIndex + 1 + if(playerIndex == players.length){ + playerIndex = 0 + } + console.log(lastIndex + " interroge " + choosedPlayerIndex + " a propos de " + person.getName() + " et dit oui") + socket.emit("node checked", personIndex, true, choosedPlayerIndex, room, playerIndex) + } + else{ + console.log(lastIndex + " interroge " + choosedPlayerIndex + " a propos de " + person.getName() + " et dit non") + socket.emit("node checked", personIndex, false, choosedPlayerIndex, room, lastIndex) + 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) + } + } + else{ + console.log(choosedPlayerIndex + " => Pas bot" ) + socket.emit("ask player", personIndex, players[choosedPlayerIndex].id, players[lastIndex]) + console.log(lastIndex + " interroge " + +choosedPlayerIndex + " sur " + personNetwork.getPersons()[personIndex].getName()) + const tester = IndiceTesterFactory.Create(indices[choosedPlayerIndex]) + if (!tester.Works(person)){ + 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) + } + } + } + } + } + } + } + }, [lastIndex]) + + if (first){ first = false @@ -88,6 +180,14 @@ let cptTour: number = 0 for(let i = 0; i{ + if (p instanceof Bot && personNetwork!=null){ + p.index=index + p.initiateMap(personNetwork) + } + }) + } setActualPlayerIndexData(index) if (playerIndex == thisPlayerIndex){ handleTurnBarTextChange("À vous de jouer") @@ -142,9 +242,10 @@ let cptTour: number = 0 } }) - socket.on("node checked",(id, works, askedIndex, newPlayerIndex) => { + socket.on("node checked",(id, works, askedIndex, newPlayerIndex, socketId) => { const node = nodes.get().find((n) => id == n.id) if (node!=undefined){ + onNodeClick(false) playerIndex = newPlayerIndex if (mapIndexPersons.get(askedIndex)?.find((p) => p.getId() == id) == undefined){ @@ -152,13 +253,19 @@ let cptTour: number = 0 const tab = mapIndexPersons.get(askedIndex) if (p!=undefined && tab != undefined){ tab.push(p) + if (actualPlayerIndex == 0){ + players.forEach((player) => { + if (player instanceof Bot){ + player.newInformation(p, askedIndex, works) + } + }) + } } } if (!node.label.includes(colorToEmoji(positionToColor(askedIndex), works))){ networkData.nodes.update({id: id, label: node.label + colorToEmoji(positionToColor(askedIndex), works)}) } - if (playerIndex === thisPlayerIndex){ handleTurnBarTextChange("À vous de jouer") handleShowTurnBar(true) @@ -167,8 +274,10 @@ let cptTour: number = 0 handleShowTurnBar(false) } } + lastSocketId = socketId lastAskingPlayer = 0 lastNodeId = -1 + setLastIndex(newPlayerIndex) }) socket.on("already asked", (nodeId, askedPlayer) =>{ @@ -177,13 +286,14 @@ let cptTour: number = 0 socket.on("asked wrong", () =>{ askedWrong = true + askedWrongBot=true handleShowTurnBar(true) handleTurnBarTextChange("Mauvais choix, posez un carré !") socket.emit("put grey background", socket.id, thisPlayerIndex) }) - socket.on("asked", (nodeId, askingPlayer, askingPlayerIndex) => { + socket.on("asked", (nodeId, askingPlayer) => { if (askingPlayer.id !== lastAskingPlayer || nodeId !== lastNodeId ){ lastAskingPlayer = askingPlayer.id lastNodeId = nodeId @@ -199,20 +309,30 @@ let cptTour: number = 0 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)){ + playerIndex = playerIndex + 1 + if(playerIndex == players.length){ + playerIndex = 0 + } socket.emit("node checked", nodeId, true, thisPlayerIndex, room, playerIndex) } else{ - maybe = maybe - 1 + maybe = thisPlayerIndex - 1 if(maybe == 0){ maybe = players.length - 1 } - socket.emit("node checked", nodeId, false, thisPlayerIndex, room, maybe) - socket.emit("asked wrong", askingPlayer, room) + let index = players.findIndex((p) => p.id == askingPlayer.id) + if (players[index] instanceof Bot){ + index = playerIndex + 1 + if(index == players.length){ + index = 0 + } + } + if (index != undefined){ + socket.emit("node checked", nodeId, false, thisPlayerIndex, room, index) + socket.emit("asked wrong", askingPlayer, room) + } + } } } @@ -327,8 +447,24 @@ let cptTour: number = 0 } } else if(touchedPlayer != -1 && playerIndex == actualPlayerIndex && touchedPlayer p.getId() == params.nodes[0]) + if (person != undefined){ + if (test.Works(person)){ + let nextPlayerIndex = actualPlayerIndex + 1 + if (nextPlayerIndex == players.length){ + nextPlayerIndex = 0 + } + socket.emit("node checked", params.nodes[0], true, touchedPlayer, room, nextPlayerIndex) + } + else{ + socket.emit("node checked", params.nodes[0], false, touchedPlayer, room, actualPlayerIndex) + socket.emit("asked wrong", players[actualPlayerIndex]) + } + } } else{ socket.emit("ask player", params.nodes[0], players[touchedPlayer].id, players.find((p) => p.id === socket.id, actualPlayerIndex)) @@ -337,6 +473,7 @@ let cptTour: number = 0 } } else if(playerIndex == actualPlayerIndex && touchedPlayer==players.length){ + botIndex = -1 const person = personNetwork?.getPersons().find((p) => p.getId() == params.nodes[0]) if (person != undefined){ const indiceTester = IndiceTesterFactory.Create(indices[actualPlayerIndex]) @@ -347,7 +484,8 @@ let cptTour: number = 0 let playerIndex = actualPlayerIndex + 1 if (indiceTester.Works(person)){ - socket.emit("node checked", params.nodes[0], true, actualPlayerIndex, room, nextPlayerIndex) + let i = 0 + socket.emit("node checked", params.nodes[0], true, actualPlayerIndex, room, actualPlayerIndex) while(playerIndex != actualPlayerIndex){ if (playerIndex == players.length){ playerIndex = 0 @@ -356,18 +494,28 @@ let cptTour: number = 0 const works = tester.Works(person) await delay(500); socket.emit("asked all 1by1", person.getId(), players[playerIndex].id) - socket.emit("node checked", params.nodes[0], works, playerIndex, room, nextPlayerIndex) + if (works){ + socket.emit("node checked", params.nodes[0], true, playerIndex, room, actualPlayerIndex) + } if(!works){ + socket.emit("node checked", params.nodes[0], works, playerIndex, room, nextPlayerIndex) socket.emit("put correct background", socket.id) touchedPlayer=-1 return } + if (i == players.length - 1){ + socket.emit("put correct background", socket.id) + await delay(1000) + socket.emit("end game", actualPlayerIndex, room) + return + } playerIndex ++ + i++ } touchedPlayer=-1 socket.emit("put correct background", socket.id) await delay(1000) - socket.emit("end game", thisPlayerIndex, room) + socket.emit("end game", actualPlayerIndex, room) } } } diff --git a/cryptide_project/src/Components/PersonStatus.tsx b/cryptide_project/src/Components/PersonStatus.tsx index 959b23b..a66429d 100644 --- a/cryptide_project/src/Components/PersonStatus.tsx +++ b/cryptide_project/src/Components/PersonStatus.tsx @@ -31,7 +31,6 @@ const PersonStatus: React.FC = ({img = Person, state= Person, const [touchedPlayer, setTouchedPlayer] = useState(-2) useEffect(() =>{ setTouchedPlayer(playerTouched) - console.log(touchedPlayer) }, [playerTouched]) return (
setPlayerTouched(index)}> diff --git a/cryptide_project/src/Pages/Lobby.tsx b/cryptide_project/src/Pages/Lobby.tsx index f977e29..54bd477 100644 --- a/cryptide_project/src/Pages/Lobby.tsx +++ b/cryptide_project/src/Pages/Lobby.tsx @@ -5,7 +5,6 @@ import { useTheme } from '../Style/ThemeContext'; /* res */ import PlayerItemList from '../Components/PlayerItemList' import PersonImg from '../res/img/Person.png'; -import Bot from '../res/img/bot.png'; import param from '../res/icon/param.png'; import cible from '../res/icon/cible.png'; @@ -25,6 +24,7 @@ import { random } from 'lodash'; import Player from '../model/Player'; import Human from '../model/Human'; import EasyBot from '../model/EasyBot'; +import Bot from '../model/Bot'; @@ -61,19 +61,20 @@ function Lobby() { const network: PersonNetwork = JSONParser.JSONToNetwork(jsonNetwork) const choosenOne: Person = network.getPersons().filter((i) => i.getId() == jsonPerson.id)[0] const choosenIndices : Indice[] = JSONParser.JSONToIndices(jsonIndicesString) - let index = 0 for (let i=0; i[]> + constructor( id: string, name: string){ super(id, name); + this.actualNetwork = new Map[]>() + this.index = -1 + } - abstract playRound(personNetwork : PersonNetwork, players: Player): [number, boolean] + abstract playRound(personNetwork : PersonNetwork, players: Player[]): [number, number] + + abstract placeSquare(personNetwork : PersonNetwork, players: Player[]): number + + abstract newInformation(person: Person, playerIndex: number, works: boolean): void + + abstract initiateMap(personNetwork: PersonNetwork): void } export default Bot \ No newline at end of file diff --git a/cryptide_project/src/model/EasyBot.ts b/cryptide_project/src/model/EasyBot.ts index 89fa803..cb5f38f 100644 --- a/cryptide_project/src/model/EasyBot.ts +++ b/cryptide_project/src/model/EasyBot.ts @@ -1,12 +1,16 @@ +import { DataSet } from "vis-network"; +import { colorToEmoji, positionToColor } from "../ColorHelper"; import Bot from "./Bot"; +import IndiceTesterFactory from "./Factory/IndiceTesterFactory"; +import NodePerson from "./Graph/NodePerson"; import Indice from "./Indices/Indice"; +import Pair from "./Pair"; +import Person from "./Person"; import PersonNetwork from "./PersonsNetwork"; import Player from "./Player"; class EasyBot extends Bot{ - public indice: Indice | undefined - constructor(id: string, name: string){ super(id, name) } @@ -19,8 +23,86 @@ class EasyBot extends Bot{ }; } - playRound(personNetwork: PersonNetwork, players: Player): [number, boolean] { - return [1, false] + playRound(personNetwork: PersonNetwork, players: Player[]): [number, number] { + if (this.indice==undefined){ + return [-1, -1] + } + let rand = Math.random() + const filterPlayers = players.filter((p) => p.id != this.id) + if (rand < 0.75){ + const possibleCombinaison = new Map() + filterPlayers.forEach((p, index) =>{ + possibleCombinaison.set(index, []) + }) + personNetwork.getPersons().forEach((p) =>{ + players.forEach((player, index) =>{ + if (index!=this.index && (!this.actualNetwork.get(p)?.includes(new Pair(index, true) || !this.actualNetwork.get(p)?.includes(new Pair(index, false))))){ + const t = possibleCombinaison.get(index) + if( t==undefined){ + possibleCombinaison.set(index, [p.getId()]) + } + else{ + t.push(p.getId()) + } + } + }) + }) + let r = this.index + while(r==this.index){ + r = Math.floor(Math.random() * players.length) + } + const tab = possibleCombinaison.get(r) + if (tab!= undefined){ + const randIndex = Math.floor(Math.random() * tab.length) + const tester = IndiceTesterFactory.Create(this.indice) + const pers = personNetwork.getPersons().find((p) => p.getId() == tab[randIndex]) + if (pers != undefined) + return [r, tab[randIndex]] + } + } + else{ + const filterNodes = [] + const possibleNodes: number[] = [] + const indiceTester=IndiceTesterFactory.Create(this.indice) + personNetwork.getPersons().forEach((p) => { + let works = true + for(let i = 0; i{ + const tab = this.actualNetwork.get(p) + if (!indiceTester.Works(p) && (!tab?.includes(new Pair(this.index, true) || !tab?.includes(new Pair(this.index, false))))){ + tabFilterPerson.push(p) + } + }) + return tabFilterPerson[Math.floor(Math.random() * tabFilterPerson.length)].getId() + } + + newInformation(person: Person, playerIndex: number, works: boolean): void { + this.actualNetwork.get(person)?.push(new Pair(playerIndex, works)) + } + initiateMap(personNetwork: PersonNetwork): void { + personNetwork.getPersons().forEach((p) =>{ + this.actualNetwork.set(p, []) + }) } } diff --git a/cryptide_project/src/model/NetworkGenerator.ts b/cryptide_project/src/model/NetworkGenerator.ts index 41584e7..a4bb545 100644 --- a/cryptide_project/src/model/NetworkGenerator.ts +++ b/cryptide_project/src/model/NetworkGenerator.ts @@ -7,7 +7,7 @@ class NetworkGenerator{ static GenerateNetwork(nbPerson: number): PersonNetwork{ let json = require("../res/names.json") - const tabSports: Sport[] = [0, 1, 2, 3, 4, 5, 5, 5, 5] + const tabSports: Sport[] = [0, 1, 2, 3, 4, 5, 5, 5] const tabColor: Color[] = [0, 1, 2, 3, 4] const tabJeune: number[] = [] const tabAdo: number[] = [] diff --git a/cryptide_project/src/model/Pair.ts b/cryptide_project/src/model/Pair.ts new file mode 100644 index 0000000..1e56a7f --- /dev/null +++ b/cryptide_project/src/model/Pair.ts @@ -0,0 +1,15 @@ +class Pair{ + public first: T1 + public second: T2 + + constructor(first: T1, second: T2){ + this.first=first + this.second=second + } + + equals(other: Pair): boolean { + return this.first === other.first && this.second === other.second; + } +} + +export default Pair \ No newline at end of file