|
@@ -4,7 +4,7 @@ import uuid
|
|
|
from flask import Blueprint, session, abort, request, current_app, jsonify
|
|
|
|
|
|
from db import db, Game, CoordSet, GuessSet
|
|
|
-from lib import generate_coord
|
|
|
+from lib import generate_coord, score
|
|
|
|
|
|
game = Blueprint("game", __name__)
|
|
|
|
|
@@ -23,8 +23,15 @@ def require_game(game_id):
|
|
|
return g
|
|
|
|
|
|
|
|
|
+def require_guess_set(game_id):
|
|
|
+ name = require_name()
|
|
|
+ gs = GuessSet.query.get((game_id, name))
|
|
|
+ if gs is None:
|
|
|
+ abort(404)
|
|
|
+ return gs
|
|
|
+
|
|
|
+
|
|
|
def new_coord_string():
|
|
|
- lat, lng = generate_coord(current_app.config["GOOGLE_API_KEY"])
|
|
|
return f"{lat},{lng}"
|
|
|
|
|
|
|
|
@@ -40,13 +47,14 @@ def create_game():
|
|
|
# basically impossible collision, but let's be safe
|
|
|
game_id = str(uuid.uuid4())
|
|
|
|
|
|
- cs = CoordSet(
|
|
|
- coord_1=new_coord_string(),
|
|
|
- coord_2=new_coord_string(),
|
|
|
- coord_3=new_coord_string(),
|
|
|
- coord_4=new_coord_string(),
|
|
|
- coord_5=new_coord_string()
|
|
|
- )
|
|
|
+ key = current_app.config["GOOGLE_API_KEY"]
|
|
|
+ cs = CoordSet()
|
|
|
+ for round_num in "12345":
|
|
|
+ coord = generate_coord(key)
|
|
|
+ while coord is None:
|
|
|
+ # very unlikely, but it is possible for generate_coord to fail
|
|
|
+ coord = generate_coord(key)
|
|
|
+ cs.set_coord(round_num, *coord)
|
|
|
db.session.add(cs)
|
|
|
db.session.commit()
|
|
|
|
|
@@ -59,6 +67,10 @@ def create_game():
|
|
|
db.session.add(new_game)
|
|
|
db.session.commit()
|
|
|
|
|
|
+ gs = GuessSet(game_id=game_id, player_name=name, coord_set=CoordSet())
|
|
|
+ db.session.add(gs)
|
|
|
+ db.session.commit()
|
|
|
+
|
|
|
return jsonify({
|
|
|
"gameId": game_id
|
|
|
})
|
|
@@ -73,19 +85,58 @@ def game_settings(game_id):
|
|
|
"creator": g.creator,
|
|
|
"timer": g.timer,
|
|
|
"coords": g.coord_set.to_dict(),
|
|
|
- "guesses": [], # TODO
|
|
|
+ "players": [
|
|
|
+ {
|
|
|
+ "name": gs.player_name,
|
|
|
+ "currentRound": gs.get_current_round(),
|
|
|
+ "totalScore": gs.get_total_score(),
|
|
|
+ "guesses": gs.to_dict(),
|
|
|
+ } for gs in g.guess_sets
|
|
|
+ ],
|
|
|
})
|
|
|
|
|
|
|
|
|
-@game.route("/<game_id>/guesses")
|
|
|
-def guesses(game_id):
|
|
|
+@game.route("/<game_id>/join", methods=["POST"])
|
|
|
+def join(game_id):
|
|
|
name = require_name()
|
|
|
g = require_game(game_id)
|
|
|
- return "Unimplemented", 500 # TODO
|
|
|
|
|
|
+ if GuessSet.query.get((g.game_id, name)) is not None:
|
|
|
+ abort(400)
|
|
|
|
|
|
-@game.route("/<game_id>/guesses/<round>", methods=["POST"])
|
|
|
-def make_guess(game_id, round):
|
|
|
- name = require_name()
|
|
|
- g = require_game(game_id)
|
|
|
- return "Unimplemented", 500 # TODO
|
|
|
+ cs = CoordSet()
|
|
|
+ db.session.add(cs)
|
|
|
+ db.session.commit()
|
|
|
+
|
|
|
+ gs = GuessSet(game_id=g.game_id, player_name=name, coord_set=cs)
|
|
|
+ db.session.add(gs)
|
|
|
+ db.session.commit()
|
|
|
+ return "", 201
|
|
|
+
|
|
|
+
|
|
|
+@game.route("/<game_id>/guesses")
|
|
|
+def guesses(game_id):
|
|
|
+ gs = require_guess_set(game_id)
|
|
|
+ return jsonify({
|
|
|
+ "currentRound": gs.get_current_round(),
|
|
|
+ "guesses": gs.to_dict(),
|
|
|
+ })
|
|
|
+
|
|
|
+
|
|
|
+@game.route("/<game_id>/guesses/<round_num>", methods=["POST"])
|
|
|
+def make_guess(game_id, round_num):
|
|
|
+ gs = require_guess_set(game_id)
|
|
|
+ if round_num != gs.get_current_round():
|
|
|
+ abort(400)
|
|
|
+
|
|
|
+ lat = request.json.get("lat", None)
|
|
|
+ lng = request.json.get("lng", None)
|
|
|
+ if not isinstance(lat, float) or not isinstance(lng, float):
|
|
|
+ abort(400)
|
|
|
+
|
|
|
+
|
|
|
+ target = require_game(game_id).coord_set.get_coord(round_num)
|
|
|
+ guess_score = score(target, (lat, lng))
|
|
|
+ gs.set_guess(round_num, lat, lng, guess_score)
|
|
|
+ db.session.commit()
|
|
|
+ return jsonify({"score": guess_score}), 201
|