from flask_sqlalchemy import SQLAlchemy db = SQLAlchemy() class Game(db.Model): game_id = db.Column(db.String, primary_key=True) timer = db.Column(db.Integer) creator = db.Column(db.String) coord_id = db.Column(db.Integer, db.ForeignKey("coord_set.coord_id")) coord_set = db.relationship("CoordSet") guess_sets = db.relationship("GuessSet", backref="game", lazy=True) def __str__(self): return f"Game({self.game_id}, {self.timer})" class CoordSet(db.Model): coord_id = db.Column(db.Integer, primary_key=True) coord_1 = db.Column(db.String) coord_2 = db.Column(db.String) coord_3 = db.Column(db.String) coord_4 = db.Column(db.String) coord_5 = db.Column(db.String) def to_dict(self): to_return = {} for r, c in zip("12345", (self.coord_1, self.coord_2, self.coord_3, self.coord_4, self.coord_5)): if c is None: continue lat, lng = c.split(",") to_return[r] = { "lat": float(lat), "lng": float(lng) } return to_return def get_coord(self, round_num): # TODO this logic is a little gross if round_num == "1": c = self.coord_1 elif round_num == "2": c = self.coord_2 elif round_num == "3": c = self.coord_3 elif round_num == "4": c = self.coord_4 elif round_num == "5": c = self.coord_5 else: raise ValueError(f"Invalid round number {round_num}") if c is not None: return tuple(float(x) for x in c.split(",")) # returns None if the selected coord was None def set_coord(self, round_num, lat, lng): # TODO this logic is a little gross if round_num == "1": self.coord_1 = f"{lat},{lng}" elif round_num == "2": self.coord_2 = f"{lat},{lng}" elif round_num == "3": self.coord_3 = f"{lat},{lng}" elif round_num == "4": self.coord_4 = f"{lat},{lng}" elif round_num == "5": self.coord_5 = f"{lat},{lng}" else: raise ValueError(f"Invalid round number {round_num}") class GuessSet(db.Model): game_id = db.Column(db.String, db.ForeignKey( "game.game_id"), primary_key=True) player_name = db.Column(db.String, primary_key=True) coord_id = db.Column(db.Integer, db.ForeignKey("coord_set.coord_id")) coord_set = db.relationship("CoordSet") score_1 = db.Column(db.Integer) score_2 = db.Column(db.Integer) score_3 = db.Column(db.Integer) score_4 = db.Column(db.Integer) score_5 = db.Column(db.Integer) def to_dict(self): c = self.coord_set.to_dict() for r, s in zip("12345", (self.score_1, self.score_2, self.score_3, self.score_4, self.score_5)): if r in c: c[r]["score"] = s else: c[r] = None return c def get_current_round(self): for r, s in zip("12345", (self.score_1, self.score_2, self.score_3, self.score_4, self.score_5)): if s is None: return r # returns None if all rounds completed def get_total_score(self): return ((self.score_1 or 0) + (self.score_2 or 0) + (self.score_3 or 0) + (self.score_4 or 0) + (self.score_5 or 0)) def set_timed_out(self, round_num): self.set_guess(round_num, -200, -200, 0) def set_guess(self, round_num, lat, lng, score): self.coord_set.set_coord(round_num, lat, lng) # TODO this logic is a little gross if round_num == "1": self.score_1 = score elif round_num == "2": self.score_2 = score elif round_num == "3": self.score_3 = score elif round_num == "4": self.score_4 = score elif round_num == "5": self.score_5 = score else: raise ValueError(f"Invalid round number {round_num}")