public void prepareAI()
    {
        restoreMoves();
        carPos          = new Vector2Int((int)carScript.transform.position.x, (int)carScript.transform.position.y);
        lowestTotalCost = -1;
        Stopwatch s = new Stopwatch();

        s.Start();
        for (int i = 0; i < tileScript.FinishTile.GetLength(0); i++)
        {
            Vector2Int  targetPosition = tileScript.FinishTile[i];
            TileForList startTile      = new TileForList(carPos, 0, calculateDistanceToTarget(carPos, targetPosition), carScript.CurrentSpeed, null, "Start Tile", targetPosition);
            if (debugMode)
            {
                print(startTile.ToString());
            }
            openlist.Clear();
            closedlist.Clear();
            openlist.Add(startTile);
            findOptimalPath();
        }
        isOutOfPosition = false;
        s.Stop();
        Debug.Log("prepareAI time taken" + s.Elapsed.TotalSeconds);
    }
    private void createPath(TileForList finishTile)
    {
        Debug.Log("createPath");
        int sentinel = 500;

        optimalSolution.Push(finishTile);
        if (debugMode)
        {
            print("Optimal Path");
            print(finishTile.ToString());
        }
        TileForList previousTile = finishTile.previousTile;

        previousTile.thisAction = finishTile.previousAction;
        while (previousTile != null)
        {
            sentinel--;
            optimalSolution.Push(previousTile);
            if (debugMode)
            {
                print(previousTile.ToString());
            }
            TileForList nextPreviousTile;
            nextPreviousTile = previousTile.previousTile;
            if (nextPreviousTile != null)
            {
                nextPreviousTile.thisAction = previousTile.previousAction;
            }
            previousTile = nextPreviousTile;
        }
        if (debugMode)
        {
            print("End Optimal Path");
        }
    }
    public void nextCarAction()
    {
        if (debugMode)
        {
            print("NextCarAction");
        }
        TileForList nextMove = getNextMove();

        Debug.Log(nextMove.ToString());
        string nextAction = nextMove.thisAction;

        if (nextAction.Equals("Finish"))
        {
            if (debugMode)
            {
                print("Car has finished");
            }
            haveFinished = true;
        }
        else if (nextAction.Equals("Accelerate"))
        {
            if (debugMode)
            {
                print("AccelerateCar");
            }
            carScript.accelerate();
        }
        else if (nextAction.Equals("Deaccelerate"))
        {
            if (debugMode)
            {
                print("DeaccelerateCar");
            }
            carScript.deaccelerate();
        }
        else if (nextAction.Equals("Do Nothing"))
        {
            if (debugMode)
            {
                print("Do No action with car");
            }
            carScript.doNothing();
        }
        else if (nextAction.Equals("Move Up"))
        {
            if (debugMode)
            {
                print("Move car up");
            }
            carScript.moveUp();
        }
        else if (nextAction.Equals("Move Down"))
        {
            if (debugMode)
            {
                print("Move car down");
            }
            carScript.moveDown();
        }
        else
        {
            if (debugMode)
            {
                print("AI could not find an action with this name: " + nextAction);
            }
        }
        if (debugMode)
        {
            print("End NextCarAction");
        }
    }
    private void findOptimalPath()
    {
        int sentinel = 5000;

        while (0 < openlist.Count)
        {
            //Debug.Log("sentinel: " + sentinel);
            //sentinel--;
            TileForList currentTile = openlist[0];
            openlist.RemoveAt(0);
            closedlist.Add(new TileForClosedList(currentTile));
            if (debugMode)
            {
                print("currentTile: " + currentTile.ToString());
            }
            if (currentTile.targetPosition.x < currentTile.position.x)
            {
                continue;
            }
            if (currentTile.targetPosition.x == currentTile.position.x && currentTile.position.y == currentTile.targetPosition.y)
            {
                if (currentTile.tileTotalCost < lowestTotalCost || lowestTotalCost == -1)
                {
                    optimalSolution.Clear();
                    lowestTotalCost = currentTile.tileTotalCost;
                    Debug.Log("lowestTotalCost: " + lowestTotalCost);
                    currentTile.thisAction = "Finish";
                    createPath(currentTile);
                }
                break;
            }
            if (createDebugTiles)
            {
                Instantiate(debugTile, new Vector3(currentTile.position.x, currentTile.position.y, -1), Quaternion.identity);
            }
            if (canAccelerate(currentTile.speed, currentTile.position))
            {
                int nextSpeed = currentTile.speed;
                nextSpeed++;
                int[] makeMovesArray = makeMoves(nextSpeed, currentTile, 0);
                nextSpeed = makeMovesArray[0];
                int nextXPosition = makeMovesArray[1];
                int nextYPosition = currentTile.position.y;
                addToOpenList(new Vector2Int(nextXPosition, nextYPosition), currentTile.tileCost + 1, nextSpeed, currentTile, "Accelerate");
            }
            if (canDeaccelerate(currentTile.speed, currentTile.position))
            {
                int nextSpeed = currentTile.speed;
                nextSpeed--;
                int[] makeMovesArray = makeMoves(nextSpeed, currentTile, 0);
                nextSpeed = makeMovesArray[0];
                int nextXPosition = makeMovesArray[1];
                int nextYPosition = currentTile.position.y;
                addToOpenList(new Vector2Int(nextXPosition, nextYPosition), currentTile.tileCost + 1, nextSpeed, currentTile, "Deaccelerate");
            }
            if (canDoNothing(currentTile.speed, currentTile.position))
            {
                int   nextSpeed      = currentTile.speed;
                int[] makeMovesArray = makeMoves(nextSpeed, currentTile, 0);
                nextSpeed = makeMovesArray[0];
                int nextXPosition = makeMovesArray[1];
                int nextYPosition = currentTile.position.y;
                addToOpenList(new Vector2Int(nextXPosition, nextYPosition), currentTile.tileCost + 1, nextSpeed, currentTile, "Do Nothing");
            }
            if (canMoveUp(currentTile.speed, currentTile))
            {
                int   nextSpeed      = currentTile.speed;
                int[] makeMovesArray = makeMoves(nextSpeed, currentTile, +1);
                nextSpeed = makeMovesArray[0];
                int nextXPosition = makeMovesArray[1];
                int nextYPosition = currentTile.position.y + 1;
                addToOpenList(new Vector2Int(nextXPosition, nextYPosition), currentTile.tileCost + 1, nextSpeed, currentTile, "Move Up");
            }
            if (canMoveDown(currentTile.speed, currentTile))
            {
                int   nextSpeed      = currentTile.speed;
                int[] makeMovesArray = makeMoves(nextSpeed, currentTile, -1);
                nextSpeed = makeMovesArray[0];
                int nextXPosition = makeMovesArray[1];
                int nextYPosition = currentTile.position.y - 1;
                addToOpenList(new Vector2Int(nextXPosition, nextYPosition), currentTile.tileCost + 1, nextSpeed, currentTile, "Move Down");
            }
            //			for (int i = -1; i < 2; i++) {
            //				int xOffset = i;
            //				if (currentTile.position.x + xOffset < 0 ||
            //					currentTile.position.x + xOffset >= tileScript.TileArray.GetLength (0)) {
            //					continue;
            //				}
            //				for (int j = -1; j < 2; j++) {
            //					int yOffset = j;
            //					if (currentTile.position.y + yOffset < 0 ||
            //						currentTile.position.y + yOffset >= tileScript.TileArray.GetLength (1)) {
            //						continue;
            //					}
            //
            //				}
            //			}
            openlist.Sort((a, b) => a.tileTotalCost.CompareTo(b.tileTotalCost));
        }
        if (openlist.Count == 0)
        {
            Debug.Log("Openlist is empty");
        }
        if (sentinel == 0)
        {
            Debug.Log("sentinel reached zero, openlist count: " + openlist.Count);
        }
    }