public dynamic Pathfinder(Vector2 destination, Vector2 current, Random rng, bool isZombie) { Point start = ToGridPosition(destination, new Point(tiles[0, 0].Box.Width, tiles[0, 0].Box.Height)); Point finish = ToGridPosition(current, new Point(tiles[0, 0].Box.Width, tiles[0, 0].Box.Height)); //initialise grid with coordinates and counter WTuple <Vector2, TileStates, int>[,] grid = new WTuple <Vector2, TileStates, int> [dimensions.X, dimensions.Y]; for (int x = 0; x < dimensions.X; x++) { for (int y = 0; y < dimensions.Y; y++) { grid[x, y] = new WTuple <Vector2, TileStates, int>(tiles[x, y].Position, tiles[x, y].State, 9999); } } start = new Point(MathHelper.Clamp(start.X, 0, 25), MathHelper.Clamp(start.Y, 0, 25)); List <Point> done = new List <Point>(); List <Point> check = new List <Point>(); //if (this.GetTile(start).State == TileStates.Blocked) //return false; if (this.GetTile(finish).State == TileStates.Blocked) { return(false); } check.Add(start); int counter = 0; grid[check[0].X, check[0].Y].Item3 = counter; counter++; SortedSet <WTuple <Vector2, Point, int> > toCheck = new SortedSet <WTuple <Vector2, Point, int> >(new Extensions.ByScore()); while (check.Count > 0) { //check all around the tile and assign a counter Vector2 max = new Vector2(check[0].X + 1, check[0].Y + 1); Vector2 min = new Vector2(check[0].X - 1, check[0].Y - 1); if (check[0].X + 1 >= dimensions.X) { max.X = dimensions.X - 1; } if (check[0].Y + 1 >= dimensions.Y) { max.Y = dimensions.Y - 1; } if (check[0].X - 1 < 0) { min.X = 0; } if (check[0].Y - 1 < 0) { min.Y = 0; } for (int x = (int)min.X; x <= max.X; x++) { for (int y = (int)min.Y; y <= max.Y; y++) { int i = done.FindIndex(f => f.X == x && f.Y == y); if ((x == check[0].X && y == check[0].Y) || i > -1 || grid[x, y].Item3 != 9999) { //Console.WriteLine(done.Count()); } else { if (tiles[x, y].State == TileStates.Blocked || tiles[x, y].State == TileStates.Immpassable) { grid[x, y].Item2 = tiles[x, y].State; } else if (tiles[x, y].State == TileStates.Active || tiles[x, y].State == TileStates.Limbo) { grid[x, y].Item2 = TileStates.Active; float distance = Vector2.Distance(grid[x, y].Item1, grid[finish.X, finish.Y].Item1); float score = distance + 1; grid[x, y].Item3 = grid[check[0].X, check[0].Y].Item3 + 1; toCheck.Add(new WTuple <Vector2, Point, int>(grid[x, y].Item1, new Point(x, y), (int)score)); } } } } if (toCheck.Count > 0) { var v = toCheck.ElementAt(0); check.Add(v.Item2); toCheck.RemoveWhere(x => x.Item2 == v.Item2); } done.Add(check[0]); if (check[0] == finish) { check.Clear(); return(CalculateWayPoints(grid, rng, isZombie, current)); } else { check.RemoveAt(0); } //counter++; } done.Clear(); return(TileStates.Blocked); }
protected List <Vector2> CalculateWayPoints(object grid, Random rng, bool isZombie, Vector2 pos) { WTuple <Vector2, TileStates, int>[,] _grid = ((WTuple <Vector2, TileStates, int> [, ])grid); List <Vector2> points = new List <Vector2>(); //find start point Point start = Grid.ToGridPosition(pos, Grid.GetTileSize); Point current = start; //find finish Point finish = new Point(); for (int x = 0; x < _grid.GetLength(0); x++) { for (int y = 0; y < _grid.GetLength(1); y++) { if (_grid[x, y].Item3 == 0) { finish = new Point(x, y); break; } } } while (current != finish) { Vector2 next = new Vector2(); bool found = false; //check all around the tile and assign a counter Vector2 max = new Vector2(current.X + 1, current.Y + 1); Vector2 min = new Vector2(current.X - 1, current.Y - 1); int maxx = _grid.GetLength(0); int maxy = _grid.GetLength(1); if (current.X + 1 >= maxx) { max.X = maxx - 1; } if (current.Y + 1 >= maxy) { max.Y = maxy - 1; } if (current.X - 1 < 0) { min.X = 0; } if (current.Y - 1 < 0) { min.Y = 0; } int trueMaxX = MathHelper.Clamp(current.X + 1, current.X, maxx); int trueMaxY = MathHelper.Clamp(current.Y + 1, current.Y, maxy); List <Vector2> lfound = new List <Vector2>(); List <Point> pfound = new List <Point>(); for (int x = (int)min.X; x <= max.X; x++) { for (int y = (int)min.Y; y <= max.Y; y++) { if (x != current.X || y != current.Y) { if (_grid[x, y].Item3 < _grid[current.X, current.Y].Item3) { next = new Vector2(_grid[x, y].Item1.X + (size.X / 2), _grid[x, y].Item1.Y + (size.Y / 2)); pfound.Add(new Point(x, y)); lfound.Add(next); } } } } var rnd = rng.Next(0, lfound.Count); if (lfound.Count > 0) { if (isZombie) { points.Add(lfound[0]); } else { points.Add(lfound[rnd]); } current = pfound[rnd]; } } return(points); }