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); } }
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) { Coord2 desiredPos; Coord2 currentPos; //bool ok = false; currentPos = GridPosition; desiredPos = GridPosition; do { if (plr.GridPosition.X > GridPosition.X) { desiredPos.X += 1; } else if (plr.GridPosition.X < GridPosition.X) { desiredPos.X -= 1; } else if (plr.GridPosition.Y > GridPosition.Y) { desiredPos.Y += 1; } else if (plr.GridPosition.Y < GridPosition.Y) { desiredPos.Y -= 1; } } while (level.ValidPosition(desiredPos)); }
//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); }
//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 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(); } } }
public void SetPosition(Coord2 newPos, Level level) { if (level.ValidPosition(newPos)) { gridPosition = newPos; targetPosition = newPos; screenPosition = newPos; } }
protected override void ChooseNextGridLocation(Level level, Player plr) { bool moved = false; Coord2 newPos = GridPosition; if (GridPosition.X > plr.GridPosition.X) { newPos.X -= 1; if (level.ValidPosition(newPos) == false) { newPos.X += 1; newPos.Y -= 1; } } else if (GridPosition.X < plr.GridPosition.X) { newPos.X += 1; if (level.ValidPosition(newPos) == false) { newPos.X -= 1; newPos.Y += 1; } } else if (GridPosition.Y > plr.GridPosition.Y) { newPos.Y -= 1; if (level.ValidPosition(newPos) == false) { newPos.X -= 1; newPos.Y += 1; } } else if (GridPosition.Y < plr.GridPosition.Y) { newPos.Y += 1; if (level.ValidPosition(newPos) == false) { newPos.X += 1; newPos.Y -= 1; } } moved = SetNextGridPosition(newPos, level); }
//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; }
//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; } }
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. }
protected override void ChooseNextGridLocation(Level level, Player plr) { Coord2 pos; pos = GridPosition; if (level.ValidPosition(SetNextPos(movementDir, pos))) { SetNextGridPosition(SetNextPos(movementDir, pos), level); } else { } }
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; } } } } } }
// 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; }
// 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); }
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); }
//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 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; } } }
// 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); } }
//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; }
// 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(); }
// 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 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; } } }
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; } } }
protected override void ChooseNextGridLocation(Level level, Player plr) { Coord2 newPos; Coord2 halfPos; newPos = GridPosition; halfPos = GridPosition; if (plr.GridPosition.X > GridPosition.X) { halfPos.X += 1; if (level.ValidPosition(halfPos) && canMoveRight == true) { newPos.X += 1; } else { halfPos.X -= 1; halfPos.Y -= 1; canMoveRight = false; if (level.ValidPosition(halfPos)) { newPos.Y -= 1; } else { newPos.X -= 1; halfPos.X += 2; if ((level.ValidPosition(halfPos)) && (!level.ValidPosition(newPos))) { canMoveRight = true; } } } } else { if (plr.GridPosition.X < GridPosition.X) { halfPos.X -= 1; if (level.ValidPosition(halfPos)) { //newPos = halfPos; } else { //newPos.Y += 1; } } else { if (plr.GridPosition.Y > GridPosition.Y) { halfPos.Y += 1; if (level.ValidPosition(halfPos)) { newPos = halfPos; } else { // newPos.Y -= 1; } } else { if (plr.GridPosition.Y < GridPosition.Y) { halfPos.Y -= 1; if (level.ValidPosition(halfPos)) { newPos = halfPos; } else { // newPos.Y += 1; } } } } } SetNextGridPosition(newPos, level); }
// 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, 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]; } }
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); }
//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; } } }