diff --git a/src/Controller/GameController.php b/src/Controller/GameController.php index 6d65b2a..8149d7c 100644 --- a/src/Controller/GameController.php +++ b/src/Controller/GameController.php @@ -35,14 +35,14 @@ class GameController private function prepareGame(int $mapId): array { $map = $this->mapRepository->getById($mapId); - $session = $this->request->session(); if (!($state = $session->get('state')) || $state['mapId'] !== $mapId) { $session->set('state', [ 'mapId' => $mapId, 'area' => $map->getArea(), - 'rounds' => [] + 'rounds' => [], + 'currentRound' => -1 ]); } diff --git a/src/Controller/GameFlowController.php b/src/Controller/GameFlowController.php index d6c446a..e5bdc9b 100644 --- a/src/Controller/GameFlowController.php +++ b/src/Controller/GameFlowController.php @@ -30,44 +30,30 @@ class GameFlowController return new JsonContent(['error' => 'no_session_found']); } - if (count($state['rounds']) === 0) { - $place = $this->selectNewPlace($state, $mapId); + if (!isset($state['currentRound']) || $state['currentRound'] == -1 || $state['currentRound'] >= static::NUMBER_OF_ROUNDS) { + $this->startNewGame($state, $mapId); + } - $session->set('state', $state); + $response = []; - $data = [ - 'place' => [ - 'panoId' => $place->getPanoIdCached(), - 'pov' => $place->getPov()->toArray() - ] - ]; - } else { - $rounds = count($state['rounds']); - $last = $state['rounds'][$rounds - 1]; + $last = $state['rounds'][$state['currentRound']]; + $response['place'] = [ + 'panoId' => $last['panoId'], + 'pov' => $last['pov']->toArray() + ]; - $history = []; - for ($i = 0; $i < $rounds - 1; ++$i) { - $round = $state['rounds'][$i]; - $history[] = [ - 'position' => $round['position']->toArray(), - 'guessPosition' => $round['guessPosition']->toArray(), - 'distance' => $round['distance'], - 'score' => $round['score'] - ]; - } - - $data = [ - 'history' => $history, - 'place' => [ - 'panoId' => $last['panoId'], - 'pov' => isset($last['pov']) ? // should be checked not to break with old sessions - $last['pov']->toArray() : - ['heading' => 0.0, 'pitch' => 0.0, 'zoom' => 0.0] - ] + $response['history'] = []; + for ($i = 0; $i < $state['currentRound']; ++$i) { + $round = $state['rounds'][$i]; + $response['history'][] = [ + 'position' => $round['position']->toArray(), + 'guessPosition' => $round['guessPosition']->toArray(), + 'distance' => $round['distance'], + 'score' => $round['score'] ]; } - return new JsonContent($data); + return new JsonContent($response); } public function evaluateGuess(): IContent @@ -79,7 +65,7 @@ class GameFlowController return new JsonContent(['error' => 'no_session_found']); } - $last = $state['rounds'][count($state['rounds']) - 1]; + $last = $state['rounds'][$state['currentRound']]; $position = $last['position']; $guessPosition = new Position((float) $this->request->post('lat'), (float) $this->request->post('lng')); @@ -90,7 +76,9 @@ class GameFlowController $last['guessPosition'] = $guessPosition; $last['distance'] = $distance; $last['score'] = $score; - $state['rounds'][count($state['rounds']) - 1] = $last; + + $state['rounds'][$state['currentRound']] = $last; + $state['currentRound'] += 1; $response = [ 'result' => [ @@ -100,15 +88,13 @@ class GameFlowController ] ]; - if (count($state['rounds']) < static::NUMBER_OF_ROUNDS) { - $place = $this->selectNewPlace($state, $mapId); + if ($state['currentRound'] < static::NUMBER_OF_ROUNDS) { + $next = $state['rounds'][$state['currentRound']]; - $response['newPlace'] = [ - 'panoId' => $place->getPanoIdCached(), - 'pov' => $place->getPov()->toArray() + $response['place'] = [ + 'panoId' => $next['panoId'], + 'pov' => $next['pov']->toArray() ]; - } else { - $state['rounds'] = []; } $session->set('state', $state); @@ -116,19 +102,23 @@ class GameFlowController return new JsonContent($response); } - private function selectNewPlace(array &$state, int $mapId) + private function startNewGame(array &$state, int $mapId) { - $exclude = array_column($state['rounds'], 'placeId'); - $place = $this->placeRepository->getRandomForMapWithValidPano($mapId, $exclude); + $places = $this->placeRepository->getRandomNForMapWithValidPano($mapId, static::NUMBER_OF_ROUNDS); - $state['rounds'][] = [ - 'placeId' => $place->getId(), - 'position' => $place->getPosition(), - 'panoId' => $place->getPanoIdCached(), - 'pov' => $place->getPov() - ]; + $state['rounds'] = []; + $state['currentRound'] = 0; - return $place; + foreach ($places as $place) { + $state['rounds'][] = [ + 'placeId' => $place->getId(), + 'position' => $place->getPosition(), + 'panoId' => $place->getPanoIdCached(), + 'pov' => $place->getPov() + ]; + } + + $this->request->session()->set('state', $state); } private function calculateDistance(Position $realPosition, Position $guessPosition): float diff --git a/src/Repository/PlaceRepository.php b/src/Repository/PlaceRepository.php index e12cb0b..84c90cf 100644 --- a/src/Repository/PlaceRepository.php +++ b/src/Repository/PlaceRepository.php @@ -28,6 +28,21 @@ class PlaceRepository yield from $this->pdm->selectMultipleFromDb($select, Place::class); } + //TODO: use Map instead of id + public function getRandomNForMapWithValidPano(int $mapId, int $n, array $exclude = []): array + { + $places = []; + + for ($i = 1; $i <= $n; ++$i) { + $place = $this->getRandomForMapWithValidPano($mapId, $exclude); + + $places[] = $place; + $exclude[] = $place->getId(); + } + + return $places; + } + //TODO: use Map instead of id public function getRandomForMapWithValidPano(int $mapId, array $exclude = []): Place {