public Stack<Square> Start(int startX, int startY, int targetX, int targetY, Bot bot) { closedSquares = new Square[bot.room.Width, bot.room.Height]; openSquares = new Square[bot.room.Width, bot.room.Height]; openSquaresList = new List<Square>(); int h = CalculateH(startX, startY, targetX, targetY); Square start = new Square(startX, startY, 0, h, null); openSquares[startX, startY] = start; openSquaresList.Add(start); Square current = start; int maxCount = 1000; int currentCount = 0; while (openSquaresList.Count > 0) { //Find square with lowest F score in openlist current = openSquaresList.First(); foreach (Square s in openSquaresList) { if (s.G + s.H < current.G + current.H) { current = s; } } //Check if current square is target. if so, construct and return path if (current.x == targetX && current.y == targetY) { Stack<Square> temppath = ReconstructPath(new Stack<Square>(), current); Stack<Square> newpath = new Stack<Square>(); while (temppath.Count > 0) { Square s = temppath.Pop(); if (bot.room.getBlock(0, s.x, s.y).blockId == 4 || bot.room.getBlock(0, s.x, s.y).blockId == 32 ||bot.room.getBlock(0, s.x, s.y).blockId == 0) { newpath.Push(s); } else break; } newpath = new Stack<Square>(newpath); //Console.WriteLine(newpath.Count); //string str = ""; //foreach (Square s in newpath) // str += "X:" + s.x + " Y:" + s.y + " \n"; //Console.WriteLine(str); return newpath; } if (currentCount > maxCount) return null; //Switch current square from openlist to closedlist closedSquares[current.x, current.y] = current; openSquares[current.x, current.y] = null; for (int i = 0; i < openSquaresList.Count; i++) { Square temp = openSquaresList[i]; if (temp.x == current.x && temp.y == current.y) { openSquaresList.RemoveAt(i); break; } } //Check the neighbours of the current square for (int i = 0; i < 8; i++) { Square neighbour = new Square( current.x + adjacentSquares[i].x, current.y + adjacentSquares[i].y, current.G + adjacentSquares[i].cost, CalculateH(current.x + adjacentSquares[i].x, current.y + adjacentSquares[i].y, targetX, targetY), current); if (neighbour.x < 0 || neighbour.y < 0 || neighbour.x >= bot.room.Width || neighbour.y >= bot.room.Height) continue; if (bot.room.getBlock(0, neighbour.x, neighbour.y).blockId != 4) neighbour.G += 10000; //neighbour.G += bot.room.getBlock(0, neighbour.x, neighbour.y); int neighborInClosedF = 0; Square temp = closedSquares[neighbour.x, neighbour.y]; if (temp != null) neighborInClosedF = temp.G + temp.H; //If it's in closedsquares and its F is over the one in closedsquares, dont care about it if (closedSquares[neighbour.x, neighbour.y] != null && (neighbour.G + neighbour.H) >= neighborInClosedF) continue; //If it isn't in opensquares or its F is lower than the one in closedsquares, add it or swap them if ((openSquares[neighbour.x, neighbour.y] == null || ((neighbour.G + neighbour.H) < neighborInClosedF) && bot.room.getBlock(0, neighbour.x, neighbour.y).blockId == 4)) { neighbour.parent = current; openSquares[neighbour.x, neighbour.y] = neighbour; openSquaresList.Add(neighbour); currentCount++; } } } return null; }
public Square(int x, int y, int G, int H, Square parent) { this.x = x; this.y = y; this.G = H; this.H = H; this.parent = parent; }
public bool Equals(Square square) { return square.x == x && square.y == y; }
Stack<Square> ReconstructPath(Stack<Square> currentstack, Square current) { if (current.parent != null) { currentstack.Push(current.parent); currentstack = ReconstructPath(currentstack, current.parent); } else currentstack.Push(current); return currentstack; }