aboutsummaryrefslogtreecommitdiff
path: root/content/posts/2024-12-12-guessr/index.md
diff options
context:
space:
mode:
Diffstat (limited to 'content/posts/2024-12-12-guessr/index.md')
-rw-r--r--content/posts/2024-12-12-guessr/index.md132
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