import uuid from flask_sqlalchemy import SQLAlchemy from lib import generate_coord db = SQLAlchemy() session = db.session class Game(db.Model): game_id = db.Column(db.String, primary_key=True) timer = db.Column(db.Integer) rounds = db.Column(db.Integer) coordinates = db.relationship("Coordinate", lazy=True, order_by="Coordinate.round_number") players = db.relationship("Player", lazy=True) @staticmethod def create(timer, creator, rounds=5): game_id = str(uuid.uuid4()) while Game.query.get(game_id) is not None: # basically impossible collision, but let's be safe game_id = str(uuid.uuid4()) new_game = Game( game_id=game_id, timer=timer, rounds=rounds ) db.session.add(new_game) for round_num in range(rounds): (lat, lng) = generate_coord() coord = Coordinate( game_id=game_id, round_number=round_num+1, latitude=lat, longitude=lng ) db.session.add(coord) new_game.join(creator) # commits the session return new_game def join(self, player_name): p = Player( game_id=self.game_id, player_name=player_name ) db.session.add(p) db.session.commit() def to_dict(self): return { "gameId": self.game_id, "timer": self.timer, "rounds": self.rounds, "coords": [{ str(c.round_number): { "lat": c.latitude, "lng": c.longitude, } } for c in self.coordinates], "players": [p.to_dict() for p in self.players], } class Player(db.Model): player_id = db.Column(db.Integer, primary_key=True, autoincrement=True) game_id = db.Column(db.String, db.ForeignKey("game.game_id")) player_name = db.Column(db.String) guesses = db.relationship("Guess", lazy=True, order_by="Guess.round_number") def get_total_score(self): return sum(g.round_score for g in self.guesses) def get_current_round(self): if len(self.guesses) == 0: return 1 next_round = self.guesses[-1].round_number + 1 if next_round <= Game.query.get(self.game_id).rounds: return next_round return None def add_guess(self, round_num, lat, lng, score): g = Guess( player_id=self.player_id, round_number=round_num, latitude=lat, longitude=lng, round_score=score, ) db.session.add(g) db.session.commit() def add_timeout(self, round_num): self.add_guess(round_num, -200, -200, 0) def to_dict(self): return { "name": self.player_name, "currentRound": self.get_current_round(), "totalScore": self.get_total_score(), "guesses": [{ str(g.round_number): { "lat": g.latitude, "lng": g.longitude, "score": g.round_score, } } for g in self.guesses], } class Coordinate(db.Model): game_id = db.Column(db.String, db.ForeignKey("game.game_id"), primary_key=True) round_number = db.Column(db.Integer, primary_key=True, autoincrement=False) latitude = db.Column(db.Float) longitude = db.Column(db.Float) class Guess(db.Model): player_id = db.Column(db.String, db.ForeignKey("player.player_id"), primary_key=True) round_number = db.Column(db.Integer, primary_key=True, autoincrement=False) latitude = db.Column(db.Float) longitude = db.Column(db.Float) round_score = db.Column(db.Integer)