예제 #1
0
    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)
예제 #2
0
    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
예제 #3
0
    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