db.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import uuid
  2. from flask_sqlalchemy import SQLAlchemy
  3. from lib import generate_coord
  4. db = SQLAlchemy()
  5. session = db.session
  6. class Game(db.Model):
  7. game_id = db.Column(db.String, primary_key=True)
  8. timer = db.Column(db.Integer)
  9. rounds = db.Column(db.Integer)
  10. coordinates = db.relationship("Coordinate", lazy=True, order_by="Coordinate.round_number")
  11. players = db.relationship("Player", lazy=True)
  12. @staticmethod
  13. def create(timer, rounds):
  14. game_id = str(uuid.uuid4())
  15. while Game.query.get(game_id) is not None:
  16. # basically impossible collision, but let's be safe
  17. game_id = str(uuid.uuid4())
  18. new_game = Game(
  19. game_id=game_id,
  20. timer=timer,
  21. rounds=rounds
  22. )
  23. db.session.add(new_game)
  24. for round_num in range(rounds):
  25. (lat, lng) = generate_coord()
  26. coord = Coordinate(
  27. game_id=game_id,
  28. round_number=round_num+1,
  29. latitude=lat,
  30. longitude=lng
  31. )
  32. db.session.add(coord)
  33. db.session.commit()
  34. return new_game
  35. def join(self, player_name):
  36. p = Player(
  37. game_id=self.game_id,
  38. player_name=player_name
  39. )
  40. db.session.add(p)
  41. db.session.commit()
  42. return p
  43. def to_dict(self):
  44. return {
  45. "gameId": self.game_id,
  46. "timer": self.timer,
  47. "rounds": self.rounds,
  48. "coords": {
  49. str(c.round_number): {
  50. "lat": c.latitude,
  51. "lng": c.longitude,
  52. } for c in self.coordinates
  53. },
  54. "players": [p.to_dict() for p in self.players],
  55. }
  56. class Player(db.Model):
  57. player_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
  58. game_id = db.Column(db.String, db.ForeignKey("game.game_id"))
  59. player_name = db.Column(db.String)
  60. guesses = db.relationship("Guess", lazy=True, order_by="Guess.round_number")
  61. def get_total_score(self):
  62. return sum(g.round_score for g in self.guesses)
  63. def get_current_round(self):
  64. if len(self.guesses) == 0:
  65. return 1
  66. next_round = self.guesses[-1].round_number + 1
  67. if next_round <= Game.query.get(self.game_id).rounds:
  68. return next_round
  69. return None
  70. def add_guess(self, round_num, lat, lng, score):
  71. g = Guess(
  72. player_id=self.player_id,
  73. round_number=round_num,
  74. latitude=lat,
  75. longitude=lng,
  76. round_score=score,
  77. )
  78. db.session.add(g)
  79. db.session.commit()
  80. def add_timeout(self, round_num):
  81. self.add_guess(round_num, -200, -200, 0)
  82. def to_dict(self):
  83. return {
  84. "name": self.player_name,
  85. "currentRound": self.get_current_round(),
  86. "totalScore": self.get_total_score(),
  87. "guesses": {
  88. str(g.round_number): {
  89. "lat": g.latitude,
  90. "lng": g.longitude,
  91. "score": g.round_score,
  92. } for g in self.guesses
  93. },
  94. }
  95. class Coordinate(db.Model):
  96. game_id = db.Column(db.String, db.ForeignKey("game.game_id"), primary_key=True)
  97. round_number = db.Column(db.Integer, primary_key=True, autoincrement=False)
  98. latitude = db.Column(db.Float)
  99. longitude = db.Column(db.Float)
  100. class Guess(db.Model):
  101. player_id = db.Column(db.String, db.ForeignKey("player.player_id"), primary_key=True)
  102. round_number = db.Column(db.Integer, primary_key=True, autoincrement=False)
  103. latitude = db.Column(db.Float)
  104. longitude = db.Column(db.Float)
  105. round_score = db.Column(db.Integer)