private void queueMovement(Vector3 platformPosition, PlayerMovementPath newPath = null)
    {
        if (newPath == null)
        {
            CollisionMap map = getCollisionMap(platformPosition);
            this.path = PathFindingLogic.ProcessSolution(map);
        }
        else
        {
            this.path = newPath;
        }

        moveToNewPosition();
    }
    public List <GameObject> getProposedPath(Vector3 clickCoordinatePosition)
    {
        CollisionMap map = getCollisionMap(clickCoordinatePosition);

        Coordinate playerCoordinate = new Coordinate(player.transform.position);
        GameObject possibleBallAtClickCoordinate = gameObjects.movableObjects.Find(x => new Coordinate(x.transform.position).Equals(new Coordinate(clickCoordinatePosition)));

        if (possibleBallAtClickCoordinate != null)
        {
            map.setBlock(new Coordinate(possibleBallAtClickCoordinate.transform.position), false);
        }

        PlayerMovementPath thePath = PathFindingLogic.ProcessSolution(map);

        List <GameObject> listOfGameObjects = new List <GameObject>();

        if (thePath != null)
        {
            listOfGameObjects.Add(gameObjects.getPlatform(playerCoordinate));

            while (true)
            {
                Coordinate nextCoordinate = thePath.getNext();

                if (nextCoordinate == null)
                {
                    break;
                }

                GameObject platform = gameObjects.getPlatform(nextCoordinate);

                if (platform != null)
                {
                    listOfGameObjects.Add(platform);
                }
            }
        }

        return(listOfGameObjects);
    }
    private void userClickEvent()
    {
        Ray        ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;

        if (Physics.Raycast(ray, out hit))
        {
            GameObject selectedObject = hit.transform.gameObject;
            GameObject ball           = null;

            // If the user selected a platform
            if (hit.transform.gameObject.name.Contains("platform"))
            {
                bool userIsMovingTheBall = false;
                List <GameObject> ballMovementCoordinates = new List <GameObject>();

                if (GridHighlighter.Instance.BallMovementMode)
                {
                    // Has the user selected a platform on the movement path?
                    ballMovementCoordinates = getBallMovementModeCoordinates(GridHighlighter.Instance.BallMovementModeTargetBall.transform.position);
                    userIsMovingTheBall     = ballMovementCoordinates.Contains(selectedObject);
                }

                if (userIsMovingTheBall)
                {
                    // Will need to travel in a straight line to the target location.
                    PlayerMovementPath moveTheBallMovementPath = new PlayerMovementPath();

                    Coordinate ballCoordinate   = new Coordinate(GridHighlighter.Instance.BallMovementModeTargetBall.transform.position);
                    Coordinate playerCoordinate = new Coordinate(player.transform.position);
                    char       direction        = playerCoordinate.getDirection(ballCoordinate);

                    Coordinate clickedCoordinate = new Coordinate(hit.transform.gameObject.transform.position);
                    Coordinate nextCoordinate    = new Coordinate(playerCoordinate, direction);

                    // While the next coordinate doesn't equal the click coordinate, add to movement path
                    while (!nextCoordinate.Equals(clickedCoordinate))
                    {
                        moveTheBallMovementPath.CoordinatePath.Add(nextCoordinate);

                        nextCoordinate = new Coordinate(nextCoordinate, direction);
                    }
                    moveTheBallMovementPath.CoordinatePath.Add(clickedCoordinate);

                    queueMovement(hit.transform.gameObject.transform.position, moveTheBallMovementPath);
                }
                else
                {
                    GridHighlighter.Instance.BallMovementMode = false;

                    Coordinate platformCoordinate = new Coordinate(hit.transform.gameObject.transform.position);
                    ball = gameObjects.movableObjects.Find(x => new Coordinate(x.transform.position).Equals(platformCoordinate));

                    // If user has clicked the platform underneith the ball
                    if (ball == null)
                    {
                        queueMovement(selectedObject.transform.position);
                    }
                }
            }

            // User has clicked on a ball to move
            if (hit.transform.gameObject.name.Contains("ball"))
            {
                ball = hit.transform.gameObject;
            }

            //Maybe make generic - not just a ball

            // if the user selected a ball to move
            if (ball != null)
            {
                Coordinate ballCoordinate = new Coordinate(ball.transform.position);
                // Select the platform underneath the ball
                GameObject targetPlatform = gameObjects.getPlatform(ballCoordinate);

                if (targetPlatform != null)
                {
                    CollisionMap map = getCollisionMap(targetPlatform.transform.position);
                    // We want to find the path to the ball
                    map.setBlock(ballCoordinate, false);

                    PlayerMovementPath newPath = PathFindingLogic.ProcessSolution(map);

                    if (newPath.CoordinatePath.Count > 1)
                    {
                        GridHighlighter.Instance.BallMovementMode           = false;
                        GridHighlighter.Instance.BallMovementModeTargetBall = null;

                        // Move the player to the ball
                        newPath.CoordinatePath.RemoveAt(newPath.CoordinatePath.Count - 1);
                        queueMovement(targetPlatform.transform.position, newPath);
                    }
                    else
                    {
                        // User has clicked the ball, while standing next to it
                        GridHighlighter.Instance.BallMovementMode           = true;
                        GridHighlighter.Instance.BallMovementModeTargetBall = ball;
                    }
                }
            }
        }
    }
    private void moveToNewPosition()
    {
        movingFromCoordinate = new Coordinate(player.transform.position).toVector3D(player.transform.position.y);
        Coordinate nextCoordinate = null;

        if (this.path != null)
        {
            nextCoordinate = this.path.getNext();
            if (nextCoordinate != null)
            {
                movingToCoordinate = nextCoordinate.toVector3D(player.transform.position.y);
            }
        }

        if (nextCoordinate == null)
        {
            startTime     = 0;
            journeyLength = 0;
            this.path     = null;
            movingPlayer  = false;
            ballToMove    = null;

            GridHighlighter.Instance.BallMovementMode           = false;
            GridHighlighter.Instance.BallMovementModeTargetBall = null;
        }
        else
        {
            bool playerCollidesWithBall         = false;
            bool playerCannotMoveDueToBallBlock = false;

            Coordinate playerCoordinate = new Coordinate(player.transform.position);

            GameObject ball = gameObjects.movableObjects.Find(x => new Coordinate(x.transform.position).Equals(nextCoordinate));
            playerCollidesWithBall = ball != null;

            if (playerCollidesWithBall)
            {
                // If we continue in this direction, will be ball collide with anything else?
                char       dir      = playerCoordinate.getDirection(nextCoordinate);
                Coordinate newCoord = new Coordinate(nextCoordinate, dir);

                CollisionMap map = getCollisionMap(movingToCoordinate);

                // if the next coordinate is blocked
                if (map.getElement(newCoord) == null || map.getElement(newCoord).Blocked)
                {
                    playerCannotMoveDueToBallBlock = true;
                }
                else
                {
                    ballToMove = ball;
                    movingBallFromCoordinate = new Coordinate(ball.transform.position).toVector3D(ball.transform.position.y);
                    movingBallToCoordinate   = newCoord.toVector3D(ball.transform.position.y);
                }
            }

            if (!playerCollidesWithBall)
            {
                playerCannotMoveDueToBallBlock = false;
            }

            if (!playerCannotMoveDueToBallBlock)
            {
                startTime     = Time.time;
                journeyLength = Vector3.Distance(player.transform.position, movingToCoordinate);
                movingPlayer  = true;
            }
            else
            {
                // The player cannot move because it is being blocked by a ball being blocked
                // by something else!
                startTime     = 0;
                journeyLength = 0;
                this.path     = null;
                movingPlayer  = false;

                ballToMove = null;
            }
        }
    }