def get_game_history(self, request): """ Query game history kind for games matching id """ game = get_by_game_id(game_id=request.game_id) if not game: return OthelloGameHistoryForm( message='No history found for game ' + request.game_id) # query Othello game history entity with game id request.game_id game_history = OthelloGameHistory.query(ancestor=game.key).get() if not game_history: raise endpoints.BadRequestException( 'Could not find history linked to this game') return OthelloGameHistoryForm( game_status=game_history.key.parent().get().status, game_id=int(request.game_id), moves=game_history.moves)
def _make_move(self, request): """ Controller for movements. If game is SINGLE_PLAYER, CPU will take turn after player submits valid move. Otherwise, CPU waits for valid move or yield from player""" game = get_by_game_id(request.game_id) if not game: return False, "Game not found" print "Game status", game.status, type(game.status) if not game.status == "ACTIVE": return False, "This game is not active" if ndb.Key(OthelloPlayer, request.user_name, parent=ndb.Key(User, request.user_name))\ not in game.userKeys: return False, "Player {0} is not registered for this game".\ format(request.user_name) parent_keys = [p.parent() for p in game.userKeys] players = ndb.get_multi(parent_keys) print "Players in this game", players # load game logic object game_logic = load_game_logic(game.gamelogic) player_turn = 1 if players[0].name == request.user_name else 2 isvalid, message = game_logic._make_move(player_turn, request.move) print message # load an update game history in memory game_history = OthelloGameHistory.query(ancestor=game.key).get() if not game_history.moves: moves = [] else: moves = json.loads(game_history.moves) # append moves from user if move is valid if isvalid: moves.append([request.user_name, request.move]) if game_logic.game_mode == TWO_PLAYER_MODE: # PUSH TASK QUEUE to notify opponent that move has been made taskqueue.add(params={'email': players[0].email if player_turn == 2 else players[1].email, 'score': game_logic._getScore()}, url='/tasks/send_gameturn_notification_email') print "Whose turn is it?", game_logic.CP # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # CPU MOVE if isvalid and game_logic.game_mode == SINGLE_PLAYER_MODE: print "Calling CPU for move..." isvalid, cpu_move = game_logic._cpu_move() moves.append(['cpu', cpu_move]) print message message = "Your move was valid. {0}".format(cpu_move) # updates game logic with values from OthelloLogic instance update_game_logic(game_logic, game.gamelogic) # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # GAME OVER CONDITIONS if game_logic._isBoardFull(): game.status = "ENDED_COMPLETE" message = "Game has ended. The board is full!" if request.move == '0': game.status = "ENDED_INCOMPLETE" # record last move moves.append([players[0].name if player_turn == 1 else players[1].name, request.move]) message = "The user abandoned the game. " "Score will be accounted for" if not game.status == "ACTIVE": # get score score_player1, score_player2 = game_logic._getScore() score_diff = abs(score_player1-score_player2) player1_entry = OthelloScoreBoardEntry.query( ancestor=game.userKeys[0]).get() # CHECK END OF TWO PLAYER GAME if game_logic.game_mode == TWO_PLAYER_MODE: player2_entry = OthelloScoreBoardEntry.query( ancestor=game.userKeys[1]).get() if score_player1 > score_player2: # PLAYER 1 WINS message = "Player {0} wins!".format( game.userKeys[0].parent().get().name) player1_entry.points += score_player1 player1_entry.wins += 1 player1_entry.winning_streak += 1 # update score difference average - player 1 update_score_difference_ave( player1_entry.score_difference_average, score_diff) player2_entry.winning_streak = 0 elif score_player1 < score_player2: # PLAYER 2 WINS message = "Player {0} wins!".format( game.userKeys[1].parent().get().name) player2_entry.points += score_player2 player2_entry.wins += 1 player2_entry.winning_streak += 1 # update score difference average - player 2 update_score_difference_ave( player2_entry.score_difference_average, score_diff) player1_entry.winning_streak = 0 else: # tie game message = "This game is tied! No changes in scoreboard" # update players scoreboard entries in datastore ndb.put_multi([player1_entry, player2_entry]) # CHECK END FOR SINGLE PLAYER GAME if game_logic.game_mode == SINGLE_PLAYER_MODE: if score_player1 > score_player2: # PLAYER 1 WINS message = "Player {0} wins!".format( game.userKeys[0].parent().get().name) player1_entry.points += score_player1 player1_entry.wins += 1 update_score_difference_ave( player1_entry.score_difference_average, score_diff) player1_entry.winning_streak += 1 elif score_player1 < score_player2: message = "CPU wins." player1_entry.winning_streak = 0 player1_entry.put() # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # UPDATE GAME AND HISTORY DATASTORE game.put() # UPDATE GAME HISTORY game_history.moves = json.dumps(moves) game_history.put() return True, message
def _newOthelloGame(self, request): """ Logic for creating a new Othello game. Create ndb types that will store the game logic using the OthelloLogic class implementation """ # set game mode if request.player_two: playerNames = [ request.player_one, request.player_two ] else: playerNames = [ request.player_one ] if len(playerNames) == 1: game_mode = SINGLE_PLAYER_MODE else: game_mode = TWO_PLAYER_MODE # get OthelloPlayer keys for this game # assert : all keys have been verified to exist othello_players_keys = [ndb.Key( OthelloPlayer, name, parent=ndb.Key( User, name)) for name in playerNames] # initialize logic new_game_logic = OthelloLogic(game_mode=game_mode) # initialize game object with # explicit array name containers json_board = json.dumps(new_game_logic.B) json_array_x = json.dumps(new_game_logic.X) json_array_y = json.dumps(new_game_logic.Y) json_array_n = json.dumps(new_game_logic.N) json_array_move = json.dumps(new_game_logic.D) json_check_move = json.dumps(new_game_logic.C) game_logic = OthelloDatastoreLogic( board=json_board, player_turn=new_game_logic.CP, check_move=json_check_move, array_move=json_array_move, array_x=json_array_x, array_y=json_array_y, array_n=json_array_n, game_mode=new_game_logic.game_mode) new_game = OthelloGame( status="ACTIVE", starttime=datetime.today(), gamelogic=game_logic, userKeys=othello_players_keys) # link new game to creator, in this case, first user in player list g_id = OthelloGame.allocate_ids(size=1, parent=othello_players_keys[0])[0] g_key = ndb.Key('OthelloGame', g_id, parent=othello_players_keys[0]) new_game.key = g_key # add generated id as game id new_game.game_id = g_id # create game history entity # adding scoreboard entry new_game.put() print "Game created" gh_id = OthelloGameHistory.allocate_ids(size=1, parent=g_key)[0] gh_key = ndb.Key(OthelloGameHistory, gh_id, parent=g_key) game_history = OthelloGameHistory(key=gh_key) game_history.put() # load OtheloPlayer entities players = ndb.get_multi(othello_players_keys) for p in players: p.gameKeys.append(g_key) ndb.put_multi(players) print "Added game to player game keys" return new_game.game_id