game_api.py 2.5 KB

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