db.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  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=5):
  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. def to_dict(self):
  43. return {
  44. "gameId": self.game_id,
  45. "timer": self.timer,
  46. "rounds": self.rounds,
  47. "coords": [{
  48. str(c.round_number): {
  49. "lat": c.latitude,
  50. "lng": c.longitude,
  51. }
  52. } for c in self.coordinates],
  53. "players": [p.to_dict() for p in self.players],
  54. }
  55. class Player(db.Model):
  56. player_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
  57. game_id = db.Column(db.String, db.ForeignKey("game.game_id"))
  58. player_name = db.Column(db.String)
  59. guesses = db.relationship("Guess", lazy=True, order_by="Guess.round_number")
  60. def get_total_score(self):
  61. return sum(g.round_score for g in self.guesses)
  62. def get_current_round(self):
  63. if len(self.guesses) == 0:
  64. return 1
  65. next_round = self.guesses[-1].round_number + 1
  66. if next_round <= Game.query.get(self.game_id).rounds:
  67. return next_round
  68. return None
  69. def add_guess(self, round_num, lat, lng, score):
  70. g = Guess(
  71. player_id=self.player_id,
  72. round_number=round_num,
  73. latitude=lat,
  74. longitude=lng,
  75. round_score=score,
  76. )
  77. db.session.add(g)
  78. db.session.commit()
  79. def add_timeout(self, round_num):
  80. self.add_guess(round_num, -200, -200, 0)
  81. def to_dict(self):
  82. return {
  83. "name": self.player_name,
  84. "currentRound": self.get_current_round(),
  85. "totalScore": self.get_total_score(),
  86. "guesses": [{
  87. str(g.round_number): {
  88. "lat": g.latitude,
  89. "lng": g.longitude,
  90. "score": g.round_score,
  91. }
  92. } for g in self.guesses],
  93. }
  94. class Coordinate(db.Model):
  95. game_id = db.Column(db.String, db.ForeignKey("game.game_id"), primary_key=True)
  96. round_number = db.Column(db.Integer, primary_key=True, autoincrement=False)
  97. latitude = db.Column(db.Float)
  98. longitude = db.Column(db.Float)
  99. class Guess(db.Model):
  100. player_id = db.Column(db.String, db.ForeignKey("player.player_id"), primary_key=True)
  101. round_number = db.Column(db.Integer, primary_key=True, autoincrement=False)
  102. latitude = db.Column(db.Float)
  103. longitude = db.Column(db.Float)
  104. round_score = db.Column(db.Integer)