Пример #1
0
    def get_scores(cls):
        """Returns all Scores existing within the application."""
        # Check that user is authenticated
        get_endpoints_current_user()

        scores = Score.query()
        return ScoreForms(scores=[score.to_form() for score in scores])
Пример #2
0
    def get_user_rankings(cls, request):
        """
        Returns a list of UserRank forms ordered in descending order
        by total margin of victory.
        """
        # Ensure user is authenticated
        get_endpoints_current_user()

        users = User.query().order(-User.total_victory_margin)
        return UserRankForms(user_ranks=[user.to_rankform() for user in users])
Пример #3
0
    def get_game(cls, request):
        """Returns an existing game in the application"""
        # First verify the user is authenticated
        get_endpoints_current_user()

        game = get_by_urlsafe(request.urlsafe_game_key, Game)
        if game:
            return game.to_form()
        else:
            raise endpoints.NotFoundException('Game not found!')
Пример #4
0
    def get_user_scores(cls, request):
        """Returns all Scores associated with the current signed-in User"""
        # Check that current user is authenticated
        get_endpoints_current_user()

        user = User.query(User.email == request.email).get()
        if not user:
            raise NotFoundException(
                'A User with that email address does not exist!')

        scores = Score.query(Score.user == user.key)
        return ScoreForms(scores=[score.to_form() for score in scores])
Пример #5
0
    def cancel_game(cls, request):
        """
        Removes a game that is currently in progress from the system. The game
        is specificed by Key, contained in the request, and must belong to the currently
        authenticated user.
        """
        # Get the current user - making sure it's authenticated
        gplus_user = get_endpoints_current_user()
        user = User.query(User.email == gplus_user.email()).get()

        # Get the game specified by key in the request
        game = get_by_urlsafe(request.urlsafe_game_key, Game)

        # Ensure the game exists
        if not game:
            raise endpoints.NotFoundException('Game not found!')

        # Ensure the game is associated to the current user
        if user.key != game.user:
            raise endpoints.ForbiddenException("Cannot cancel another user's game!")

        # Ensure the game is not completed
        if game.game_over:
            raise endpoints.ForbiddenException("Cannot cancel a game that has already been completed!")

        # All good to remove the game from datastore
        game.key.delete()
Пример #6
0
 def query_current_user(cls):
     """Creates a query for the scores of the current user.
     Returns:
         An ndb.Query object bound to the current user. This can be used
         to filter for other properties or order by them.
     """
     current_user = get_endpoints_current_user()
     return cls.query(cls.user == current_user)
Пример #7
0
 def query_current_user(cls):
     """Creates a query for the scores of the current user.
     Returns:
         An ndb.Query object bound to the current user. This can be used
         to filter for other properties or order by them.
     """
     current_user = get_endpoints_current_user()
     return cls.query(cls.user == current_user)
Пример #8
0
    def get_user_games(cls):
        """Returns all of the current User's active games"""
        gplus_user = get_endpoints_current_user()
        user = User.query(User.email == gplus_user.email()).get()

        active_games = Game.query() \
            .filter(Game.user == user.key) \
            .filter(Game.game_over == False)
        return GameForms(games=[game.to_form() for game in active_games])
Пример #9
0
    def get_high_scores(cls, request):
        """
        Returns a list of highscores. The scores are ordered
        in descending order by the margin of victory. In the request,
        the user can specify 'number_of_results' to limit the total
        number of scores returned
        """
        # Check that the current user is authenticated
        get_endpoints_current_user()

        # Get number_of_results limit from request
        number_of_results = request.number_of_results

        if number_of_results < 0:
            raise BadRequestException("Number of results field must be greater than 0!")
        elif number_of_results == 0:
            scores = Score.query().order(-Score.victory_margin)
        else:
            scores = Score.query().order(-Score.victory_margin).fetch(number_of_results)

        return ScoreForms(scores=[score.to_form() for score in scores])
Пример #10
0
    def new_game(cls, request):
        """Creates and returns a new game"""
        gplus_user = get_endpoints_current_user()
        user = User.query(User.email == gplus_user.email()).get()

        if request.total_rounds not in ROUNDS_OPTIONS:
            raise endpoints.BadRequestException('Invalid total number of rounds.'
                                                ' Must be a number contained in the set: {0}.'.format(ROUNDS_OPTIONS))

        game = Game(user=user.key, total_rounds=request.total_rounds, remaining_rounds=request.total_rounds)
        game.put()
        return game.to_form()
