private int[] makeMoves(int currentSpeed, TileForList currentTile, int yPositionChange) { int currentXPosition = currentTile.position.x; int numberOfMoves = Mathf.Abs(currentSpeed); Vector2Int nextPos = currentTile.position; nextPos.y += yPositionChange; for (int movesDone = 0; movesDone < numberOfMoves; movesDone++) { Vector2Int previousPos = nextPos; if (0 < currentSpeed) { nextPos.x++; } else { nextPos.x--; } if (checkCollision(nextPos)) { currentSpeed = 0; nextPos = previousPos; break; } } return(new int[] { currentSpeed, nextPos.x }); }
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"); } }
private void addToOpenList(Vector2Int nextPos, int nextTileCost, int nextTileSpeed, TileForList currentTile, string previousAction) { int nextTileTotalCost = nextTileCost + calculateDistanceToTarget(nextPos, currentTile.targetPosition); TileForList newTile = new TileForList(nextPos, nextTileCost, nextTileTotalCost, nextTileSpeed, currentTile, previousAction, currentTile.targetPosition); if (!checkClosedList(new TileForClosedList(newTile)) && !openlist.Contains(newTile)) { openlist.Add(newTile); } }
private TileForList getNextMove() { if (isOutOfPosition) { prepareAI(); } if (difficulty == (int)difficultyEnum.Perfect || 0 < numberOfPerfectMoves) { if (difficulty != (int)difficultyEnum.Perfect) { numberOfPerfectMoves--; } return(optimalSolution.Pop()); } else { bool doneMove = false; TileForList modified = optimalSolution.Pop(); Vector2Int position = new Vector2Int((int)carScript.transform.position.x, (int)carScript.transform.position.y); while (!doneMove) { int randomValue = (int)Random.Range(0, 5); Debug.Log("Random Value " + randomValue); if (!doneMove && randomValue == 0 && carScript.canAccelerate()) { modified.thisAction = "Accelerate"; doneMove = true; } else if (!doneMove && randomValue == 1 && carScript.canDeaccelerate()) { modified.thisAction = "Deaccelerate"; doneMove = true; } else if (!doneMove && randomValue == 2 && carScript.canDoNothing()) { modified.thisAction = "Do Nothing"; doneMove = true; } else if (!doneMove && randomValue == 3 && carScript.canMoveUp()) { modified.thisAction = "Move Up"; doneMove = true; } else if (!doneMove && randomValue == 4 && carScript.canMoveDown()) { modified.thisAction = "Move Down"; doneMove = true; } } isOutOfPosition = true; return(modified); } }
public override bool Equals(object obj) { if (obj.GetType() == typeof(TileForList)) { TileForList objTile = (TileForList)obj; if (objTile.position == this.position && objTile.speed == this.speed && objTile.tileTotalCost >= this.tileTotalCost) { return(true); } } return(false); }
private bool canMoveDown(int currentSpeed, TileForList currentTile) { Vector2Int position = currentTile.position; if (0 < position.y && currentTile.previousAction != "Move Up") { if (currentSpeed <= carScript.MaximumSpeedForHeightChange && tileScript.TileArray[position.x, position.y - 1] != -1) { return(true); } } return(false); }
public TileForList(Vector2Int position, int tileCost, int tileTotalCost, int speed, TileForList previousTile, string previousAction, Vector2Int targetPosition) { this.position = position; this.tileCost = tileCost; this.tileTotalCost = tileTotalCost; this.speed = speed; if (previousTile != null) { this.previousTile = previousTile; } else { this.previousTile = null; } this.previousAction = previousAction; this.targetPosition = targetPosition; }
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"); } }
public TileForClosedList(TileForList copy) : base(copy) { }
public TileForClosedList(Vector2Int position, int tileCost, int tileTotalCost, int speed, TileForList previousTile, string previousAction, Vector2Int targetPosition) : base(position, tileCost, tileTotalCost, speed, previousTile, previousAction, targetPosition) { }
public TileForList(TileForList copy) : this(copy.position, copy.tileCost, copy.tileTotalCost, copy.speed, copy.previousTile, copy.previousAction, copy.targetPosition) { }
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); } }