diff options
| author | 2026-02-02 00:35:54 +0300 | |
|---|---|---|
| committer | 2026-02-02 00:35:54 +0300 | |
| commit | bfdd73d7324a4f66a16f55d4fb064b0ff08d40e9 (patch) | |
| tree | 27fff9c802dcdd22960bb2e776e58278000d0364 /content/posts/2024-12-12-guessr.md | |
| parent | Поправил шаблон (diff) | |
| download | blog-bfdd73d7324a4f66a16f55d4fb064b0ff08d40e9.tar.gz blog-bfdd73d7324a4f66a16f55d4fb064b0ff08d40e9.tar.bz2 blog-bfdd73d7324a4f66a16f55d4fb064b0ff08d40e9.tar.xz blog-bfdd73d7324a4f66a16f55d4fb064b0ff08d40e9.zip | |
Большая чистка блога
Diffstat (limited to 'content/posts/2024-12-12-guessr.md')
| -rw-r--r-- | content/posts/2024-12-12-guessr.md | 130 |
1 files changed, 0 insertions, 130 deletions
diff --git a/content/posts/2024-12-12-guessr.md b/content/posts/2024-12-12-guessr.md deleted file mode 100644 index 235901c..0000000 --- a/content/posts/2024-12-12-guessr.md +++ /dev/null @@ -1,130 +0,0 @@ ---- -categories: -- Мои проекты -date: '2024-12-12T22:27:49+03:00' -description: '' -image: files/2024-12-12-guessr_logo.webp -location: Казань -tags: -- IT -- Проект выходного дня -title: Guessr ---- - -На недавних выходных я запилил очередной «проект выходного дня». На этот раз — -аналог известного сервиса GeoGuessr, но в отличие от него, все точки -сконцентрированы в моей родной Казани. Ну и я не использую панорамы, а -фотографии мест. - -Я обещал выложить исходники, и в общем, вот они: -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" - } - ``` - -- Получение состояния. Просто возвращает вышеуказанные параметры - ```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) - -```go -err = btx.NewSelect(). - ColumnExpr(`p.guid, p.img`). - Model(r). - Where(`p.count = (SELECT MIN(pl.count) FROM places pl WHERE pl.deleted_at IS NULL)`). - OrderExpr(`RANDOM()`). - Limit(1). - Scan(ctx, r) -``` - -Ещё я бы отметил то, что я решил по максимуму логику вынести в БД, и, например, -при угадывании расстояние до точки, а также вышеупомянутый geojson формируются -так же на стороне БД: -https://git.neonxp.ru/guessr.git/tree/pkg/service/places.go#n50 (стр. 50-59) - -```go -err := p.db.NewSelect(). - Model(&model.Place{GUID: guid}). - WherePK("guid"). - ColumnExpr(`p.name, p.guid, p.img, - ST_Distance(ST_MakePoint(?, ?)::geography, p.position::geography)::int AS distance, - ST_AsGeoJSON(ST_MakeLine( - ST_SetSRID(ST_MakePoint(?, ?), 4326), - ST_SetSRID(p.position, 4326) - )) AS geojson`, lon, lat, lon, lat). - Scan(ctx, r) -``` - -## Дальнейшие планы - -В комментах к анонсу ребята накидали достаточно много хороших идей, синтезировав -которые, и добавив свои хотелки я составил примерно такой чеклист: - -- [ ] Авторизация и общая доска лидерства -- [ ] После угадывания спрашивать у игрока «сложность», чтобы потом можно было, - например, настраивать чтобы попадались только простые объекты. И, например, - разное количество очков за простые и сложные объекты -- [ ] Подумать как вынести игру в оффлайн, по типу того же ингресса. Это сложно - и предстоит хорошо это обдумать - -Как-то так :) А впереди новые выходные и новые «проекты выходного дня»!
\ No newline at end of file |
