From 02fcbd2f9c8085ce165441c88ab0f65345387d08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C5=91cze=20Bence?= Date: Fri, 19 Mar 2021 23:14:01 +0100 Subject: [PATCH] MAPG-203 prepare GameFlowController for multiplayer --- src/Controller/GameFlowController.php | 153 +++++++++++++++++++++++--- 1 file changed, 135 insertions(+), 18 deletions(-) diff --git a/src/Controller/GameFlowController.php b/src/Controller/GameFlowController.php index e5bdc9b..8a02fbe 100644 --- a/src/Controller/GameFlowController.php +++ b/src/Controller/GameFlowController.php @@ -1,9 +1,13 @@ request = $request; + $this->pdm = new PersistentDataManager(); + $this->multiConnector = new MultiConnector(); + $this->multiRoomRepository = new MultiRoomRepository(); $this->placeRepository = new PlaceRepository(); } - public function getInitialData(): IContent + public function initialData(): IContent { $mapId = (int) $this->request->query('mapId'); $session = $this->request->session(); @@ -32,6 +45,7 @@ class GameFlowController if (!isset($state['currentRound']) || $state['currentRound'] == -1 || $state['currentRound'] >= static::NUMBER_OF_ROUNDS) { $this->startNewGame($state, $mapId); + $session->set('state', $state); } $response = []; @@ -56,7 +70,45 @@ class GameFlowController return new JsonContent($response); } - public function evaluateGuess(): IContent + public function multiInitialData(): IContent + { + $roomId = $this->request->query('roomId'); + $session = $this->request->session(); + + if (!($multiState = $session->get('multiState')) || $multiState['roomId'] !== $roomId) { + return new JsonContent(['error' => 'no_session_found']); + } + + $room = $this->multiRoomRepository->getByRoomId($roomId); + $state = $room->getStateArray(); + $members = $room->getMembersArray(); + + if ($members['owner'] !== $multiState['token']) { + return new JsonContent(['error' => 'not_owner_of_room']); + } + + if ($state['currentRound'] == -1 || $state['currentRound'] >= static::NUMBER_OF_ROUNDS - 1) { + $this->startNewGame($state, $state['mapId']); + $room->setStateArray($state); + $room->setUpdatedDate(new DateTime()); + $this->pdm->saveToDb($room); + } + + $places = []; + foreach ($state['rounds'] as $round) { + $places[] = [ + 'position' => $round['position']->toArray(), + 'panoId' => $round['panoId'], + 'pov' => $round['pov']->toArray() + ]; + } + + $this->multiConnector->sendMessage('start_game', ['roomId' => $roomId, 'places' => $places]); + + return new JsonContent(['ok' => true]); + } + + public function guess(): IContent { $mapId = (int) $this->request->query('mapId'); $session = $this->request->session(); @@ -66,28 +118,23 @@ class GameFlowController } $last = $state['rounds'][$state['currentRound']]; - - $position = $last['position']; $guessPosition = new Position((float) $this->request->post('lat'), (float) $this->request->post('lng')); - - $distance = $this->calculateDistance($position, $guessPosition); - $score = $this->calculateScore($distance, $state['area']); + $result = $this->evalueteGuess($last['position'], $guessPosition, $state['area']); $last['guessPosition'] = $guessPosition; - $last['distance'] = $distance; - $last['score'] = $score; - - $state['rounds'][$state['currentRound']] = $last; - $state['currentRound'] += 1; + $last['distance'] = $result['distance']; + $last['score'] = $result['score']; $response = [ 'result' => [ - 'position' => $position->toArray(), - 'distance' => $distance, - 'score' => $score + 'position' => $last['position']->toArray(), + 'distance' => $result['distance'], + 'score' => $result['score'] ] ]; + $state['rounds'][$state['currentRound']] = $last; + $state['currentRound'] += 1; if ($state['currentRound'] < static::NUMBER_OF_ROUNDS) { $next = $state['rounds'][$state['currentRound']]; @@ -102,7 +149,79 @@ class GameFlowController return new JsonContent($response); } - private function startNewGame(array &$state, int $mapId) + public function multiGuess(): IContent + { + $roomId = $this->request->query('roomId'); + $session = $this->request->session(); + + if (!($multiState = $session->get('multiState')) || $multiState['roomId'] !== $roomId) { + return new JsonContent(['error' => 'no_session_found']); + } + + $room = $this->multiRoomRepository->getByRoomId($roomId); + $state = $room->getStateArray(); + + $last = $state['rounds'][$state['currentRound']]; + $guessPosition = new Position((float) $this->request->post('lat'), (float) $this->request->post('lng')); + $result = $this->evalueteGuess($last['position'], $guessPosition, $state['area']); + + $this->multiConnector->sendMessage('guess', [ + 'roomId' => $roomId, + 'token' => $multiState['token'], + 'guess' => $guessPosition->toArray(), + 'distance' => $result['distance'], + 'score' => $result['score'] + ]); + + $response = [ + 'result' => [ + 'position' => $last['position']->toArray(), + 'distance' => $result['distance'], + 'score' => $result['score'] + ] + ]; + + return new JsonContent($response); + } + + public function multiNextRound(): IContent + { + $roomId = $this->request->query('roomId'); + $session = $this->request->session(); + + if (!($multiState = $session->get('multiState')) || $multiState['roomId'] !== $roomId) { + return new JsonContent(['error' => 'no_session_found']); + } + + $room = $this->multiRoomRepository->getByRoomId($roomId); + $state = $room->getStateArray(); + $members = $room->getMembersArray(); + + if ($members['owner'] !== $multiState['token']) { + return new JsonContent(['error' => 'not_owner_of_room']); + } + + $state['currentRound'] += 1; + if ($state['currentRound'] < static::NUMBER_OF_ROUNDS) { + $this->multiConnector->sendMessage('next_round', ['roomId' => $roomId, 'currentRound' => $state['currentRound']]); + } + + $room->setStateArray($state); + $room->setUpdatedDate(new DateTime()); + $this->pdm->saveToDb($room); + + return new JsonContent(['ok' => true]); + } + + private function evalueteGuess(Position $realPosition, Position $guessPosition, float $area) + { + $distance = $this->calculateDistance($realPosition, $guessPosition); + $score = $this->calculateScore($distance, $area); + + return ['distance' => $distance, 'score' => $score]; + } + + private function startNewGame(array &$state, int $mapId): void { $places = $this->placeRepository->getRandomNForMapWithValidPano($mapId, static::NUMBER_OF_ROUNDS); @@ -117,8 +236,6 @@ class GameFlowController 'pov' => $place->getPov() ]; } - - $this->request->session()->set('state', $state); } private function calculateDistance(Position $realPosition, Position $guessPosition): float