def nextThreeGrids(sg):
    sgUp = sg.simulateMove("up");
    sgRight = sg.simulateMove("right");
    sgLeft = sg.simulateMove("left");

    possibleFuture = [sgUp, sgRight, sgLeft];
    future = [];
    for sgFuture in (possibleFuture):
        if (Tools.staleMove(sg, sgFuture)):
            future.append(False);
        else:
            future.append(sgFuture);
    return future;
def nextThreeGrids(sg):
    sgUp = sg.simulateMove("up")
    sgRight = sg.simulateMove("right")
    sgLeft = sg.simulateMove("left")

    possibleFuture = [sgUp, sgRight, sgLeft]
    future = []
    for sgFuture in (possibleFuture):
        if (Tools.staleMove(sg, sgFuture)):
            future.append(False)
        else:
            future.append(sgFuture)
    return future
def generateNextMove(game_state):
    grid = Tools.getGridState(game_state);
    sg = smartGrid(True, grid, np.zeros((4, 4), bool));
    sgUp = sg.simulateMove("up");
    sgRight = sg.simulateMove("right");
    sgLeft = sg.simulateMove("left");

    if (not Tools.staleMove(sg, sgUp) and sgUp.getHighestTile() == sgUp.intGrid[0, 0]):
        return "up";
    elif (not Tools.staleMove(sg, sgLeft) and sgLeft.getHighestTile() == sgLeft.intGrid[0, 0]):
        return "left";
    elif (not Tools.staleMove(sg, sgRight) and sgRight.getHighestTile() == sgRight.intGrid[0, 0]):
        return "right";
    elif (not Tools.staleMove(sg, sgUp)):
        return "up";
    elif (not Tools.staleMove(sg, sgLeft)):
        return "left";
    elif (not Tools.staleMove(sg, sgRight)):
        return "right";
    else:
        return "down";
def generateNextMove(game_state):
    grid = Tools.getGridState(game_state)
    sg = smartGrid(True, grid, np.zeros((4, 4), bool))
    sgUp = sg.simulateMove("up")
    sgRight = sg.simulateMove("right")
    sgLeft = sg.simulateMove("left")

    if (not Tools.staleMove(sg, sgUp)
            and sgUp.getHighestTile() == sgUp.intGrid[0, 0]):
        return "up"
    elif (not Tools.staleMove(sg, sgLeft)
          and sgLeft.getHighestTile() == sgLeft.intGrid[0, 0]):
        return "left"
    elif (not Tools.staleMove(sg, sgRight)
          and sgRight.getHighestTile() == sgRight.intGrid[0, 0]):
        return "right"
    elif (not Tools.staleMove(sg, sgUp)):
        return "up"
    elif (not Tools.staleMove(sg, sgLeft)):
        return "left"
    elif (not Tools.staleMove(sg, sgRight)):
        return "right"
    else:
        return "down"
def generateNextMove(game_state):
    grid = Tools.getGridState(game_state)
    sg = smartGrid(True, grid, np.zeros((4, 4), bool))
    sgUp = sg.simulateMove("up")
    sgRight = sg.simulateMove("right")
    sgLeft = sg.simulateMove("left")

    # no moves possible
    if (Tools.staleMove(sg, sgUp) and Tools.staleMove(sg, sgRight)
            and Tools.staleMove(sg, sgLeft)):
        return "down"
    # one move possible
    elif (Tools.staleMove(sg, sgUp) and Tools.staleMove(sg, sgRight)):
        return "left"
    # one move possible
    elif (Tools.staleMove(sg, sgUp) and Tools.staleMove(sg, sgLeft)):
        return "right"
    # one move possible
    elif (Tools.staleMove(sg, sgRight) and Tools.staleMove(sg, sgLeft)):
        return "up"
    # right and left moves possible
    elif (Tools.staleMove(sg, sgUp)):
        scoresRL = compareFutures(sgRight, sgLeft)
        if (scoresRL[0] > scoresRL[1]):
            return "right"
        # on tie, choose left
        else:
            return "left"
    # right and up moves possible
    elif (Tools.staleMove(sg, sgLeft)):
        scoresRU = compareFutures(sgRight, sgUp)
        if (scoresRU[0] > scoresRU[1]):
            return "right"
        # on tie, choose up
        else:
            return "up"
    # left and up moves possible
    elif (Tools.staleMove(sg, sgRight)):
        scoresLU = compareFutures(sgLeft, sgUp)
        if (scoresLU[0] > scoresLU[1]):
            return "left"
        # on tie, choose up
        else:
            return "up"
    # all three moves possible
    else:
        scoresUL = compareFutures(sgUp, sgLeft)
        # up is better than left
        if (scoresUL[0] > scoresUL[1]):
            #compare up and right
            scoresUR = compareFutures(sgUp, sgRight)
            # up is best
            if (scoresUR[0] > scoresUR[1]):
                return "up"
            # right is best
            else:
                return "right"
        # left is better than up
        else:
            # compare left and right
            scoresLR = compareFutures(sgLeft, sgRight)
            # left is best
            if (scoresLR[0] > scoresLR[1]):
                return "left"
            # right is best
            else:
                return "right"
def generateNextMove(game_state):
    grid = Tools.getGridState(game_state);
    sg = smartGrid(True, grid, np.zeros((4, 4), bool));
    sgUp = sg.simulateMove("up");
    sgRight = sg.simulateMove("right");
    sgLeft = sg.simulateMove("left");

    # no moves possible
    if (Tools.staleMove(sg, sgUp) and Tools.staleMove(sg, sgRight) and Tools.staleMove(sg, sgLeft)):
        return "down";
    # one move possible
    elif (Tools.staleMove(sg, sgUp) and Tools.staleMove(sg, sgRight)):
        return "left";
    # one move possible
    elif (Tools.staleMove(sg, sgUp) and Tools.staleMove(sg, sgLeft)):
        return "right";
    # one move possible
    elif (Tools.staleMove(sg, sgRight) and Tools.staleMove(sg, sgLeft)):
        return "up";
    # right and left moves possible
    elif (Tools.staleMove(sg, sgUp)):
        scoresRL = compareFutures(sgRight, sgLeft);
        if (scoresRL[0] > scoresRL[1]):
            return "right";
        # on tie, choose left
        else:
            return "left";
    # right and up moves possible
    elif (Tools.staleMove(sg, sgLeft)):
        scoresRU = compareFutures(sgRight, sgUp);
        if (scoresRU[0] > scoresRU[1]):
            return "right";
        # on tie, choose up
        else:
            return "up";
    # left and up moves possible
    elif (Tools.staleMove(sg, sgRight)):
        scoresLU = compareFutures(sgLeft, sgUp);
        if (scoresLU[0] > scoresLU[1]):
            return "left";
        # on tie, choose up
        else:
            return "up";
    # all three moves possible
    else:
        scoresUL = compareFutures(sgUp, sgLeft);
        # up is better than left
        if (scoresUL[0] > scoresUL[1]):
            #compare up and right
            scoresUR = compareFutures(sgUp, sgRight);
            # up is best
            if (scoresUR[0] > scoresUR[1]):
                return "up";
            # right is best
            else:
                return "right";
        # left is better than up
        else:
            # compare left and right
            scoresLR = compareFutures(sgLeft, sgRight);
            # left is best
            if (scoresLR[0] > scoresLR[1]):
                return "left";
            # right is best
            else:
                return "right";