// 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); } }
public Game1() { //constructor graphics = new GraphicsDeviceManager(this); graphics.PreferredBackBufferHeight = BackBufferHeight; graphics.PreferredBackBufferWidth = BackBufferWidth; Window.Title = "Pathfinder"; Content.RootDirectory = "../../../Content"; //set frame rate TargetElapsedTime = TimeSpan.FromTicks(TimeSpan.TicksPerSecond / TargetFrameRate); //load level map level = new Level(); level.Loadmap("../../../Content/0.txt"); //instantiate bot and player objects player = new Player(1, 1); //bot = new AiBotPathFollower(38, 38); //bot = new AiBotStatic(38, 38); allBots = new List <AiBotBase>() { new AiBotStatic(38, 38), new AiBotStatic(38, 15), new AiBotStatic(15, 38), new AiBotStatic(15, 15), new AiBotStatic(5, 5), new AiBotStatic(38, 1), new AiBotStatic(1, 38), new AiBotStatic(35, 1), new AiBotStatic(1, 35), new AiBotStatic(5, 15), new AiBotStatic(15, 5), new AiBotStatic(10, 15), new AiBotStatic(15, 10), new AiBotStatic(25, 20), new AiBotStatic(20, 25), new AiBotStatic(12, 12), new AiBotStatic(1, 8), new AiBotStatic(8, 1), new AiBotStatic(32, 18), new AiBotStatic(18, 32) }; //allBots = new List<AiBotBase>() { new AiBotStatic(38, 38), new AiBotStatic(38, 15), new AiBotStatic(15, 38), new AiBotStatic(15, 15), new AiBotStatic(5, 5), new AiBotStatic(38, 1), new AiBotStatic(1, 38), new AiBotStatic(35, 1), new AiBotStatic(1, 35), new AiBotStatic(5, 15), new AiBotStatic(15, 5), new AiBotStatic(10, 15), new AiBotStatic(15, 10), new AiBotStatic(25, 20), new AiBotStatic(20, 25), new AiBotStatic(12, 12), new AiBotStatic(1, 8), new AiBotStatic(8, 1), new AiBotStatic(32, 18), new AiBotStatic(18, 32) }; foreach (AiBotBase b in allBots) { //b.Update(gameTime, level, player); b.Update(new GameTime(), level, player); } bot = allBots[0]; DoTest(); }
public void Update(Level level, Player plr, AiBotBase bot) { if (running == true) { watch.Start(); } sourceValue++; for (int x = 0; x < 40; x++) { for (int y = 0; y < 40; y++) { buffer1[x, y] = buffer2[x, y]; } } //Array.Copy(buffer1, buffer2, buffer2.Length); buffer1[plr.GridPosition.X, plr.GridPosition.Y] = sourceValue; for (int xx = 0; xx < 40; xx++) { for (int yy = 0; yy < 40; yy++) { if (level.ValidPosition(new Coord2(xx, yy))) { int highestScent = 0; Coord2 pos = new Coord2(xx, yy); for (int i = 0; i < 8; i++) { Coord2 test = pos + PreCalcNeighbours[i]; if (test.X >= 0 && test.X < gridSize && test.Y >= 0 && test.Y < gridSize) { int temp = buffer1[pos.X + PreCalcNeighbours[i].X, pos.Y + PreCalcNeighbours[i].Y]; if (temp > highestScent) { highestScent = temp; } } buffer2[pos.X, pos.Y] = highestScent - 1; } } } } if ((buffer1[bot.GridPosition.X, bot.GridPosition.Y] <= 0)) { running = true; } else if ((buffer1[bot.GridPosition.X, bot.GridPosition.Y] >= 1)) { running = false; if (running == false) { watch.Stop(); scentTimer = watch.ElapsedMilliseconds.ToString(); //Console.WriteLine("Scent time = " + scentTimer + " Milliseconds"); watch.Reset(); } } }
private void SetBotType(PathfinderAlgorithm algorithm) { if (algorithm == PathfinderAlgorithm.Dijkstra || algorithm == PathfinderAlgorithm.AStar) { bot = new AiBotDijkstra(bot.Texture, bot.GridPosition.X, bot.GridPosition.Y); } else if (algorithm == PathfinderAlgorithm.ScentMap) { bot = new AiBotScent(bot.Texture, bot.GridPosition.X, bot.GridPosition.Y); } else { Console.WriteLine("Could not set bot type, unrecognized algorithm."); } }
public Game1() { //constructor graphics = new GraphicsDeviceManager(this); graphics.PreferredBackBufferHeight = BackBufferHeight; graphics.PreferredBackBufferWidth = BackBufferWidth; Window.Title = "Pathfinder - SHA12307610"; Content.RootDirectory = "../../../Content"; //set frame rate TargetElapsedTime = TimeSpan.FromTicks(TimeSpan.TicksPerSecond / TargetFrameRate); //load level map level = new Level(); level.Loadmap("../../../Content/5.txt"); //instantiate bot and player objects bot = new AiBotStatic(10, 20); player = new Player(30, 20); }
public Level(Map map, Player plr, AiBotBase bot) { this.map = map; this.player = plr; this.bot = bot; }
// Task B // Create a new class function called build(). This function will calculate the path, // and fill out the data arrays we defined above.The build function will need to take some parameters: // 1. A reference to a bot, to get the starting location // 2. A reference to the player, to get the end location // 3. A reference to a level, so we can determine which grid locations are blocked by walls public void Build(Level level, AiBotBase bot, Player plr) { // 1. All nodes should be marked as open // 2. Each node’s cost should be initialised to a very big number (1, 000, 000 for example) // 3. Links are not important at this stage, so just set them all to { -1,-1} // 4. Every value of “inPath” should be initialised as false. for (int i = 0; i < 40; i++) { for (int j = 0; j < 40; j++) { closed[i, j] = false; cost[i, j] = 1000000; link[i, j] = new Coord2(-1, -1); inPath[i, j] = false; heuristicValues[i, j] = Math.Abs(i - plr.GridPosition.X) + Math.Abs(j - plr.GridPosition.Y); //heuristicValues[i, j] = Math.Max(Math.Abs(i - plr.GridPosition.X), Math.Abs(j - plr.GridPosition.Y)); //heuristicValues[i, j] = (float)Math.Sqrt(((i - plr.GridPosition.X) * (i - plr.GridPosition.X)) + ((j - plr.GridPosition.Y) * (j - plr.GridPosition.Y))); } } path = new Coord2[200]; // To start the search, the bot’s position should be marked as open, eg: closed[bot.GridPosition.X, bot.GridPosition.Y] = false; // Similarly, the cost at the bot’s position should be set to zero cost[bot.GridPosition.X, bot.GridPosition.Y] = 0; //Temp coord position Coord2 pos; pos.X = 0; pos.Y = 0; // While the player grid position is not closed --- or maybe (pos != plr.GridPosition) while (!closed[plr.GridPosition.X, plr.GridPosition.Y]) { //Temp minium value for comparison float min = 1000000; // 1. Find the grid location with the lowest cost, that is not closed, and is not blocked on the map layout(on the first iteration of the loop, this should actually be the bot’s position). // If there are locations with equal lowest cost, it doesn’t matter which you choose. for (int i = 0; i < 40; i++) { for (int j = 0; j < 40; j++) { // If the cost of the searching grid position is less than the min position and is open and valid // update the pos and min cost if (cost[i, j] + heuristicValues[i, j] < min && closed[i, j] == false && level.ValidPosition(new Coord2(i, j))) { min = cost[i, j] + heuristicValues[i, j]; pos.X = i; pos.Y = j; } } } // 2. Mark this location as closed closed[pos.X, pos.Y] = true; // 3. Calculate a new cost for the 8 locations neighbouring this one: // this will be equal to the cost of the location that was just closed(the parent) + the cost of moving from there to the // neighbour(so, + 1 for left, right, up, down, + 1.4 for diagonals) : BUT only change the cost of the neighbouring square in the cost array IF: float pairCost = 0; //Loop through neighbouring grid coords for (int i = pos.X - 1; i < pos.X + 2; i++) { for (int j = pos.Y - 1; j < pos.Y + 2; j++) { // a. The neighbouring location is not blocked on the map layout. if (level.ValidPosition(new Coord2(i, j)) && !closed[i, j]) { // Set the cost value for moving to the new location if (i != pos.X && j != pos.Y) { pairCost = 1.4f; } else if ((i != pos.X && j == pos.Y) || (i == pos.X && j != pos.Y)) { pairCost = 1.0f; } else { pairCost = 0.0f; } // b. The new cost value found for the neighbour is lower than its current cost value. if (cost[pos.X, pos.Y] + pairCost < cost[i, j]) { // Set the cost value of the neigbour cost[i, j] = cost[pos.X, pos.Y] + pairCost; // 4. If you have set a new cost value for a neighbour, then also set its corresponding link value to be equal to the coordinates of its parent // (the location that was closed) link[i, j] = pos; } } } } // 5. This should be repeated until the location occupied by the player is closed, at which point the while loop should terminate. } // Task C // When the loop has terminated (the player’s location has been closed), the array of links should represent a traceable path from the player back to the bot. // This path is defined by the values in the link array.The next task is to extract these locations. // // Starting from the player coordinates, trace back through the links array and mark the corresponding entries in the “inPath” array to true. // The code for this should look something like: //Set to true when we are back at the bot position bool done = false; //Start of path Coord2 nextClosed = plr.GridPosition; int pathCounter = 0; path[0] = plr.GridPosition; //While not at the bots position while (!done) { //Set in path as true inPath[nextClosed.X, nextClosed.Y] = true; pathCounter++; //Set the next closed coord nextClosed = link[nextClosed.X, nextClosed.Y]; path[pathCounter] = nextClosed; //If the nextclosed is the bots position finish the loop if (nextClosed == bot.GridPosition) { done = true; } } path[pathCounter + 1] = bot.GridPosition; int swag = 9; swag++; }
public void Build(Level level, AiBotBase bot, Player plr) { watch.Start(); float gScore = float.MaxValue; for (int x = 0; x < 40; x++) { for (int y = 0; y < 40; y++) { IsOpen[x, y] = true; //Set all to open cost[x, y] = float.MaxValue; link[x, y] = new Coord2(-1, -1); inPath[x, y] = false; //Manhattan heuristic h[x, y] = Math.Abs(x - plr.GridPosition.X) + Math.Abs(y - plr.GridPosition.Y); } } IsOpen[bot.GridPosition.X, bot.GridPosition.Y] = true; cost[bot.GridPosition.X, bot.GridPosition.Y] = 0; Coord2 currentNode = new Coord2(); //Loop while location occupied by the player is closed while (IsOpen[plr.GridPosition.X, plr.GridPosition.Y] == true) { gScore = float.MaxValue; //Find the grid location with the lowest cost, that is not closed, and is not blocked for (int x = 0; x < 40; x++) { for (int y = 0; y < 40; y++) { //Is open if (IsOpen[x, y] == true) { //Is not blocked if (level.ValidPosition(new Coord2(x, y))) { if (cost[x, y] + h[x, y] < gScore) { //If the cost is lower, save it to lowest cost //and remember the position currentNode = new Coord2(x, y); gScore = cost[x, y] + h[x, y]; } } } } } //Mark the lowest cost node as closed IsOpen[currentNode.X, currentNode.Y] = false; //Calculate new cost for the 8 locations around this node for (int i = 0; i < 8; i++) { //Get the position of each neighbour Coord2 neighbourPosition = new Coord2(currentNode.X + PreCalcNeighbours[i].X, currentNode.Y + PreCalcNeighbours[i].Y); //Is the neighboura valid position if (level.ValidPosition(neighbourPosition)) { float newCost; //Straights if (i <= 3) { newCost = cost[currentNode.X, currentNode.Y] + 1; } else //Diagonals { newCost = cost[currentNode.X, currentNode.Y] + 1.4f; } //If this new cost is lower than the neighbours orginal cost if (newCost <= cost[neighbourPosition.X, neighbourPosition.Y]) { //Set the neighbours cost to be the new one cost[neighbourPosition.X, neighbourPosition.Y] = newCost; //Also set the neighbours link value to be the parent link[neighbourPosition.X, neighbourPosition.Y] = currentNode; } } } } bool done = false; Coord2 nextClosed = plr.GridPosition; while (!done) { inPath[nextClosed.X, nextClosed.Y] = true; nextClosed = link[nextClosed.X, nextClosed.Y]; if (nextClosed == bot.GridPosition) { done = true; } } watch.Stop(); AStarTimer = watch.ElapsedMilliseconds.ToString(); Console.WriteLine("AStar time = " + AStarTimer + " Milliseconds"); watch.Reset(); }
public int Build(Level level, AiBotBase bot, Player plr) { DateTime start = DateTime.Now; for (int x = 0; x < 40; x++) { for (int y = 0; y < 40; y++) { closed[x, y] = false; cost[x, y] = 1000000.0f; link[x, y] = new Coord2(-1, -1); inPath[x, y] = false; } } cost[bot.GridPosition.X, bot.GridPosition.Y] = 0.0f; bool done = false; Coord2 bestPos = new Coord2(0, 0); while (!done) { float checkCost = 1000000; for (int x = 0; x < 40; x++) { for (int y = 0; y < 40; y++) { if (cost[x, y] < checkCost && !closed[x, y]) { bestPos.X = x; bestPos.Y = y; checkCost = cost[x, y]; //Debug.WriteLine("Best Pos X: " + bestPos.X + " Y:" + bestPos.Y); } } } //Debug.WriteLine(plr.GridPosition.X + " " + plr.GridPosition.Y + "::" + bot.GridPosition.X + " " + bot.GridPosition.Y); closed[bestPos.X, bestPos.Y] = true; // For some reason this code is broken? Not sure why. for (int x = -1; x <= 1; x++) { for (int y = -1; y <= 1; y++) { float costMod = costings[x + 1, y + 1]; float newCost = cost[bestPos.X, bestPos.Y] + costMod; Coord2 checkPos = new Coord2(bestPos.X + x, bestPos.Y + y); if (level.ValidPosition(checkPos)) { if (cost[bestPos.X + x, bestPos.Y + y] > newCost) { cost[bestPos.X + x, bestPos.Y + y] = newCost; link[bestPos.X + x, bestPos.Y + y].X = bestPos.X; link[bestPos.X + x, bestPos.Y + y].Y = bestPos.Y; } } /*try * //{ * if (bestPos.X > 0 && bestPos.Y > 0 && bestPos.X < 39 && bestPos.Y < 39) * { * if (cost[bestPos.X + x, bestPos.Y + y] > newCost && level.ValidPosition(bestPos)) * { * cost[bestPos.X + x, bestPos.Y + y] = newCost; * link[bestPos.X + x, bestPos.Y + y].X = bestPos.X; * link[bestPos.X + x, bestPos.Y + y].Y = bestPos.Y; * //Debug.WriteLine("X: " + bestPos.X + " Y: " + bestPos.Y); * } * } * //} * //catch * //{ * //Debug.WriteLine("Here"); * //}*/ } } if (bestPos == plr.GridPosition) { done = true; //Debug.WriteLine("DONE"); } } done = false; Coord2 nextClosed = plr.GridPosition; while (!done) { inPath[nextClosed.X, nextClosed.Y] = true; nextClosed = link[nextClosed.X, nextClosed.Y]; if (nextClosed == bot.GridPosition) { done = true; } } DateTime end = DateTime.Now; TimeSpan duration = end - start; return(duration.Milliseconds); }
protected override void Update(GameTime gameTime) { //initialize keyboard controls. KeyboardState keyState = Keyboard.GetState(); Coord2 currentPos = new Coord2(); currentPos = player.GridPosition; //player movement. if (keyState.IsKeyDown(Keys.Escape))//exit. { //writes data to text files when the escape button is pressed, is blank otherwise. astar_writetext.Close(); astar_unoptomised_writetext.Close(); dijkstra_writetext.Close(); scentmap_writetext.Close(); this.Exit(); } if (keyState.IsKeyDown(Keys.W))//up. { currentPos.Y -= 1; player.SetNextLocation(currentPos, level); } else if (keyState.IsKeyDown(Keys.S))//down. { currentPos.Y += 1; player.SetNextLocation(currentPos, level); } else if (keyState.IsKeyDown(Keys.A))//left { currentPos.X -= 1; player.SetNextLocation(currentPos, level); } else if (keyState.IsKeyDown(Keys.D))//right. { currentPos.X += 1; player.SetNextLocation(currentPos, level); } //select astar. if (keyState.IsKeyDown(Keys.D1) && !oldState.IsKeyDown(Keys.D1)) { //sets other algorithms to false and resets current path. level.dijkstra_chosen = false; level.scentmap_chosen = false; level.astar_unoptomised_chosen = false; level.astar_chosen = true; level.astar.reset_path(); //resets heuristic level.manhatten = false; level.euclidian = false; level.diagonal = false; //initilizes a new bot and clears the current path. astar_bot = new AStarBot(1, 1); level.astar.astar_path.Clear(); //resets and restarts the path timer. astar_timer_start = true; stopwatch.Reset(); stopwatch.Start(); //builds current selection. level.build_astar = true; level.astar.Build(level, astar_bot, player); astar_draw = true; astar_unoptomised_draw = false; dijkstra_draw = false; scentmap_draw = false; //writes analysis data to the text file. astar_writetext.WriteLine("Heuristic Chosen: Manhatten"); astar_writetext.WriteLine("Path Count: " + level.astar.astar_path.Count()); astar_writetext.WriteLine("Execution Time: " + level.astar.elapsedMS + "ms"); astar_writetext.WriteLine("Closed Nodes: " + level.astar.isClosed); } //select dijkstra. else if (keyState.IsKeyDown(Keys.D2) && !oldState.IsKeyDown(Keys.D2)) { //sets other algorithms to false and resets current path. level.astar_chosen = false; level.scentmap_chosen = false; level.astar_unoptomised_chosen = false; level.dijkstra_chosen = true; level.dijkstra.reset_path(); //initilizes a new bot and clears the current path. dijkstra_bot = new DijkstraBot(1, 1); level.dijkstra.dijkstra_path.Clear(); //resets and restarts the path timer. dijkstra_timer_start = true; stopwatch.Reset(); stopwatch.Start(); //builds current selection. level.build_dijkstra = true; level.dijkstra.Build(level, dijkstra_bot, player); dijkstra_draw = true; astar_draw = false; scentmap_draw = false; //writes analysis data to the text file. dijkstra_writetext.WriteLine("Path Count: " + level.dijkstra.dijkstra_path.Count()); dijkstra_writetext.WriteLine("Execution Time: " + level.dijkstra.elapsedMS + "ms"); dijkstra_writetext.WriteLine("Closed Nodes: " + level.dijkstra.isClosed); } //select scentmap. else if (keyState.IsKeyDown(Keys.D3) && !oldState.IsKeyDown(Keys.D3)) { //sets other algorithms to false and resets current path. level.astar_chosen = false; level.dijkstra_chosen = false; level.astar_unoptomised_chosen = false; level.scentmap_chosen = true; level.scentmap.reset_path(); level.path_count = 0; //initilizes a new bot. scentmap_bot = new ScentmapBot(1,1); //resets and restarts the path timer. scentmap_timer_start = true; stopwatch.Reset(); stopwatch.Start(); //builds current selection. scentmap_draw = true; astar_draw = false; dijkstra_draw = false; } //select unoptomised astar. else if (keyState.IsKeyDown(Keys.D4) && !oldState.IsKeyDown(Keys.D4)) { //sets other algorithms to false and resets current path. level.astar_chosen = false; level.dijkstra_chosen = false; level.scentmap_chosen = false; level.astar_unoptomised_chosen = true; level.astar.reset_path(); //resets heuristic level.manhatten = false; level.euclidian = false; level.diagonal = false; //initilizes a new bot and clears the current path. astar_bot = new AStarBot(1, 1); level.astar.astar_path.Clear(); //resets and restarts the path timer. astar_timer_start = true; stopwatch.Reset(); stopwatch.Start(); //builds current selection. level.build_astar = true; level.astar.Build(level, astar_bot, player); astar_draw = true; astar_unoptomised_draw = true; dijkstra_draw = false; scentmap_draw = false; //writes analysis data to the text file. astar_unoptomised_writetext.WriteLine("Heuristic Choson: Manhatten"); astar_unoptomised_writetext.WriteLine("Path Count: " + level.astar.astar_path.Count()); astar_unoptomised_writetext.WriteLine("Execution Time: " + level.astar.elapsedMS + "ms"); astar_unoptomised_writetext.WriteLine("Closed Nodes: " + level.astar.isClosed); } //heuristic changing for astar and unoptomised astar. if (level.astar_chosen || level.astar_unoptomised_chosen == true) { //Euclidian. if (keyState.IsKeyDown(Keys.E) && !oldState.IsKeyDown(Keys.E)) { level.manhatten = false; level.euclidian = true; level.diagonal = false; level.astar.reset_path(); //initilizes a new bot and clears the current path. astar_bot = new AStarBot(1, 1); level.astar.astar_path.Clear(); //resets and restarts the path timer. astar_timer_start = true; stopwatch.Reset(); stopwatch.Start(); //builds current selection. level.build_astar = true; level.astar.Build(level, astar_bot, player); astar_draw = true; dijkstra_draw = false; scentmap_draw = false; if(level.astar_chosen == true) { astar_writetext.WriteLine("Heuristic Chosen: Euclidian"); astar_writetext.WriteLine("Path Count: " + level.astar.astar_path.Count()); astar_writetext.WriteLine("Execution Time: " + level.astar.elapsedMS + "ms"); astar_writetext.WriteLine("Closed Nodes: " + level.astar.isClosed); } if(level.astar_unoptomised_chosen == true) { astar_unoptomised_writetext.WriteLine("Heuristic Choson: Euclidian"); astar_unoptomised_writetext.WriteLine("Path Count: " + level.astar.astar_path.Count()); astar_unoptomised_writetext.WriteLine("Execution Time: " + level.astar.elapsedMS + "ms"); astar_unoptomised_writetext.WriteLine("Closed Nodes: " + level.astar.isClosed); } } //Diagonal. if (keyState.IsKeyDown(Keys.R) && !oldState.IsKeyDown(Keys.R)) { level.manhatten = false; level.euclidian = false; level.diagonal = true; level.astar.reset_path(); //initilizes a new bot and clears the current path. astar_bot = new AStarBot(1, 1); level.astar.astar_path.Clear(); //resets and restarts the path timer. astar_timer_start = true; stopwatch.Reset(); stopwatch.Start(); //builds current selection. level.build_astar = true; level.astar.Build(level, astar_bot, player); astar_draw = true; dijkstra_draw = false; scentmap_draw = false; if (level.astar_chosen == true) { astar_writetext.WriteLine("Heuristic Chosen: Diagonal"); astar_writetext.WriteLine("Path Count: " + level.astar.astar_path.Count()); astar_writetext.WriteLine("Execution Time: " + level.astar.elapsedMS + "ms"); astar_writetext.WriteLine("Closed Nodes: " + level.astar.isClosed); } if (level.astar_unoptomised_chosen == true) { astar_unoptomised_writetext.WriteLine("Heuristic Choson: Diagonal"); astar_unoptomised_writetext.WriteLine("Path Count: " + level.astar.astar_path.Count()); astar_unoptomised_writetext.WriteLine("Execution Time: " + level.astar.elapsedMS + "ms"); astar_unoptomised_writetext.WriteLine("Closed Nodes: " + level.astar.isClosed); } } //Manhatten. if (keyState.IsKeyDown(Keys.T) && !oldState.IsKeyDown(Keys.T)) { level.manhatten = true; level.euclidian = false; level.diagonal = false; level.astar.reset_path(); //initilizes a new bot and clears the current path. astar_bot = new AStarBot(1, 1); level.astar.astar_path.Clear(); //resets and restarts the path timer. astar_timer_start = true; stopwatch.Reset(); stopwatch.Start(); //builds current selection. level.build_astar = true; level.astar.Build(level, astar_bot, player); astar_draw = true; dijkstra_draw = false; scentmap_draw = false; if (level.astar_chosen == true) { astar_writetext.WriteLine("Heuristic Chosen: Manhatten"); astar_writetext.WriteLine("Path Count: " + level.astar.astar_path.Count()); astar_writetext.WriteLine("Execution Time: " + level.astar.elapsedMS + "ms"); astar_writetext.WriteLine("Closed Nodes: " + level.astar.isClosed); } if (level.astar_unoptomised_chosen == true) { astar_unoptomised_writetext.WriteLine("Heuristic Choson: Manhatten"); astar_unoptomised_writetext.WriteLine("Path Count: " + level.astar.astar_path.Count()); astar_unoptomised_writetext.WriteLine("Execution Time: " + level.astar.elapsedMS + "ms"); astar_unoptomised_writetext.WriteLine("Closed Nodes: " + level.astar.isClosed); } } } oldState = keyState; //when the bot has reached its target, write how long it has taken to the text file. if(level.astar_chosen == true) { astar_bot.Update(gameTime, level, player); if (astar_bot.GridPosition == player.GridPosition && astar_timer_start == true) { stopwatch.Stop(); astar_path_completed = true; astar_timer_start = false; astar_writetext.WriteLine("Time to reach player: " + stopwatch.ElapsedMilliseconds / 1000 + " seconds"); astar_writetext.WriteLine("--------------------------------------------------------------------------"); } } //when the bot has reached its target, write how long it has taken to the text file. if (level.astar_unoptomised_chosen == true) { astar_bot.Update(gameTime, level, player); if (astar_bot.GridPosition == player.GridPosition && astar_timer_start == true) { stopwatch.Stop(); astar_path_completed = true; astar_timer_start = false; astar_unoptomised_writetext.WriteLine("Time to reach player: " + stopwatch.ElapsedMilliseconds / 1000 + " seconds"); astar_unoptomised_writetext.WriteLine("--------------------------------------------------------------------------"); } } //when the bot has reached its target, write how long it has taken to the text file. if(level.dijkstra_chosen == true) { dijkstra_bot.Update(gameTime, level, player); if (dijkstra_bot.GridPosition == player.GridPosition && dijkstra_timer_start == true) { stopwatch.Stop(); dijkstra_path_completed = true; dijkstra_timer_start = false; dijkstra_writetext.WriteLine("Time to reach player: " + stopwatch.ElapsedMilliseconds / 1000 + " seconds"); dijkstra_writetext.WriteLine("--------------------------------------------------------------------------"); } } //when the bot has reached its target, write how long it has taken to the text file. if(level.scentmap_chosen == true) { scentmap_bot.Update(gameTime, level, player); level.scentmap.Update(level, player); if (scentmap_bot.GridPosition == player.GridPosition && scentmap_timer_start == true) { stopwatch.Stop(); scentmap_path_completed = true; scentmap_timer_start = false; scentmap_writetext.WriteLine("Path Count: " + level.path_count); scentmap_writetext.WriteLine("Execution Time: " + level.scentmap.elapsedMS + "ms"); scentmap_writetext.WriteLine("Time to reach player: " + stopwatch.ElapsedMilliseconds / 1000 + " seconds"); scentmap_writetext.WriteLine("--------------------------------------------------------------------------"); } } player.Update(gameTime, level); base.Update(gameTime); }
//task b public void Build(Level level, AiBotBase bot, Player plr) { for (int i = 0; i < 40; i++) { for (int j = 0; j < 40; j++) { closed[i, j] = false; cost[i, j] = 1000000; link[i, j] = new Coord2(-1, -1); inPath[i, j] = false; } } closed[bot.GridPosition.X, bot.GridPosition.Y] = false; cost[bot.GridPosition.X, bot.GridPosition.Y] = 0; Coord2 pos; pos.X = 0; pos.Y = 0; while (!closed[plr.GridPosition.X, plr.GridPosition.Y]) { float min = 1000000; //step 1 for (int i = 0; i < 40; i++) { for (int j = 0; j < 40; j++) { if (cost[i, j] < min && closed[i, j] == false && level.ValidPosition(new Coord2(i, j))) { min = cost[i, j]; pos.X = i; pos.Y = j; } } } //step 2 closed[pos.X, pos.Y] = true; //step 3 float pairCost = 0; for (int i = pos.X - 1; i < pos.X + 2; i++) { for (int j = pos.Y - 1; j < pos.Y + 2; j++) { //step 3a if (level.ValidPosition(new Coord2(i, j)) && !closed[i, j]) { if (i != pos.X && j != pos.Y) { pairCost = 1.4f; } else if ((i != pos.X && j == pos.Y) || (i == pos.X && j != pos.Y)) { pairCost = 1.0f; } else { pairCost = 0.0f; } //step 3b if (cost[pos.X, pos.Y] + pairCost < cost[i, j]) { cost[i, j] = cost[pos.X, pos.Y] + pairCost; //step 4 link[i, j] = pos; } } } } //step 5 } //task c bool done = false; //set to true when we are back at the bot position Coord2 nextClosed = plr.GridPosition; //Start of path while (!done) { inPath[nextClosed.X, nextClosed.Y] = true; nextClosed = link[nextClosed.X, nextClosed.Y]; if (nextClosed == bot.GridPosition) { done = true; } } }
//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; }
// INITIALISE NODES AS OPEN public void Build(Level level, AiBotBase bot, Player plr) { for (int i = 0; i < 40; i++) { for (int j = 0; j < 40; j++) { closed[i, j] = false; //i++; j++; } } // INITIALISE NODES COST TO HIGH VALUE for (int i = 0; i < 40; i++) { for (int j = 0; j < 40; j++) { cost[i, j] = 1000000; //i++; j++; } } // INITIALISE LINK VALUES for (int i = 0; i < 40; i++) { for (int j = 0; j < 40; j++) { link[i, j] = new Coord2(-1, -1); //i++; j++; } } // INITIALISE INPATH VALUES AS FALSE for (int i = 0; i < 40; i++) { for (int j = 0; j < 40; j++) { inPath[i, j] = false; //i++; j++; } } // INITIALISE HEURISTIC VALUES for (int i = 0; i < 40; i++) { for (int j = 0; j < 40; j++) { heuristicVals[i, j] = Math.Abs(i - plr.GridPosition.X) + Math.Abs(j - plr.GridPosition.Y); } } path = new Coord2[200]; closed[bot.GridPosition.X, bot.GridPosition.Y] = false; cost[bot.GridPosition.X, bot.GridPosition.Y] = 0; Coord2 tempPos; tempPos.X = 0; tempPos.Y = 0; // WHILE THE PLAYERS GRID POSITION IS NOT CLOSED while (tempPos != plr.GridPosition) { float comparisonVal = 1000000; for (int i = 0; i < 40; i++) { for (int j = 0; j < 40; j++) { if (cost[i, j] + heuristicVals[i, j] < comparisonVal && closed[i, j] == false && level.ValidPosition(new Coord2(i, j))) { comparisonVal = cost[i, j] + heuristicVals[i, j]; tempPos.X = i; tempPos.Y = j; } } } // MARKING THE LOCATION AS CLOSED closed[tempPos.X, tempPos.Y] = true; float pairCost = 0; // GO THROUGH NEIGHBOURING COORDS for (int i = tempPos.X - 1; i < tempPos.X + 2; i++) { for (int j = tempPos.Y - 1; j < tempPos.Y + 2; j++) { if (level.ValidPosition(new Coord2(i, j)) && !closed[i, j]) { // SETTING COST VALUE FOR MOVING TO NEW GRID COORD if (i != tempPos.X && j != tempPos.Y) { // DIAGONALLY pairCost = 1.4f; } else if ((i != tempPos.X && j == tempPos.Y) || (i == tempPos.X && j != tempPos.Y)) { // UP, DOWN, LEFT AND RIGHT pairCost = 1.0f; } else { // NO MOVEMENT - BLOCKED PATH pairCost = 0.0f; } if (cost[tempPos.X, tempPos.Y] + pairCost < cost[i, j]) { cost[i, j] = cost[tempPos.X, tempPos.Y] + pairCost; link[i, j] = tempPos; } } } } } bool done = false; Coord2 nextClosed = plr.GridPosition; int pathCounter = 0; path[0] = plr.GridPosition; while (!done) { inPath[nextClosed.X, nextClosed.Y] = true; pathCounter++; nextClosed = link[nextClosed.X, nextClosed.Y]; path[pathCounter] = nextClosed; if (nextClosed == bot.GridPosition) { done = true; } } path[pathCounter + 1] = bot.GridPosition; int swag = 9; swag++; }
public void Build(Level level, AiBotBase bot, Player plr) { for (int i = 0; i < 40; i++) { for (int ii = 0; ii < 40; ii++) { closed[i, ii] = false; cost[i, ii] = 1000000; link[i, ii] = new Coord2(-1, -1); inPath[i, ii] = false; } } cost[bot.GridPosition.X, bot.GridPosition.Y] = 0; bool repeat = true; while (repeat) { Coord2 holdC = new Coord2(0, 0); Coord2 holdCM; float holdI = 10000000; for (int i = 0; i < 40; i++) { for (int ii = 0; ii < 40; ii++) { if (cost[i, ii] < holdI && closed[i, ii] != true) { holdI = cost[i, ii]; holdC.X = i; holdC.Y = ii; } } } closed[holdC.X, holdC.Y] = true; holdCM.X = holdC.X - 1; // Up holdCM.Y = holdC.Y; if (level.ValidPosition(holdCM)) { if (cost[holdCM.X, holdCM.Y] > cost[holdC.X, holdC.Y] + 1) { cost[holdCM.X, holdCM.Y] = cost[holdC.X, holdC.Y] + 1; link[holdCM.X, holdCM.Y].X = holdC.X; link[holdCM.X, holdCM.Y].Y = holdC.Y; } } holdCM.X = holdC.X - 1; // Up-Right holdCM.Y = holdC.Y + 1; if (level.ValidPosition(holdCM)) { if (cost[holdCM.X, holdCM.Y] > cost[holdC.X, holdC.Y] + 1.4) { cost[holdCM.X, holdCM.Y] = cost[holdC.X, holdC.Y] + 1.4f; link[holdCM.X, holdCM.Y].X = holdC.X; link[holdCM.X, holdCM.Y].Y = holdC.Y; } } holdCM.X = holdC.X; // Right holdCM.Y = holdC.Y + 1; if (level.ValidPosition(holdCM)) { if (cost[holdCM.X, holdCM.Y] > cost[holdC.X, holdC.Y] + 1) { cost[holdCM.X, holdCM.Y] = cost[holdC.X, holdC.Y] + 1; link[holdCM.X, holdCM.Y].X = holdC.X; link[holdCM.X, holdCM.Y].Y = holdC.Y; } } holdCM.X = holdC.X + 1; // Down-Right holdCM.Y = holdC.Y + 1; if (level.ValidPosition(holdCM)) { if (cost[holdCM.X, holdCM.Y] > cost[holdC.X, holdC.Y] + 1.4) { cost[holdCM.X, holdCM.Y] = cost[holdC.X, holdC.Y] + 1.4f; link[holdCM.X, holdCM.Y].X = holdC.X; link[holdCM.X, holdCM.Y].Y = holdC.Y; } } holdCM.X = holdC.X + 1; // Down holdCM.Y = holdC.Y; if (level.ValidPosition(holdCM)) { if (cost[holdCM.X, holdCM.Y] > cost[holdC.X, holdC.Y] + 1) { cost[holdCM.X, holdCM.Y] = cost[holdC.X, holdC.Y] + 1; link[holdCM.X, holdCM.Y].X = holdC.X; link[holdCM.X, holdCM.Y].Y = holdC.Y; } } holdCM.X = holdC.X + 1; // Down-Left holdCM.Y = holdC.Y - 1; if (level.ValidPosition(holdCM)) { if (cost[holdCM.X, holdCM.Y] > cost[holdC.X, holdC.Y] + 1.4) { cost[holdCM.X, holdCM.Y] = cost[holdC.X, holdC.Y] + 1.4f; link[holdCM.X, holdCM.Y].X = holdC.X; link[holdCM.X, holdCM.Y].Y = holdC.Y; } } holdCM.X = holdC.X; // Left holdCM.Y = holdC.Y - 1; if (level.ValidPosition(holdCM)) { if (cost[holdCM.X, holdCM.Y] > cost[holdC.X, holdC.Y] + 1) { cost[holdCM.X, holdCM.Y] = cost[holdC.X, holdC.Y] + 1; link[holdCM.X, holdCM.Y].X = holdC.X; link[holdCM.X, holdCM.Y].Y = holdC.Y; } } holdCM.X = holdC.X - 1; // Up-Left holdCM.Y = holdC.Y - 1; if (level.ValidPosition(holdCM)) { if (cost[holdCM.X, holdCM.Y] > cost[holdC.X, holdC.Y] + 1.4) { cost[holdCM.X, holdCM.Y] = cost[holdC.X, holdC.Y] + 1.4f; link[holdCM.X, holdCM.Y].X = holdC.X; link[holdCM.X, holdCM.Y].Y = holdC.Y; } } if (holdC.X == plr.GridPosition.X && holdC.Y == plr.GridPosition.Y) { repeat = false; } } repeat = true; Coord2 nextClosed = plr.GridPosition; // Start of path while (repeat) { inPath[nextClosed.X, nextClosed.Y] = true; nextClosed = link[nextClosed.X, nextClosed.Y]; if (nextClosed == bot.GridPosition) { repeat = false; } } }
public int Build(Level level, AiBotBase bot, Player plr) { DateTime start = DateTime.Now; for (int x = 0; x < 40; x++) { for (int y = 0; y < 40; y++) { closed[x, y] = false; cost[x, y] = 1000000.0f; link[x, y] = new Coord2(-1, -1); inPath[x, y] = false; heuristics[x, y] = 1000000; } } open = new List <Coord2>(); open.Add(bot.GridPosition); for (int x = 0; x < 40; x++) { for (int y = 0; y < 40; y++) { int xDif = Math.Abs(plr.GridPosition.X - x); int yDif = Math.Abs(plr.GridPosition.Y - y); heuristics[x, y] = xDif + yDif; } } cost[bot.GridPosition.X, bot.GridPosition.Y] = 0.0f; bool done = false; while (!done) { Coord2 bestPos = new Coord2(0, 0); float checkCost = 1000000; for (int x = 0; x < 40; x++) { for (int y = 0; y < 40; y++) { if (cost[x, y] + heuristics[x, y] < checkCost && !closed[x, y]) { bestPos.X = x; bestPos.Y = y; checkCost = cost[x, y] + heuristics[x, y]; } } } //Debug.WriteLine(plr.GridPosition.X + " " + plr.GridPosition.Y + "::" + bot.GridPosition.X + " " + bot.GridPosition.Y); closed[bestPos.X, bestPos.Y] = true; open.Remove(bestPos); for (int x = -1; x <= 1; x++) { for (int y = -1; y <= 1; y++) { float costMod = costings[x + 1, y + 1]; float newCost = cost[bestPos.X, bestPos.Y] + costMod; Coord2 checkPos = new Coord2(bestPos.X + x, bestPos.Y + y); if (level.ValidPosition(checkPos)) { if (cost[bestPos.X + x, bestPos.Y + y] > newCost) { cost[bestPos.X + x, bestPos.Y + y] = newCost; link[bestPos.X + x, bestPos.Y + y].X = bestPos.X; link[bestPos.X + x, bestPos.Y + y].Y = bestPos.Y; if (!open.Contains(new Coord2(x, y))) { open.Add(new Coord2(bestPos.X + x, bestPos.Y + y)); } } } } } if (bestPos == plr.GridPosition) { done = true; } } done = false; Coord2 nextClosed = plr.GridPosition; while (!done) { path.Add(nextClosed); inPath[nextClosed.X, nextClosed.Y] = true; nextClosed = link[nextClosed.X, nextClosed.Y]; if (nextClosed == bot.GridPosition) { done = true; } } //bot.pathToFollow = path; //bot.pathIndex = path.Count - 1; DateTime end = DateTime.Now; TimeSpan duration = end - start; return(duration.Milliseconds); }
//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; }
public void Build(Level level, AiBotBase bot, Player plr) { for (int i = 0; i < 40; i++) { for (int n = 0; n < 40; n++) { closed[i, n] = false; inPath[i, n] = false; cost[i, n] = 100000; link[i, n] = new Coord2(-1, -1); } } closed[bot.GridPosition.X, bot.GridPosition.Y] = false; cost[bot.GridPosition.X, bot.GridPosition.Y] = 0; int x = 0; int y = 0; while (closed[plr.GridPosition.X, plr.GridPosition.Y] == false) //while player location is open { float minValue = float.PositiveInfinity; int minFirstIndex = -1; int minSecondIndex = -1; for (int i = 40 - 1; i >= 0; --i) { for (int j = 40 - 1; j >= 0; --j) { float value = cost[i, j]; if (value < minValue && !closed[i, j] && level.ValidPosition(new Coord2(i, j))) //if its smaller, and not closed, and not blocked { minFirstIndex = i; minSecondIndex = j; minValue = value; } } } x = minFirstIndex; y = minSecondIndex; closed[x, y] = true; //mark lowest cost location as closed for (int a = -1; a < 2; a++) { for (int b = -1; b < 2; b++) { if (level.ValidPosition(new Coord2(x + a, y + b)) && cost[x, y] + 1 < cost[x + a, y + b] && !closed[x + a, y + b]) { float costl; if (a + b == 0 || a + b == 2) { costl = 1.4f; } else { costl = 1f; } cost[x + a, y + b] = cost[x, y] + costl; link[x + a, y + b] = new Coord2(x, y); } } } /*if (level.ValidPosition(new Coord2(x + 1, y)) && cost[x, y] + 1 < cost[x + 1, y] && !closed[x + 1, y]) { //right * cost[x + 1, y] = cost[x, y] + 1f; * link[x + 1, y] = new Coord2(x, y); * } * * if (level.ValidPosition(new Coord2(x + 1, y)) && cost[x, y] + 1 < cost[x + 1, y] && !closed[x + 1, y]) { //right * cost[x + 1, y] = cost[x, y] + 1f; * link[x + 1, y] = new Coord2(x, y); * } * * if (level.ValidPosition(new Coord2(x + 1, y + 1)) && cost[x, y] + 1.4 < cost[x + 1, y + 1] && !closed[x + 1, y + 1]) { //top right * cost[x + 1, y + 1] = cost[x, y] + 1.4f; * link[x + 1, y + 1] = new Coord2(x, y); * } * if (level.ValidPosition(new Coord2(x, y + 1)) && cost[x, y] + 1 < cost[x, y + 1] && !closed[x, y + 1]) { //top * cost[x, y + 1] = cost[x, y] + 1f; * link[x, y + 1] = new Coord2(x, y); * } * * if (level.ValidPosition(new Coord2(x - 1, y + 1)) && cost[x, y] + 1.4 < cost[x - 1, y + 1] && !closed[x - 1, y + 1]) { //top left * cost[x - 1, y + 1] = cost[x, y] + 1.4f; * link[x - 1, y + 1] = new Coord2(x, y); * } * if (level.ValidPosition(new Coord2(x - 1, y)) && cost[x, y] + 1 < cost[x - 1, y] && !closed[x - 1, y]) { //left * cost[x - 1, y] = cost[x, y] + 1f; * link[x - 1, y] = new Coord2(x, y); * } * if (level.ValidPosition(new Coord2(x - 1, y - 1)) && cost[x, y] + 1.4 < cost[x - 1, y - 1] && !closed[x - 1, y - 1]) { //bot left * cost[x - 1, y - 1] = cost[x, y] + 1.4f; * link[x - 1, y - 1] = new Coord2(x, y); * } * if (level.ValidPosition(new Coord2(x, y - 1)) && cost[x, y] + 1 < cost[x, y - 1] && !closed[x, y - 1]) { //bot * cost[x, y - 1] = cost[x, y] + 1f; * link[x, y - 1] = new Coord2(x, y); * } * if (level.ValidPosition(new Coord2(x + 1, y - 1)) && cost[x, y] + 1.4 < cost[x + 1, y - 1] && !closed[x + 1, y - 1]) { //bot right * cost[x + 1, y - 1] = cost[x, y] + 1.4f; * link[x + 1, y - 1] = new Coord2(x, y); * } */ Debug.WriteLine(x + "," + y); } bool done = false; //sets to true when player's location is found Coord2 nextClosed = plr.GridPosition; //start path while (!done) { inPath[nextClosed.X, nextClosed.Y] = true; nextClosed = link[nextClosed.X, nextClosed.Y]; if (nextClosed == bot.GridPosition) { done = true; } } }
protected override void Update(GameTime gameTime) { // Allows the game to exit //if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) // this.Exit(); //player movement: read keyboard KeyboardState keyState = Keyboard.GetState(); Coord2 currentPos = new Coord2(); currentPos = player.GridPosition; if (keyState.IsKeyDown(Keys.Up)) { currentPos.Y -= 1; player.SetNextLocation(currentPos, level); if ((hasAStar == true) && (liveUpdate == true)) { level.aStar.Build(level, bot, player); } if ((hasDijkstra == true) && (liveUpdate == true)) { level.dijkstra.Build(level, bot, player); } } else if (keyState.IsKeyDown(Keys.Down)) { currentPos.Y += 1; player.SetNextLocation(currentPos, level); if ((hasAStar == true) && (liveUpdate == true)) { level.aStar.Build(level, bot, player); } if ((hasDijkstra == true) && (liveUpdate == true)) { level.dijkstra.Build(level, bot, player); } } else if (keyState.IsKeyDown(Keys.Left)) { currentPos.X -= 1; player.SetNextLocation(currentPos, level); if ((hasAStar == true) && (liveUpdate == true)) { level.aStar.Build(level, bot, player); } if ((hasDijkstra == true) && (liveUpdate == true)) { level.dijkstra.Build(level, bot, player); } } else if (keyState.IsKeyDown(Keys.Right)) { currentPos.X += 1; player.SetNextLocation(currentPos, level); if ((hasAStar == true) && (liveUpdate == true)) { level.aStar.Build(level, bot, player); } if ((hasDijkstra == true) && (liveUpdate == true)) { level.dijkstra.Build(level, bot, player); } } //toggle liveUpdate else if ((keyState.IsKeyDown(Keys.L)) && (liveUpdate == false)) { liveUpdate = true; } else if ((keyState.IsKeyDown(Keys.L)) && (liveUpdate == true)) { liveUpdate = false; } //use dijkstra else if (keyState.IsKeyDown(Keys.D)) { bot = new AiBotStatic(10, 20); level.dijkstra.Build(level, bot, player); hasScentMap = false; hasDijkstra = true; hasAStar = false; } //use AStar else if (keyState.IsKeyDown(Keys.A)) { bot = new AiBotStatic(10, 20); level.aStar.Build(level, bot, player); hasScentMap = false; hasAStar = true; hasDijkstra = false; } //Use Scent Map else if (keyState.IsKeyDown(Keys.S)) { bot = new AiBotStatic(10, 20); level.scentMap.Update(level, player, bot); hasScentMap = true; hasDijkstra = false; hasAStar = false; } //Reset else if (keyState.IsKeyDown(Keys.F)) { bot = new AiBotStatic(10, 20); hasScentMap = false; hasDijkstra = false; hasAStar = false; } //Exit else if (keyState.IsKeyDown(Keys.Escape)) { Exit(); } //update bot and player bot.Update(gameTime, level, player); player.Update(gameTime, level); //Update Scent Map level.scentMap.Update(level, player, bot); base.Update(gameTime); }
// 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]; } }
public void Build(Level level, AiBotBase bot, Player plr) { for (int i = 0; i < 40; i++) { for (int x = 0; x < 40; x++) { closed[i, x] = false; cost[i, x] = 1000000; link[i, x] = new Coord2(-1, -1); inPath[i, x] = false; } } cost[bot.GridPosition.X, bot.GridPosition.Y] = 0; while (!closed[plr.GridPosition.X, plr.GridPosition.Y]) { //finding the lowest cost square float min = 1000000; Coord2 pos = new Coord2(0, 0); for (int x = 0; x < 40; x++) { for (int y = 0; y < 40; y++) { if (cost[x, y] < min && !closed[x, y]) { min = cost[x, y]; pos.X = x; pos.Y = y; } } } closed[pos.X, pos.Y] = true; //right if (level.ValidPosition(new Coord2(pos.X, pos.Y + 1)) && (cost[pos.X, pos.Y + 1] > cost[pos.X, pos.Y] + 1)) { cost[pos.X, pos.Y + 1] = cost[pos.X, pos.Y] + 1; link[pos.X, pos.Y + 1] = pos; } //left if (level.ValidPosition(new Coord2(pos.X, pos.Y - 1)) && (cost[pos.X, pos.Y - 1] > cost[pos.X, pos.Y] + 1)) { cost[pos.X, pos.Y - 1] = cost[pos.X, pos.Y] + 1; link[pos.X, pos.Y - 1] = pos; } //top if (level.ValidPosition(new Coord2(pos.X - 1, pos.Y)) && (cost[pos.X - 1, pos.Y] > cost[pos.X, pos.Y] + 1)) { cost[pos.X - 1, pos.Y] = cost[pos.X, pos.Y] + 1; link[pos.X - 1, pos.Y] = pos; } //bot if (level.ValidPosition(new Coord2(pos.X + 1, pos.Y)) && (cost[pos.X + 1, pos.Y] > cost[pos.X, pos.Y] + 1)) { cost[pos.X + 1, pos.Y] = cost[pos.X, pos.Y] + 1; link[pos.X + 1, pos.Y] = pos; } //top-left if (level.ValidPosition(new Coord2(pos.X - 1, pos.Y - 1)) && (cost[pos.X - 1, pos.Y - 1] > cost[pos.X, pos.Y] + 1.4f)) { cost[pos.X - 1, pos.Y - 1] = cost[pos.X, pos.Y] + 1.4f; link[pos.X - 1, pos.Y - 1] = pos; } //top-right if (level.ValidPosition(new Coord2(pos.X - 1, pos.Y + 1)) && (cost[pos.X - 1, pos.Y + 1] > cost[pos.X, pos.Y] + 1.4f)) { cost[pos.X - 1, pos.Y + 1] = cost[pos.X, pos.Y] + 1.4f; link[pos.X - 1, pos.Y + 1] = pos; } //bot-left if (level.ValidPosition(new Coord2(pos.X + 1, pos.Y - 1)) && (cost[pos.X + 1, pos.Y - 1] > cost[pos.X, pos.Y] + 1.4f)) { cost[pos.X + 1, pos.Y - 1] = cost[pos.X, pos.Y] + 1.4f; link[pos.X + 1, pos.Y - 1] = pos; } //bot-right if (level.ValidPosition(new Coord2(pos.X + 1, pos.Y + 1)) && (cost[pos.X + 1, pos.Y + 1] > cost[pos.X, pos.Y] + 1.4f)) { cost[pos.X + 1, pos.Y + 1] = cost[pos.X, pos.Y] + 1.4f; link[pos.X + 1, pos.Y + 1] = pos; } } bool done = false; //set to true when we are back at the bot position Coord2 nextClosed = plr.GridPosition; //start of path while (!done) { inPath[nextClosed.X, nextClosed.Y] = true; nextClosed = link[nextClosed.X, nextClosed.Y]; if (nextClosed == bot.GridPosition) { done = true; } } }
private void SetBotType(PathfinderAlgorithm algorithm) { if (algorithm == PathfinderAlgorithm.Dijkstra || algorithm == PathfinderAlgorithm.AStar) bot = new AiBotDijkstra(bot.Texture, bot.GridPosition.X, bot.GridPosition.Y); else if (algorithm == PathfinderAlgorithm.ScentMap) bot = new AiBotScent(bot.Texture, bot.GridPosition.X, bot.GridPosition.Y); else Console.WriteLine("Could not set bot type, unrecognized algorithm."); }