From 0ad4032a9b26c5809cd340be459a33c7d3fb04f3 Mon Sep 17 00:00:00 2001 From: Quentin Roussel Date: Wed, 10 Apr 2024 19:11:51 +0000 Subject: [PATCH] started working on zone manager for backend --- traque-back/game.js | 9 ++++ traque-back/index.js | 11 +++++ traque-back/package-lock.json | 6 +++ traque-back/package.json | 1 + traque-back/zoneManager.js | 92 +++++++++++++++++++++++++++++++++++ 5 files changed, 119 insertions(+) create mode 100644 traque-back/zoneManager.js diff --git a/traque-back/game.js b/traque-back/game.js index 7898b30..c38f84f 100644 --- a/traque-back/game.js +++ b/traque-back/game.js @@ -11,6 +11,7 @@ export default class Game { constructor() { this.teams = []; this.state = GameState.SETUP; + this.zone = new ZoneManager(null, null) } setState(newState) { @@ -150,4 +151,12 @@ export default class Game { } return false; } + + setZone(newSettings) { + //cannot change zones while playing + if(game.state == GameState.PLAYING || game.state == GameState.FINISHED) { + return false; + } + this.zone.udpateSettings(newSettings) + } } \ No newline at end of file diff --git a/traque-back/index.js b/traque-back/index.js index b2aa8b2..21f488a 100644 --- a/traque-back/index.js +++ b/traque-back/index.js @@ -95,6 +95,17 @@ io.of("admin").on("connection", (socket) => { } }); + socket.on("set_zone", (zone) => { + if (!loggedIn) { + socket.emit("error", "Not logged in"); + return; + } + if(!game.setZone(zone)) { + socket.emit("error", "Error changing zone"); + } + + }) + //User is attempting to add a new team socket.on("add_team", (teamName) => { if (!loggedIn) { diff --git a/traque-back/package-lock.json b/traque-back/package-lock.json index 1fd6b0b..b4b67cc 100644 --- a/traque-back/package-lock.json +++ b/traque-back/package-lock.json @@ -10,6 +10,7 @@ "license": "ISC", "dependencies": { "dotenv": "^16.4.5", + "random-location": "^1.1.3", "socket.io": "^4.7.5" } }, @@ -174,6 +175,11 @@ "node": ">=0.10.0" } }, + "node_modules/random-location": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/random-location/-/random-location-1.1.3.tgz", + "integrity": "sha512-+9SZa8R0JTfjrdgImCyq4TJRDzGHfUM9qghsA3D7zrMnUaQVn/xIDtFI+yPegJGO7KuIkduNlL8JXqu3M7Au7w==" + }, "node_modules/socket.io": { "version": "4.7.5", "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.5.tgz", diff --git a/traque-back/package.json b/traque-back/package.json index a36a1a9..b437dc0 100644 --- a/traque-back/package.json +++ b/traque-back/package.json @@ -12,6 +12,7 @@ "type": "module", "dependencies": { "dotenv": "^16.4.5", + "random-location": "^1.1.3", "socket.io": "^4.7.5" } } diff --git a/traque-back/zoneManager.js b/traque-back/zoneManager.js new file mode 100644 index 0000000..bb217cf --- /dev/null +++ b/traque-back/zoneManager.js @@ -0,0 +1,92 @@ +import randomLocation, { randomCirclePoint } from 'random-location' +import { isInCircle } from './map_utils'; + +class ZoneManager { + constructor(onZoneUpdate, onNextZoneUpdate) { + //Setings storing where the zone will start, end and how it should evolve + //The zone will start by staying at its mzx value for reductionInterval minutes + //and then reduce during reductionDuration minutes, then wait again... + //The reduction factor is such that after reductionCount the zone will be the min zone + //a call to onZoneUpdate will be made every updateIntervalSeconds when the zone is changing + //a call to onNextZoneUpdate will be made when the zone reduction ends and a new next zone is announced + this.zoneSettings = { + min: {center: null, radius: null}, + max: {center: null, radius: null}, + reductionCount: 2, + reductionDuration: 10, + reductionInterval: 10, + updateIntervalSeconds: 10, + } + this.shrinkFactor = null; + //Live location of the zone + this.currentZone = null; + this.currentDecrement = null; + + //If the zone is shrinking, this is the target of the current shrinking + //If the zone is not shrinking, this will be the target of the next shrinking + this.nextZone = null; + + this.startDate = null; + this.zoneSettings = zoneSettings; + this.started = false; + this.timeoutId = null; + + this.onZoneUpdate = onZoneUpdate; + this.onNextZoneUpdate = onNextZoneUpdate + } + + udpateSettings(newSettings) { + this.zoneSettings = {newSettings, ...this.zoneSettings}; + this.shrinkFactor = Math.pow(this.zoneSettings.min.radius / this.zoneSettings.max.radius, 1/this.zoneSettings.reductionCount) + } + + reset() { + this.currentZoneCount = 0; + } + + start() { + this.started = true; + this.startDate = new Date(); + requestAnimationFrame(tick); + } + + /** + * Get the center of the next zone, this center need to satisfy two properties + * - it needs to be included in the current zone, this means that this new point should lie in the circle of center currentZone.center and radius currentZone.radius - newRadius + * - it needs to include the last zone, which means that the center must lie in the center of center min.center and of radius newRadius - min.radius + * @param newRadius the radius that the new zone will have + * @returns the coordinates of the new center as an object with lat and long fields + */ + getRandomNextCenter(newRadius) { + let ok = false; + let res = null + while(!ok) { + res = randomCirclePoint({latitude: this.currentZone.lat, longitude: this.currentZone.long}, this.currentZone.radius - newRadius); + ok = (isInCircle({lat: res.latitude, long: res.longitude}, this.zoneSettings.min.center, newRadius - this.zoneSettings.min.radius)) + } + return { + lat: res.latitude, + long: res.longitude + } + } + + setNextZone() { + //At this point, nextZone == currentZone, we need to update the next zone, the raidus decrement, and start a timer before the next shrink + + //last zone + if(this.currentZoneCount == this.zoneSettings.currentZoneCount - 1) { + //Copy values + this.nextZone = {center: [...this.zoneSettings.min.center],...this.zoneSettings.min} + }else { + //TODO : compute next zone + this.nextZone.center = this.getRandomNextCenter(this.nextZone.radius * this.shrinkFactor) + this.nextZone.radius *= this.shrinkFactor; + this.timeoutId = setTimeout(() => this.startShrinking(), 1000 * 60 * this.zoneSettings.reductionIntervalMinutes) + } + } + + startShrinking() { + + } + +} \ No newline at end of file