diff options
Diffstat (limited to 'content/posts/2024-12-12-guessr/index.md')
-rw-r--r-- | content/posts/2024-12-12-guessr/index.md | 132 |
1 files changed, 74 insertions, 58 deletions
diff --git a/content/posts/2024-12-12-guessr/index.md b/content/posts/2024-12-12-guessr/index.md index 8016647..eb1c713 100644 --- a/content/posts/2024-12-12-guessr/index.md +++ b/content/posts/2024-12-12-guessr/index.md @@ -8,65 +8,78 @@ location = "Казань" image="logo.webp" +++ -На недавних выходных я запилил очередной «проект выходного дня». На этот раз — аналог известного сервиса GeoGuessr, но -в отличие от него, все точки сконцентрированы в моей родной Казани. Ну и я не использую панорамы, а фотографии мест. +На недавних выходных я запилил очередной «проект выходного дня». На этот раз — +аналог известного сервиса GeoGuessr, но в отличие от него, все точки +сконцентрированы в моей родной Казани. Ну и я не использую панорамы, а +фотографии мест. -Я обещал выложить исходники, и в общем, вот они: https://git.neonxp.ru/guessr.git/ +Я обещал выложить исходники, и в общем, вот они: +https://git.neonxp.ru/guessr.git/ # Немного про разработку -Первым встал вопрос, откуда брать данные, а именно фотографии и координаты точек. Пару лет назад нашу страну покинул -такой проект, как Ingress, представлявший собой гео игру в дополненной реальности. В свою очередь, я посчитал, что раз -проект решил отказаться от нас, как игроков, я посчитал морально оправданным ~~спиз~~экспропреировать кусочек их данных, -а именно спарсил с их карты intel.ingress.com т.н. «порталы», которые, по сути и есть эти самые геоточки с фотографиями. - -Дамп я загнал в Postgresql с подключенным расширением [Postgis](https://postgis.net/). - -Ну а далее написал достаточно простой API на Golang, который реализует следующие методы: - -- Создание новой игровой сессии, в ответ ставится кука внутри которой зашифровано текущее состояние — ник, количество - очков, ID текущего угадываемого объекта (в начале пустое). - ```http - POST /api/state - Content-Type: application/json - - { - "username": "NeonXP" - } - ``` +Первым встал вопрос, откуда брать данные, а именно фотографии и координаты +точек. Пару лет назад нашу страну покинул такой проект, как Ingress, +представлявший собой гео игру в дополненной реальности. В свою очередь, я +посчитал, что раз проект решил отказаться от нас, как игроков, я посчитал +морально оправданным ~~спиз~~экспропреировать кусочек их данных, а именно +спарсил с их карты intel.ingress.com т.н. «порталы», которые, по сути и есть эти +самые геоточки с фотографиями. + +Дамп я загнал в Postgresql с подключенным расширением +[Postgis](https://postgis.net/). + +Ну а далее написал достаточно простой API на Golang, который реализует следующие +методы: + +- Создание новой игровой сессии, в ответ ставится кука внутри которой + зашифровано текущее состояние — ник, количество очков, ID текущего + угадываемого объекта (в начале пустое). + ```http + POST /api/state + Content-Type: application/json + + { + "username": "NeonXP" + } + ``` - Получение состояния. Просто возвращает вышеуказанные параметры - ```http - GET /api/state - ``` -- Выдача нового объекта для угадывания. При этом возвращается ссылка на фото и обновляется состояние, тем что в него - вписывается ID объекта - ```http - POST /api/next - ``` -- Угадывание. Собственно, на вход передаются координаты куда на карте указал игрок. А в ответ возвращается: - - Название объекта - - Расстояние от переданной точки до реального размещения объекта - - Geojson строка в которой зашифрована линия соединяющая точку и объект (нужна для отрисовки красной линии на карте) - - При этом высчитываются очки которые получает игрок за попытку по формуле max(1000-d, 0), где d - расстояние между - выбранной точкой и объектом в метрах. То есть, если разница меньше 1000м, то чем ближе - тем больше очков (максимум - 1000 очков за 1 очень точное угадывание). - ```http - POST /api/guess - Content-Type: application/json - - { - "lat": 55.123, - "lon": 49.123 - } - ``` + ```http + GET /api/state + ``` +- Выдача нового объекта для угадывания. При этом возвращается ссылка на фото и + обновляется состояние, тем что в него вписывается ID объекта + ```http + POST /api/next + ``` +- Угадывание. Собственно, на вход передаются координаты куда на карте указал + игрок. А в ответ возвращается: + - Название объекта + - Расстояние от переданной точки до реального размещения объекта + - Geojson строка в которой зашифрована линия соединяющая точку и объект (нужна + для отрисовки красной линии на карте) + + При этом высчитываются очки которые получает игрок за попытку по формуле + max(1000-d, 0), где d - расстояние между выбранной точкой и объектом в метрах. + То есть, если разница меньше 1000м, то чем ближе - тем больше очков (максимум + 1000 очков за 1 очень точное угадывание). + ```http + POST /api/guess + Content-Type: application/json + + { + "lat": 55.123, + "lon": 49.123 + } + ``` Вот в общем-то и всё API! -Из интересностей, при выборе очередной точки у неё в БД увеличивается счетчик, а сам select выбирает случайную точку -только среди тех точек, где этот счетчик минимальный. То есть, пока не будут выданы игрокам все точки, уже выбранные -заново не будут выданы. Вот это место в коде: https://git.neonxp.ru/guessr.git/tree/pkg/service/places.go#n26 -(стр. 26-32) +Из интересностей, при выборе очередной точки у неё в БД увеличивается счетчик, а +сам select выбирает случайную точку только среди тех точек, где этот счетчик +минимальный. То есть, пока не будут выданы игрокам все точки, уже выбранные +заново не будут выданы. Вот это место в коде: +https://git.neonxp.ru/guessr.git/tree/pkg/service/places.go#n26 (стр. 26-32) ```go err = btx.NewSelect(). @@ -78,8 +91,9 @@ err = btx.NewSelect(). Scan(ctx, r) ``` -Ещё я бы отметил то, что я решил по максимуму логику вынести в БД, и, например, при угадывании расстояние до точки, а -также вышеупомянутый geojson формируются так же на стороне БД: +Ещё я бы отметил то, что я решил по максимуму логику вынести в БД, и, например, +при угадывании расстояние до точки, а также вышеупомянутый geojson формируются +так же на стороне БД: https://git.neonxp.ru/guessr.git/tree/pkg/service/places.go#n50 (стр. 50-59) ```go @@ -97,12 +111,14 @@ err := p.db.NewSelect(). # Дальнейшие планы -В комментах к анонсу ребята накидали достаточно много хороших идей, синтезировав которые, и добавив свои хотелки я -составил примерно такой чеклист: +В комментах к анонсу ребята накидали достаточно много хороших идей, синтезировав +которые, и добавив свои хотелки я составил примерно такой чеклист: - [ ] Авторизация и общая доска лидерства -- [ ] После угадывания спрашивать у игрока «сложность», чтобы потом можно было, например, настраивать чтобы попадались - только простые объекты. И, например, разное количество очков за простые и сложные объекты -- [ ] Подумать как вынести игру в оффлайн, по типу того же ингресса. Это сложно и предстоит хорошо это обдумать +- [ ] После угадывания спрашивать у игрока «сложность», чтобы потом можно было, + например, настраивать чтобы попадались только простые объекты. И, например, + разное количество очков за простые и сложные объекты +- [ ] Подумать как вынести игру в оффлайн, по типу того же ингресса. Это сложно + и предстоит хорошо это обдумать Как-то так :) А впереди новые выходные и новые «проекты выходного дня»!
\ No newline at end of file |