feature/MAPG-203-initial-multiplayer-implementation #5

Merged
bence merged 4 commits from feature/MAPG-203-initial-multiplayer-implementation into develop 2021-03-15 12:32:54 +01:00
4 changed files with 49 additions and 55 deletions

View File

@ -26,7 +26,7 @@
}); });
Game.map.fitBounds(mapBounds); Game.map.fitBounds(mapBounds);
MapGuesser.httpRequest('GET', '/game/' + mapId + '/newPlace.json', function () { MapGuesser.httpRequest('GET', '/game/' + mapId + '/initialData.json', function () {
document.getElementById('loading').style.visibility = 'hidden'; document.getElementById('loading').style.visibility = 'hidden';
document.getElementById('panoCover').style.visibility = 'hidden'; document.getElementById('panoCover').style.visibility = 'hidden';
@ -35,8 +35,8 @@
return; return;
} }
Game.panoId = this.response.panoId; Game.panoId = this.response.place.panoId;
Game.pov = this.response.pov; Game.pov = this.response.place.pov;
if (this.response.history) { if (this.response.history) {
for (var i = 0; i < this.response.history.length; ++i) { for (var i = 0; i < this.response.history.length; ++i) {
@ -200,8 +200,13 @@
document.getElementById('showSummaryButton').style.display = 'block'; document.getElementById('showSummaryButton').style.display = 'block';
} }
Game.panoId = this.response.panoId; if (this.response.newPlace) {
Game.pov = this.response.pov; Game.panoId = this.response.newPlace.panoId;
Game.pov = this.response.newPlace.pov;
} else {
Game.panoId = null;
Game.pov = null;
}
}, data); }, data);
}, },

View File

