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])
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])
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!')
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])
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()
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)
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])
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])
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()
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
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()
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
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
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()