// Read through lists to find the path. public void FindPath(AiBotBase bot, Player plr, Level level) { if (data.Count == 0) return; path = new List<Coord2>(); int lowest = int.MaxValue; Coord2 currentPos = new Coord2(-1, -1); Coord2 nextPos = new Coord2(bot.GridPosition.X, bot.GridPosition.Y); while (Math.Abs(plr.GridPosition.X - currentPos.X) > 1 || Math.Abs(plr.GridPosition.Y - currentPos.Y) > 1)//(new Coord2(plr.GridPosition.X, plr.GridPosition.Y-1) != currentPos) { currentPos = nextPos; if (data[(plr.GridPosition.X) * level.GridSizeX + plr.GridPosition.Y].ElementAt((currentPos.X) * level.GridSizeY + (currentPos.Y)) != 0 || data[(plr.GridPosition.X) * level.GridSizeX + plr.GridPosition.Y].ElementAt((currentPos.X) * level.GridSizeY + (currentPos.Y)) < int.MaxValue) { for (int i = -1; i <= 1; i++) for (int j = -1; j <= 1; j++) if (level.ValidPosition(new Coord2(currentPos.X + i, currentPos.Y + j))) if (data[plr.GridPosition.X * 40 + plr.GridPosition.Y].ElementAt((currentPos.X + i) * 40 + (currentPos.Y + j)) < lowest) //if (i == 0 || j == 0) if (new Coord2(currentPos.X + i, currentPos.Y + j) != new Coord2(currentPos.X, currentPos.Y)) { lowest = data[plr.GridPosition.X * 40 + plr.GridPosition.Y].ElementAt((currentPos.X + i) * 40 + (currentPos.Y + j)); nextPos = new Coord2(currentPos.X + i, currentPos.Y + j); } } if (lowest == int.MaxValue) break; path.Add(nextPos); } }
protected override void ChooseNextGridLocation(Level level, Player plr) { bool ok = false; Coord2 pos;// = new Coord2(); while (!ok) { pos = GridPosition; int x = rnd.Next(0,4); switch (x) { case (0): pos.X += 1; break; case (1): pos.X -= 1; break; case (2): pos.Y += 1; break; case (3): pos.Y -= 1; break; } ok = SetNextGridPosition(pos, level); } }
protected override void ChooseNextGridLocation(Level level, Player plr) { //your code will go here. Coord2 position; position = GridPosition; if(plr.GridPosition.X < position.X)//if player position X less than bot position X move back on the X axis { //position.X -= 1; } if (plr.GridPosition.X > position.X)//if player position X greater then bot position X move forward on the X axis. { //position.X += 1; } if (plr.GridPosition.Y < position.Y)//if player position Y less than bot position Y move down on the Y axis. { //position.Y -= 1; } if (plr.GridPosition.Y > position.Y)//if player position Y greater than bot position Y move up on the Y axis. { //position.Y += 1; } SetNextGridPosition(position, level);//sets position of bot. level.ValidPosition(position);//checks for walls. }
protected override void ChooseNextGridLocation(Level level, Player plr) { double currentDistance = GetDistance(plr.GridPosition, GridPosition); Coord2 testPosition = new Coord2(GridPosition.X, GridPosition.Y); for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { if (i == 0 || j == 0) { testPosition = new Coord2(GridPosition.X + i, GridPosition.Y + j); if (currentDistance > GetDistance(plr.GridPosition, testPosition)) { currentDistance = GetDistance(plr.GridPosition, testPosition); SetNextGridPosition(testPosition, level); currentDirection = testPosition - GridPosition; } } } } if (!level.ValidPosition(GridPosition + currentDirection)) { currentDirection = new Coord2(currentDirection.Y, currentDirection.X); SetNextGridPosition(GridPosition + currentDirection, level); } }
//sets next position for player to move to: called by keyboard processing functions. validates new position against level, //so can't move to blocked position, or position off grid public void SetNextLocation(Coord2 newLoc, Level level) { if (timerMs > 0) return; if (level.ValidPosition(newLoc)) { targetPosition = newLoc; timerMs = moveTime; } }
public void SetPosition(Coord2 newPos, Level level) { if (level.ValidPosition(newPos)) { gridPosition = newPos; targetPosition = newPos; screenPosition = newPos; } }
//sets target position: the next grid location to move to //need to validate this position - so must be within 1 cell of current position(in x and y directions) //and must also be valid on the map: greater than 0, less than mapsize, and not a wall public bool SetNextGridPosition(Coord2 pos, Level level) { if (pos.X < (gridPosition.X - 1)) return false; if (pos.X > (gridPosition.X + 1)) return false; if (pos.Y < (gridPosition.Y - 1)) return false; if (pos.Y > (gridPosition.Y + 1)) return false; if (!level.ValidPosition(pos)) return false; targetPosition = pos; return true; }
//Handles animation moving from current grid position (gridLocation) to next grid position (targetLocation) //When target location is reached, sets grid location to targetLocation, and then calls ChooseNextGridLocation //and resets animation timer public void Update(GameTime gameTime, Level level, Player plr) { timerMs -= gameTime.ElapsedGameTime.Milliseconds; if (timerMs <= 0) { gridPosition = targetPosition; ChooseNextGridLocation(level, plr); timerMs = moveTime; } //calculate screen position screenPosition = (gridPosition * 15) + ((((targetPosition * 15) - (gridPosition * 15)) * (moveTime - timerMs)) / moveTime); }
protected override void ChooseNextGridLocation(Level level, Player plr) { Coord2 position; position = GridPosition; if (plr.GridPosition.X < position.X) { position.X -= 1; } if (plr.GridPosition.X > position.X) { position.X += 1; } if (plr.GridPosition.Y < position.Y) { position.Y -= 1; } if (plr.GridPosition.Y > position.Y) { position.Y += 1; } if (!level.ValidPosition(position)) { if (plr.GridPosition.Y < position.Y) { position = GridPosition; position.Y -= 1; SetNextGridPosition(position, level); } if (plr.GridPosition.Y > position.Y) { position = GridPosition; position.Y += 1; SetNextGridPosition(position, level); } if (plr.GridPosition.X > position.X) { position = GridPosition; position.X -= 1; SetNextGridPosition(position, level); } if (plr.GridPosition.X < position.X) { position = GridPosition; position.X += 1; SetNextGridPosition(position, level); } } SetNextGridPosition(position, level);//sets position of bot. }
//Handles animation moving from current grid position (gridLocation) to next grid position (targetLocation) public void Update(GameTime gameTime, Level level) { if (timerMs > 0) { timerMs -= gameTime.ElapsedGameTime.Milliseconds; if (timerMs <= 0) { timerMs = 0; gridPosition = targetPosition; } } //calculate screen position screenPosition = (gridPosition * 15) + ((((targetPosition * 15) - (gridPosition * 15)) * (moveTime - timerMs)) / moveTime); }
public Scent(Level lvl) { bufferOne = new int[lvl.GridSize, lvl.GridSize]; bufferTwo = new int[lvl.GridSize, lvl.GridSize]; for (int i = 0; i < lvl.GridSize; i++) { for (int j = 0; j < lvl.GridSize; j++) { bufferOne[i, j] = 0; bufferTwo[i, j] = 0; } } sourceValue = 0; }
protected override void ChooseNextGridLocation(Level level, Player plr) { Coord2 CurrentPos; if(level.build_astar == true) { CurrentPos = GridPosition; //sets new position for the bot. if (GridPosition != plr.GridPosition) { CurrentPos = level.astar.astar_path[index]; } SetNextGridPosition(CurrentPos, level); index++; } }
public Dijkstra(Level level) { closed = new bool[level.GridSize, level.GridSize]; cost = new float[level.GridSize, level.GridSize]; link = new Coord2[level.GridSize, level.GridSize]; inPath = new bool[level.GridSize, level.GridSize]; path = new List<Coord2>(); for (int i = 0; i < level.GridSize; i++) { for (int j = 0; j < level.GridSize; j++) { cost[i, j] = int.MaxValue-1; closed[i, j] = false; link[i, j] = new Coord2(-1, -1); inPath[i, j] = false; } } }
// Create a text file by flooding Dijkstra's for every cell. public void Calculate(Level level) { int firstTile = level.tiles[0][0]; level.tiles[0][0] = 1; Dijkstra dijkstra = new Dijkstra(level); AiBotSimple bot = new AiBotSimple(0,0); Player player = new Player(level.GridSizeX-1, level.GridSizeY-1); Coord2 current = new Coord2(-1, -1); dijkstra.Build(level, bot, player); StreamWriter writer = new StreamWriter("precompute.txt", true); for (int x = 0; x < level.GridSize; x++) { for (int y = 0; y < level.GridSize; y++) { for (int i = 0; i < level.GridSize; i++) { for (int j = 0; j < level.GridSize; j++) { if (new Coord2(i, j) == player.GridPosition) writer.Write(0); else if (level.ValidPosition(new Coord2(i, j)) && dijkstra.cost[i,j].ToString() != "2.147484E+09") writer.Write(dijkstra.cost[i, j].ToString()); else writer.Write("-"); string tab = "\t"; writer.Write(tab); } } writer.WriteLine(); bot = new AiBotSimple(x, y); player = new Player(0, 0); dijkstra = new Dijkstra(level); dijkstra.Build(level, bot, player); } } writer.Close(); level.tiles[0][0] = firstTile; }
// Read base class's input class and follow through. protected override void ChooseNextGridLocation(Level level, Player plr) { if (path == null) { if (dijkstra != null) path = dijkstra.path; else if (aStar != null) path = aStar.path; else if (level.precompute != null) { path = level.precompute.path; path.Reverse(); } } else if (path.Count > 0) { SetNextGridPosition(path[path.Count-1], level); path.RemoveAt(path.Count - 1); } }
// Follow the highest adjacent scent value. protected override void ChooseNextGridLocation(Level level, Player plr) { if (GridPosition == plr.GridPosition) return; Coord2 next = new Coord2(-1, -1); int highest = 0; for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { if (level.ValidPosition(new Coord2(GridPosition.X+i, GridPosition.Y+j)) && plr.GetScent(GridPosition.X + i, GridPosition.Y + j) > highest && (i == 0 || j == 0)) { if (i == 0 && j == 0) continue; highest = plr.GetScent(GridPosition.X + i, GridPosition.Y + j); next = new Coord2(GridPosition.X + i, GridPosition.Y + j); } } } SetNextGridPosition(next, level); }
protected override void ChooseNextGridLocation(Level level, Player plr) { Coord2 CurrentPos; CurrentPos = GridPosition; //checks bot surrounding nodes. if(GridPosition != plr.GridPosition) { for (int f = -1; f <= 1; f++) { for (int g = -1; g <= 1; g++) { //changes bot position. if (level.scentmap.buffer1[GridPosition.X + f, GridPosition.Y + g] > level.scentmap.buffer1[GridPosition.X, GridPosition.Y]) { CurrentPos = new Coord2(GridPosition.X + f, GridPosition.Y + g); level.path_count ++; } SetNextGridPosition(CurrentPos, level); } } } }
public void Update(Level level, Player plr) { try { sourceValue++; } catch { throw new Exception("A billion years passed and this somehow overflowed."); } // Make buffers identical. Array.Copy(bufferOne, bufferTwo, bufferTwo.Length); bufferOne[plr.GridPosition.X, plr.GridPosition.Y] = sourceValue; bufferTwo[plr.GridPosition.X, plr.GridPosition.Y] = sourceValue; // Iterate through cells, using one buffer for comparison and another for updating. for (int x = 0; x < level.GridSize; x++) { for (int y = 0; y < level.GridSize; y++) { for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { if (level.ValidPosition(new Coord2(x + i, y + j)) && (level.ValidPosition(new Coord2(x+i, y)) && level.ValidPosition(new Coord2(x, y+j)))) { if ((bufferOne[x, y] < bufferTwo[x + i, y + j])) bufferOne[x, y] = bufferTwo[x+i,y+j] - 1; } } } } } }
protected override void LoadContent() { // Create sprite batch spriteBatch = new SpriteBatch(GraphicsDevice); // Load textures tileTexture1 = Game.Content.Load<Texture2D>("Images/tile1"); tileTexture2 = Game.Content.Load<Texture2D>("Images/tile2"); playerTexture = Game.Content.Load<Texture2D>("Images/target"); botTexture = Game.Content.Load<Texture2D>("Images/ai"); // Load Font mainFont = Game.Content.Load<SpriteFont>("Fonts/bmpFont"); // Initialize the level level = new Level(new Map(tileTexture1, tileTexture2), new Player(playerTexture, 0, 0), new AiBotDijkstra(botTexture, 0, 0)); // Initialize mouse position mousePos = new Point(0, 0); base.LoadContent(); }
//this function is filled in by a derived class: must use SetNextGridLocation to actually move the bot protected abstract void ChooseNextGridLocation(Level level, Player plr);
protected override void ChooseNextGridLocation(Level level, Player plr) { }
public Game1() { //program settings. Window.Title = "GAL11266257_CGP3001M_Assignment 2"; graphics = new GraphicsDeviceManager(this); graphics.PreferredBackBufferHeight = BackBufferHeight; graphics.PreferredBackBufferWidth = BackBufferWidth; Content.RootDirectory = "../../../Content"; TargetElapsedTime = TimeSpan.FromTicks(TimeSpan.TicksPerSecond / TargetFrameRate); //loads map. level = new Level(); level.Loadmap("../../../Content/0.txt"); //loads player. player = new Player(125, 67); }
protected override void LoadContent() { // Create sprite batch spriteBatch = new SpriteBatch(GraphicsDevice); // Load textures tileTexture1 = Game.Content.Load<Texture2D>("Images/tile1"); tileTexture2 = Game.Content.Load<Texture2D>("Images/tile2"); playerTexture = Game.Content.Load<Texture2D>("Images/target"); botTexture = Game.Content.Load<Texture2D>("Images/ai"); level = new Level(new Map(tileTexture1, tileTexture2), new Player(playerTexture, 0, 0), new AiBotBlank(botTexture, 0, 0)); base.LoadContent(); }
// Set cost of cell (parent cost + movement cost). private void SetCost(Coord2 currentPosition, Level level, int x, int y, bool diag) { int moveCost; if (!diag) moveCost = 10; else moveCost = 14; if (cost[currentPosition.X + x, currentPosition.Y + y] > cost[currentPosition.X, currentPosition.Y] + moveCost) { cost[currentPosition.X + x, currentPosition.Y + y] = cost[currentPosition.X, currentPosition.Y] + moveCost; link[currentPosition.X + x, currentPosition.Y + y] = currentPosition; } }
// Generate the path. public void Build(Level level, AiBotBase bot, Player plr) { cost[bot.GridPosition.X, bot.GridPosition.Y] = 0; Coord2 currentPosition = bot.GridPosition; closed[bot.GridPosition.X, bot.GridPosition.Y] = true; while (!closed[plr.GridPosition.X, plr.GridPosition.Y]) { // Open adjacent cells. for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { if (level.ValidPosition(new Coord2(currentPosition.X + i, currentPosition.Y + j)) && !closed[currentPosition.X + i, currentPosition.Y + j] && (i != 0 || j != 0) && (currentPosition.X + i < level.GridSize && currentPosition.Y + j < level.GridSize && currentPosition.X + i >= 0 && currentPosition.Y + j >= 0) && (level.ValidPosition(new Coord2(currentPosition.X + i, currentPosition.Y)) && level.ValidPosition(new Coord2(currentPosition.X, currentPosition.Y + j)))) { if (i == 0 || j == 0) SetCost(currentPosition, level, i, j, false); else SetCost(currentPosition, level, i, j, true); } } } float lowestCost = int.MaxValue; Coord2 nextPosition = currentPosition; // Iterate through the list to check open cells for valid movements. for (int i = 0; i < level.GridSize; i++) { for (int j = 0; j < level.GridSize; j++) { if (!closed[i, j] && level.ValidPosition(new Coord2(i, j)) && cost[i, j] < lowestCost) { lowestCost = cost[i, j]; nextPosition = new Coord2(i, j); } } } if (currentPosition == nextPosition) break; closed[nextPosition.X, nextPosition.Y] = true; currentPosition = nextPosition; } bool done = false; Coord2 nextClose = plr.GridPosition; while (!done) { if (nextClose.X == -1) break; if (nextClose == bot.GridPosition) { playerPos = plr.GridPosition; done = true; } inPath[nextClose.X, nextClose.Y] = true; path.Add(new Coord2(nextClose.X, nextClose.Y)); nextClose = link[nextClose.X, nextClose.Y]; } }
//generates path. public void Build(Level level, AiBotBase bot, Player plr) { //starts timing the algorithm. var watch = Stopwatch.StartNew(); astar_is_built = true; astar_built = true; //fill nodes with default value. for (int i = 0; i < map_size; i++) { for (int j = 0; j < map_size; j++) { closed[i, j] = false; cost[i, j] = 999999; link[i, j] = new Coord2(-1, -1); inPath[i, j] = false; } } open_locations.Add(bot.GridPosition); Coord2 lowest_location = new Coord2(-1, -1); float lowest_cost = 999999; float newcost = 999999; closed[bot.GridPosition.X, bot.GridPosition.Y] = false; cost[bot.GridPosition.X, bot.GridPosition.Y] = 0; //heuristic calculation for (int i = 0; i < map_size; i++) { for (int j = 0; j < map_size; j++) { if (level.manhatten == true) { heuristic[i, j] = Math.Abs(i - plr.GridPosition.X) + Math.Abs(j - plr.GridPosition.Y);//manhatten. } else if (level.diagonal == true) { heuristic[i, j] = Math.Max(Math.Abs(i - plr.GridPosition.X), Math.Abs(j - plr.GridPosition.Y));//diagonal. } else if (level.euclidian == true) { heuristic[i, j] = (int)Math.Sqrt(Math.Pow(i - plr.GridPosition.X, 2) + Math.Pow(j - plr.GridPosition.Y, 2));//euclidian. } else { heuristic[i, j] = Math.Abs(i - plr.GridPosition.X) + Math.Abs(j - plr.GridPosition.Y);//manhatten is the default heuristic. } } } while (!closed[plr.GridPosition.X, plr.GridPosition.Y]) { lowest_cost = 999999; //unoptomised astar. if (level.astar_unoptomised_chosen == true) { for (int x = 0; x < map_size; x++) { for (int y = 0; y < map_size; y++) { if (cost[x, y] + heuristic[x, y] < lowest_cost && !closed[x, y]) { lowest_cost = cost[x, y] + heuristic[x, y]; lowest_location = new Coord2(x, y); } } } } else { //optomised astar, only checks open locations. for (int x = 0; x < open_locations.Count(); x++) { if ((cost[open_locations[x].X, open_locations[x].Y] + heuristic[open_locations[x].X, open_locations[x].Y]) < lowest_cost && !closed[open_locations[x].X, open_locations[x].Y]) { lowest_cost = cost[open_locations[x].X, open_locations[x].Y] + heuristic[open_locations[x].X, open_locations[x].Y]; lowest_location = new Coord2(open_locations[x].X, open_locations[x].Y); } } } closed[lowest_location.X, lowest_location.Y] = true; open_locations.Remove(lowest_location); //counts nodes closed. if (closed[lowest_location.X, lowest_location.Y] == true) { isClosed ++; } for (int f = -1; f <= 1; f++) { for (int g = -1; g <= 1; g++) { //assigns a cost to each location surrounding the current path node. if (level.ValidPosition(new Coord2(lowest_location.X + f, lowest_location.Y + g))) { newcost = 999999; Coord2 neighbour_location; neighbour_location = new Coord2(lowest_location.X + f, lowest_location.Y + g); if (f != 0 ^ g != 0) { //horizontal cost. newcost = 1f; } else if (f != 0 && g != 0) { //diagonal cost. newcost = 1.4f; } if (!open_locations.Contains(neighbour_location) && neighbour_location != bot.GridPosition) { open_locations.Add(neighbour_location); } if (newcost < cost[lowest_location.X + f, lowest_location.Y + g] && level.ValidPosition(new Coord2(lowest_location.X + f, lowest_location.Y + g)) && !closed[lowest_location.X + f, lowest_location.Y + g]) { cost[lowest_location.X + f, lowest_location.Y + g] = newcost;//assigns current cost to the new cost. link[lowest_location.X + f, lowest_location.Y + g] = new Coord2(lowest_location.X, lowest_location.Y);//assigns current link to lowest location. } } } } } bool done = false; Coord2 nextclosed = plr.GridPosition; while (done == false) { //adds next step to path. astar_path.Add(nextclosed); inPath[nextclosed.X, nextclosed.Y] = true; nextclosed = link[nextclosed.X, nextclosed.Y]; if (nextclosed == bot.GridPosition) { astar_path.Add(bot.GridPosition);//adds path to the bot. done = true; } } astar_path.Reverse();//reverse path for reading. watch.Stop(); elapsedMS = watch.ElapsedMilliseconds; }
public Game1() { //constructor graphics = new GraphicsDeviceManager(this); graphics.PreferredBackBufferHeight = BackBufferHeight; graphics.PreferredBackBufferWidth = BackBufferWidth; Window.Title = "Pathfinder"; Content.RootDirectory = "Content"; this.IsMouseVisible = true; this.IsFixedTimeStep = false; elapsedTime = 0; frameCounter = 0; FPS = 60; mouseState = Mouse.GetState(); lastMouseState = mouseState; mouseClickPos = new Coord2(-1, -1); scrollOffset = Vector2.Zero; textColour = Color.BlueViolet; //set frame rate TargetElapsedTime = TimeSpan.FromTicks(TimeSpan.TicksPerSecond / TargetFrameRate); //load level map level = new Level(); string mapName = mapNumber.ToString(); //mapName = "eighty"; level.Loadmap("Content/" + mapName + ".txt"); //instantiate bot and player objects BackBufferWidth = level.gridSquareSize * level.GridSizeX; BackBufferHeight = level.GridSizeY * level.GridSquareSize; graphics.PreferredBackBufferHeight = BackBufferHeight; graphics.PreferredBackBufferWidth = BackBufferWidth; graphics.ApplyChanges(); graphics.GraphicsDevice.Reset(); SetCharacters(); //bots = new List<AiBotBase>(); #if ASTARTEST string heuristic = "Euclidean"; StreamWriter r = new StreamWriter("astarTest-" + mapName + "-" + heuristic + ".txt"); r.WriteLine("A Star Test values with " + heuristic); r.WriteLine("Map size: {0}x{1}", level.GridSizeX, level.GridSizeY); r.WriteLine("Times per build, in ms"); AStar aStar = new AStar(level); aStar = new AStar(level); Stopwatch timer = new Stopwatch(); Coord2 start = new Coord2(1, 1); Coord2 end = new Coord2(level.GridSizeX-1, level.GridSizeY-1); for (int i = 0; i < 1000; i++) { timer.Restart(); aStar.Build(level, start, end, false, heuristic); timer.Stop(); r.WriteLine("{0:N3}", timer.Elapsed.TotalMilliseconds); } r.Close(); #endif #if DIJKSTRASTEST StreamWriter r = new StreamWriter("dijkstrasTest-" + mapName + ".txt"); string mapDescription = ""; r.WriteLine("Dijkstra's Test values"); r.WriteLine("Map size: {0}x{1}", level.GridSizeX, level.GridSizeY); r.WriteLine(mapDescription); r.WriteLine("Times per build, in ms"); Dijkstra dijkstras = new Dijkstra(level); dijkstras = new Dijkstra(level); Stopwatch timer = new Stopwatch(); AiBotAlgorithm bot = new AiBotAlgorithm(1, 1); Player player = new Player(level.GridSizeX - 1, level.GridSizeY - 1); for (int i = 0; i < 1000; i++) { timer.Restart(); dijkstras.Build(level, bot, player); timer.Stop(); r.WriteLine("{0:N3}", timer.Elapsed.TotalMilliseconds); } r.Close(); #endif #if PRECOMPUTETEST StreamWriter r = new StreamWriter("precomputeTest-" + mapName + ".txt"); string mapDescription = ""; r.WriteLine("Precompute's Test values"); r.WriteLine("Map size: {0}x{1}", level.GridSizeX, level.GridSizeY); r.WriteLine(mapDescription); r.WriteLine("Times per build, in ms"); Precompute precompute = new Precompute(mapName); precompute = new Precompute(mapName); Stopwatch timer = new Stopwatch(); AiBotAlgorithm bot = new AiBotAlgorithm(1, 1); Player player = new Player(level.GridSizeX - 1, level.GridSizeY - 1); for (int i = 0; i < 1; i++) { timer.Restart(); precompute.Calculate(level); timer.Stop(); r.WriteLine("{0:N3}", timer.Elapsed.TotalMilliseconds); } r.Close(); #endif }
// Set the total cost of cells (parent + movement + heuristic). private void SetCost(Coord2 currentPosition, Coord2 plr, Level level, int x, int y, bool diag) { int moveCost; if (!diag) moveCost = 10; else moveCost = 14; if (gCost[currentPosition.X + x, currentPosition.Y + y] > gCost[currentPosition.X, currentPosition.Y] + moveCost) { float hCost = 0; if (heuristic == "Manhattan") hCost = Manhattan(currentPosition, plr, x, y); else if (heuristic == "Chebyshev") hCost = Chebyshev(currentPosition, plr, x, y); else if (heuristic == "Euclidean") hCost = Euclidean(currentPosition, plr, x, y); link[currentPosition.X + x, currentPosition.Y + y] = currentPosition; gCost[currentPosition.X + x, currentPosition.Y + y] = gCost[currentPosition.X, currentPosition.Y] + moveCost; cost[currentPosition.X + x, currentPosition.Y + y] = gCost[currentPosition.X + x, currentPosition.Y + y] + hCost; // // Heuristic. } }
public void Build(Level level, Coord2 from, Coord2 to, bool cutCorners, string heuristicIn) { cutCorners = !cutCorners; heuristic = heuristicIn; gCost[from.X, from.Y] = 0; Coord2 currentPosition = from; closed[from.X, from.Y] = true; while (!closed[to.X, to.Y]) { // Open adjacent cells. for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { if (level.ValidPosition(new Coord2(currentPosition.X + i, currentPosition.Y + j)) && !closed[currentPosition.X+i, currentPosition.Y+j]) // Make sure position is valid// Make sure position is in range { if (cutCorners) if (!(level.ValidPosition(new Coord2(currentPosition.X + i, currentPosition.Y)) && level.ValidPosition(new Coord2(currentPosition.X, currentPosition.Y + j)))) continue; if (!open.Contains(new Coord2(currentPosition.X + i, currentPosition.Y + j))) open.Add(new Coord2(currentPosition.X + i, currentPosition.Y + j)); if (i == 0 || j == 0) SetCost(currentPosition, to, level, i, j, false); else SetCost(currentPosition, to, level, i, j, true); } } } float lowestCost = int.MaxValue; Coord2 nextPosition = currentPosition; // Iterate through the open list to find next cell. for (int i = 0; i < open.Count; i++) { if (cost[open[i].X, open[i].Y] < lowestCost) { lowestCost = cost[open[i].X, open[i].Y]; nextPosition = new Coord2(open[i].X, open[i].Y); } } if (currentPosition == nextPosition) break; open.Remove(nextPosition); closed[nextPosition.X, nextPosition.Y] = true; currentPosition = nextPosition; } bool done = false; Coord2 nextClose = to; // When destination is found, cycle through parents to find the path. while (!done) { if (nextClose.X == -1) break; if (nextClose == from) { playerPos = to; done = true; } inPath[nextClose.X, nextClose.Y] = true; path.Add(new Coord2(nextClose.X, nextClose.Y)); nextClose = link[nextClose.X, nextClose.Y]; } }
//generates path. public void Build(Level level, AiBotBase bot, Player plr) { //starts timing the algorithm. var watch = Stopwatch.StartNew(); dijkstra_is_built = true; dijkstra_built = true; //fill nodes with default value. for (int i = 0; i < map_size; i++) { for (int j = 0; j < map_size; j++) { closed[i, j] = false; cost[i, j] = float.MaxValue; link[i, j] = new Coord2(-1, -1); inPath[i, j] = false; } } Coord2 lowest_location = new Coord2 (-1, -1); float lowest_cost = float.MaxValue; closed[bot.GridPosition.X, bot.GridPosition.Y] = false; cost[bot.GridPosition.X, bot.GridPosition.Y] = 0; while (!closed[plr.GridPosition.X, plr.GridPosition.Y]) { lowest_cost = float.MaxValue; for (int x = 0; x < map_size; x++) { for (int y = 0; y < map_size; y++) { //sets new lowest cost. if(cost[x,y] <= lowest_cost && !closed[x, y]) { lowest_cost = cost[x, y]; lowest_location = new Coord2(x, y); } } } //closes that node. closed[lowest_location.X, lowest_location.Y] = true; //counts nodes closed. if(closed[lowest_location.X, lowest_location.Y] == true) { isClosed ++; } for (int f = -1; f <= 1; f++) { for (int g = -1; g <= 1; g++) { //assigns a cost to each location surrounding the current path node. if(level.ValidPosition(new Coord2(lowest_location.X + f, lowest_location.Y + g))) { float newcost = float.MaxValue; if(f != 0 ^ g != 0) { //horizontal cost. newcost = lowest_cost + 1f; } else if (f != 0 && g != 0) { //diagonal cost. newcost = lowest_cost + 1.4f; } if(newcost < cost[lowest_location.X + f, lowest_location.Y + g] && level.ValidPosition(new Coord2(lowest_location.X + f, lowest_location.Y + g))) { cost[lowest_location.X + f, lowest_location.Y + g] = newcost;//assigns current cost to the new cost. link[lowest_location.X + f, lowest_location.Y + g] = new Coord2(lowest_location.X, lowest_location.Y);//assigns current link to lowest location. } } } } } bool done = false; nextclosed = plr.GridPosition; while (done == false) { //adds next step to path. dijkstra_path.Add(nextclosed); inPath[nextclosed.X, nextclosed.Y] = true; nextclosed = link[nextclosed.X, nextclosed.Y]; if (nextclosed == bot.GridPosition) { dijkstra_path.Add(bot.GridPosition);//adds path to the bot. done = true; } } dijkstra_path.Reverse();//reverse path for reading. elapsedMS = watch.ElapsedMilliseconds; }