Пример #11
0
    def _get_user_profile():
        """Returns User obj from datastore. Will create new one if non-existent."""
        # Ensure user is authenticated with Google+
        gplus_user = get_endpoints_current_user()

        # Attempt to get User from datastore
        user_id = gplus_user.email()
        user_key = ndb.Key(User, user_id)
        user = user_key.get()

        # Create new User in datastore if it doesn't exist
        if not user:
            user = User(
                key=user_key,
                displayName=gplus_user.nickname(),
                email=gplus_user.email()
            )
            user.put()

        return user
Пример #12
0
    def get_game_history(cls, request):
        """
        Returns the round-by-round result of an active or completed Game.
        The game must be associated with the current authenticated user.
        """
        # Get the current user - making sure it's authenticated
        gplus_user = get_endpoints_current_user()
        user = User.query(User.email == gplus_user.email()).get()

        # Get the game specified by key in the request
        game = get_by_urlsafe(request.urlsafe_game_key, Game)

        # Ensure the game exists
        if not game:
            raise endpoints.NotFoundException('Game not found!')

        # Ensure the game is associated to the current user
        if user.key != game.user:
            raise endpoints.ForbiddenException("You may only view the history of your own games!")

        return game.to_gamehistory_form()
Пример #13
0
    def from_form(cls, message):
        """Gets the current user and inserts a score.
        Args:
            message: A ScoreRequestMessage instance to be inserted.
        Returns:
            The Score entity that was inserted.
        """
        current_user = get_endpoints_current_user().key
        opponent = User.query(User.name == message.opponent_name)
        if message.result == 'WIN':
            result = Result.WIN
        elif message.result == 'TIE':
            result = Result.TIE
        else:
            result = Result.LOSE

        entity = cls(user=current_user, opponent=opponent,
            board_state=message.board_state, result=result,
            )
        entity.put()
        return entity
Пример #14
0
    def from_form(cls, message):
        """Gets the current user and inserts a score.
        Args:
            message: A ScoreRequestMessage instance to be inserted.
        Returns:
            The Score entity that was inserted.
        """
        current_user = get_endpoints_current_user().key
        opponent = User.query(User.name == message.opponent_name)
        if message.result == 'WIN':
            result = Result.WIN
        elif message.result == 'TIE':
            result = Result.TIE
        else:
            result = Result.LOSE

        entity = cls(
            user=current_user,
            opponent=opponent,
            board_state=message.board_state,
            result=result,
        )
        entity.put()
        return entity
Пример #15
0
    def play_round(cls, request):
        """
        Simulates a round of Rock Paper Scissors. Returns the current state of the
        game following the simulation.
        """
        # Make sure user is authenticated
        get_endpoints_current_user()

        # Grab the Game instance by the key
        game = get_by_urlsafe(request.urlsafe_game_key, Game)
        if not game:
            raise endpoints.NotFoundException('Game not found!')

        # Ensure the game is not already completed
        if game.game_over:
            raise endpoints.BadRequestException('Game already over!')

        # Generate random move for the CPU
        cpu_move = random.choice(MOVES)
        game.cpu_moves.append(cpu_move)

        # Game logic to determine winner
        user_move = request.move.upper()
        if user_move not in MOVES:
            raise endpoints.BadRequestException('Player moves must be contained in the set: {0}.'.format(MOVES))

        game.user_moves.append(user_move)

        is_tie = False
        user_move_idx = MOVES.index(user_move)
        cpu_move_idx = MOVES.index(cpu_move)

        if user_move_idx == cpu_move_idx:
            is_tie = True
            game.user_won_last_round = None
            game.round_results.append(-1)
        elif (3 + user_move_idx - cpu_move_idx) % 3 == 1:
            game.user_wins += 1
            game.user_won_last_round = True
            game.round_results.append(1)
        else:
            game.cpu_wins += 1
            game.user_won_last_round = False
            game.round_results.append(0)

        # Handle ties - Only decrement the rounds remaining when the round is not a tie
        if is_tie:
            game.total_ties += 1
        else:
            game.remaining_rounds -= 1

        # Add the user and cpu moves to the game state
        game.user_last_move = user_move
        game.cpu_last_move = cpu_move

        # End the game if there is a winner
        rounds_to_win = (game.total_rounds / 2) + 1
        if game.cpu_wins == rounds_to_win or game.user_wins == rounds_to_win:
            cls.end_game(game, game.user_wins > game.cpu_wins)

        # Update Game in datastore
        game.put()
        return game.to_form()