db.py 3.9 KB

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