@ -4,7 +4,6 @@ use MapGuesser\Interfaces\Request\IRequest;
use MapGuesser\Util\Geo\Position; use MapGuesser\Util\Geo\Position;
use MapGuesser\Response\JsonContent; use MapGuesser\Response\JsonContent;
use MapGuesser\Interfaces\Response\IContent; use MapGuesser\Interfaces\Response\IContent;
use MapGuesser\PersistentData\Model\Place;
use MapGuesser\Repository\PlaceRepository; use MapGuesser\Repository\PlaceRepository;
class GameFlowController class GameFlowController
@ -22,10 +21,9 @@ class GameFlowController
$this->placeRepository = new PlaceRepository(); $this->placeRepository = new PlaceRepository();
} }
public function getNewPlace(): IContent public function getInitialData(): IContent
{ {
$mapId = (int) $this->request->query('mapId'); $mapId = (int) $this->request->query('mapId');
$session = $this->request->session(); $session = $this->request->session();
if (!($state = $session->get('state')) || $state['mapId'] !== $mapId) { if (!($state = $session->get('state')) || $state['mapId'] !== $mapId) {
@ -33,16 +31,15 @@ class GameFlowController
} }
if (count($state['rounds']) === 0) { if (count($state['rounds']) === 0) {
$placesWithoutPano = []; $place = $this->selectNewPlace($state, $mapId);
$place = $this->placeRepository->getRandomForMapWithValidPano($mapId, [], $placesWithoutPano);
$this->addNewRoundToState($state, $place, $placesWithoutPano);
$session->set('state', $state); $session->set('state', $state);
$data = [ $data = [
'place' => [
'panoId' => $place->getPanoIdCached(), 'panoId' => $place->getPanoIdCached(),
'pov' => $place->getPov()->toArray() 'pov' => $place->getPov()->toArray()
]
]; ];
} else { } else {
$rounds = count($state['rounds']); $rounds = count($state['rounds']);
@ -61,10 +58,12 @@ class GameFlowController
$data = [ $data = [
'history' => $history, 'history' => $history,
'place' => [
'panoId' => $last['panoId'], 'panoId' => $last['panoId'],
'pov' => isset($last['pov']) ? // should be checked not to break with old sessions 'pov' => isset($last['pov']) ? // should be checked not to break with old sessions
$last['pov']->toArray() : $last['pov']->toArray() :
['heading' => 0.0, 'pitch' => 0.0, 'zoom' => 0.0], ['heading' => 0.0, 'pitch' => 0.0, 'zoom' => 0.0]
]
]; ];
} }
@ -74,7 +73,6 @@ class GameFlowController
public function evaluateGuess(): IContent public function evaluateGuess(): IContent
{ {
$mapId = (int) $this->request->query('mapId'); $mapId = (int) $this->request->query('mapId');
$session = $this->request->session(); $session = $this->request->session();
if (!($state = $session->get('state')) || $state['mapId'] !== $mapId) { if (!($state = $session->get('state')) || $state['mapId'] !== $mapId) {
@ -94,49 +92,43 @@ class GameFlowController
$last['score'] = $score; $last['score'] = $score;
$state['rounds'][count($state['rounds']) - 1] = $last; $state['rounds'][count($state['rounds']) - 1] = $last;
if (count($state['rounds']) < static::NUMBER_OF_ROUNDS) { $response = [
$exclude = [];
foreach ($state['rounds'] as $round) {
$exclude = array_merge($exclude, $round['placesWithoutPano'], [$round['placeId']]);
}
$placesWithoutPano = [];
$place = $this->placeRepository->getRandomForMapWithValidPano($mapId, $exclude, $placesWithoutPano);
$this->addNewRoundToState($state, $place, $placesWithoutPano);
$panoId = $place->getPanoIdCached();
$pov = $place->getPov()->toArray();
} else {
$state['rounds'] = [];
$panoId = null;
$pov = null;
}
$session->set('state', $state);
return new JsonContent([
'result' => [ 'result' => [
'position' => $position->toArray(), 'position' => $position->toArray(),
'distance' => $distance, 'distance' => $distance,
'score' => $score 'score' => $score
], ]
'panoId' => $panoId, ];
'pov' => $pov
]); if (count($state['rounds']) < static::NUMBER_OF_ROUNDS) {
$place = $this->selectNewPlace($state, $mapId);
$response['newPlace'] = [
'panoId' => $place->getPanoIdCached(),
'pov' => $place->getPov()->toArray()
];
} else {
$state['rounds'] = [];
} }
private function addNewRoundToState(array &$state, Place $place, array $placesWithoutPano): void $session->set('state', $state);
return new JsonContent($response);
}
private function selectNewPlace(array &$state, int $mapId)
{ {
$exclude = array_column($state['rounds'], 'placeId');
$place = $this->placeRepository->getRandomForMapWithValidPano($mapId, $exclude);
$state['rounds'][] = [ $state['rounds'][] = [
'placesWithoutPano' => $placesWithoutPano,
'placeId' => $place->getId(), 'placeId' => $place->getId(),
'position' => $place->getPosition(), 'position' => $place->getPosition(),
'panoId' => $place->getPanoIdCached(), 'panoId' => $place->getPanoIdCached(),
'pov' => $place->getPov() 'pov' => $place->getPov()
]; ];
return $place;
} }
private function calculateDistance(Position $realPosition, Position $guessPosition): float private function calculateDistance(Position $realPosition, Position $guessPosition): float

View File

@ -29,17 +29,14 @@ class PlaceRepository
} }
//TODO: use Map instead of id //TODO: use Map instead of id
public function getRandomForMapWithValidPano(int $mapId, array $exclude = [], array &$placesWithoutPano): Place public function getRandomForMapWithValidPano(int $mapId, array $exclude = []): Place
{ {
$placesWithoutPano = [];
do { do {
$place = $this->selectRandomFromDbForMap($mapId, $exclude); $place = $this->selectRandomFromDbForMap($mapId, $exclude);
$panoId = $place->getFreshPanoId(); $panoId = $place->getFreshPanoId();
if ($panoId === null) { if ($panoId === null) {
$placesWithoutPano[] = $exclude[] = $place->getId(); $exclude[] = $place->getId();
} }
} while ($panoId === null); } while ($panoId === null);

View File

@ -51,7 +51,7 @@ Container::$routeCollection->group('account', function (MapGuesser\Routing\Route
Container::$routeCollection->group('game', function (MapGuesser\Routing\RouteCollection $routeCollection) { Container::$routeCollection->group('game', function (MapGuesser\Routing\RouteCollection $routeCollection) {
$routeCollection->get('game', '{mapId}', [MapGuesser\Controller\GameController::class, 'getGame']); $routeCollection->get('game', '{mapId}', [MapGuesser\Controller\GameController::class, 'getGame']);
$routeCollection->get('game-json', '{mapId}/json', [MapGuesser\Controller\GameController::class, 'getGameJson']); $routeCollection->get('game-json', '{mapId}/json', [MapGuesser\Controller\GameController::class, 'getGameJson']);
$routeCollection->get('newPlace-json', '{mapId}/newPlace.json', [MapGuesser\Controller\GameFlowController::class, 'getNewPlace']); $routeCollection->get('initialData-json', '{mapId}/initialData.json', [MapGuesser\Controller\GameFlowController::class, 'getInitialData']);
$routeCollection->post('guess-json', '{mapId}/guess.json', [MapGuesser\Controller\GameFlowController::class, 'evaluateGuess']); $routeCollection->post('guess-json', '{mapId}/guess.json', [MapGuesser\Controller\GameFlowController::class, 'evaluateGuess']);
}); });
Container::$routeCollection->group('admin', function (MapGuesser\Routing\RouteCollection $routeCollection) { Container::$routeCollection->group('admin', function (MapGuesser\Routing\RouteCollection $routeCollection) {