game_api.py 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. from functools import wraps
  2. import uuid
  3. from flask import Blueprint, abort, request, jsonify
  4. from db import db, Game, CoordSet, GuessSet, create_game
  5. from lib import generate_coord, score
  6. game = Blueprint("game", __name__)
  7. def require_name():
  8. name = request.headers.get("Authorization", type=str)
  9. if name is None:
  10. abort(401)
  11. return name.split(maxsplit=1)[-1]
  12. def require_game(game_id):
  13. g = Game.query.get(game_id)
  14. if g is None:
  15. abort(404)
  16. return g
  17. def require_guess_set(game_id):
  18. name = require_name()
  19. gs = GuessSet.query.get((game_id, name))
  20. if gs is None:
  21. abort(404)
  22. return gs
  23. @game.route("", methods=["PUT"])
  24. def create_game():
  25. name = require_name()
  26. timer = request.json.get("timer", None)
  27. if not isinstance(timer, int) or timer <= 0:
  28. abort(400)
  29. new_game = create_game()
  30. return jsonify({"gameId": new_game.game_id})
  31. @game.route("/<game_id>")
  32. def game_settings(game_id):
  33. g = require_game(game_id)
  34. return jsonify(g.to_dict())
  35. @game.route("/<game_id>/join", methods=["POST"])
  36. def join(game_id):
  37. name = require_name()
  38. g = require_game(game_id)
  39. if GuessSet.query.get((g.game_id, name)) is not None:
  40. abort(409)
  41. cs = CoordSet()
  42. db.session.add(cs)
  43. db.session.commit()
  44. gs = GuessSet(game_id=g.game_id, player_name=name, coord_set=cs)
  45. db.session.add(gs)
  46. db.session.commit()
  47. return "", 201
  48. @game.route("/<game_id>/guesses")
  49. def guesses(game_id):
  50. gs = require_guess_set(game_id)
  51. return jsonify({
  52. "currentRound": gs.get_current_round(),
  53. "guesses": gs.to_dict(),
  54. })
  55. @game.route("/<game_id>/guesses/<round_num>", methods=["POST"])
  56. def make_guess(game_id, round_num):
  57. gs = require_guess_set(game_id)
  58. if round_num != gs.get_current_round():
  59. abort(409)
  60. timed_out = request.json.get("timeout", False)
  61. if timed_out:
  62. gs.set_timed_out(round_num)
  63. db.session.commit()
  64. return jsonify({
  65. "score": 0,
  66. "totalScore": gs.get_total_score(),
  67. "distance": None,
  68. }), 201
  69. lat = request.json.get("lat", None)
  70. lng = request.json.get("lng", None)
  71. if not isinstance(lat, float) or not isinstance(lng, float):
  72. abort(400)
  73. target = require_game(game_id).coord_set.get_coord(round_num)
  74. guess_score, distance = score(target, (lat, lng))
  75. gs.set_guess(round_num, lat, lng, guess_score)
  76. db.session.commit()
  77. return jsonify({
  78. "score": guess_score,
  79. "totalScore": gs.get_total_score(),
  80. "distance": distance,
  81. }), 201