public List<Vector> FindPath(Vector s, Vector e, Entity o) { start = s; end = e; entity = o; int w = map.blocks.GetLength(0); int h = map.blocks.GetLength(1); gScore = new int[w, h]; hScore = new int[w, h]; fScore = new int[w, h]; cameFrom = new Vector[w, h]; List<Vector> open = new List<Vector>(); List<Vector> closed = new List<Vector>(); open.Add(start); gScore[start.x, start.y] = 0; hScore[start.x, start.y] = calculateHeuristic(start); fScore[start.x, start.y] = hScore[start.x, start.y]; while(open.Count > 0) { Vector point = getLowestPointIn(open); if(point == end) return reconstructPath(cameFrom[point.x, point.y]); open.Remove(point); closed.Add(point); List<Vector> neighbours = getNeighbourPoints(point); foreach(Vector p in neighbours) { if(closed.Contains(p)) continue; int gPossible = gScore[point.x, point.y] + distanceBetween(p, point); if(!open.Contains(p) || (open.Contains(p) && gPossible < gScore[p.x, p.y])) { if(!open.Contains(p)) open.Add(p); cameFrom[p.x, p.y] = point; gScore[p.x, p.y] = gPossible; hScore[p.x, p.y] = calculateHeuristic(p); fScore[p.x, p.y] = gPossible + hScore[p.x, p.y]; } } } return null; }
public bool canMoveTo(Vector to, Vector from, Entity e) { if(to.x < 0 || to.y < 0 || to.x > 20 || to.y > 20) return false; if(e != player && player.getMovingTo() == to) return false; foreach(Entity ai in ais) if(e != ai && ai.getMovingTo() == to) return false; foreach(Entity crate in crates) if(e != null && e.canPushCrates && crate.pos / 32 == to) { Vector diff = crate.pos / 32 - from; return canMoveTo(to + diff, crate.pos / 32, crate); } else if(e != crate && crate.getMovingTo() == to) return false; foreach(Entity n in noCrates) if(n.pos / 32 == to && crates.Contains(e)) return false; foreach(Entity s in safe) if(s.pos / 32 == to) return e == player; return !blocks[to.x, to.y]; }
public Trail(Vector p, Color c) { pos = p; color = c; }
public void loadTestLevel(char[,] map) { levelLoaded = false; isTest = true; isCustom = false; trails.Clear(); ais.Clear(); crates.Clear(); noCrates.Clear(); safe.Clear(); blocks = new bool[21, 21]; for(int i = 0; i < 21; i++) for(int j = 0; j < 21; j++) { blocks[i, j] = false; switch(map[i, j]) { case '#': blocks[i, j] = true; break; case 'S': player.pos = new Vector(32 * i, 32 * j); break; case 'E': end = new Vector(i, j); break; case 'A': Entity ai = new Entity(); ai.pos = new Vector(32 * i, 32 * j); ai.color = Color.Red; ai.canPushCrates = true; ais.Add(ai); break; case 'C': Entity crate = new Entity(); crate.pos = new Vector(32 * i, 32 * j); crate.color = Color.Blue; crates.Add(crate); break; case 'N': Entity noCrate = new Entity(); noCrate.pos = new Vector(32 * i, 32 * j); noCrate.color = Color.LightBlue; noCrates.Add(noCrate); break; case 'G': Entity s = new Entity(); s.pos = new Vector(32 * i, 32 * j); s.color = Color.LightGray; safe.Add(s); break; } } moving = false; levelLoaded = true; }
public void loadLevel(int n) { levelLoaded = false; level = n; isTest = false; isCustom = false; if(n >= mapstore.maps.GetLength(0) || n < 0) return; trails.Clear(); ais.Clear(); crates.Clear(); noCrates.Clear(); safe.Clear(); blocks = new bool[21, 21]; bool foundStart = false; bool foundEnd = false; for(int i = 0; i < 21; i++) for(int j = 0; j < 21; j++) { blocks[i, j] = false; switch(mapstore.maps[n, j][i]) { case '#': blocks[i, j] = true; break; case 'S': player.pos = new Vector(32 * i, 32 * j); foundStart = true; break; case 'E': end = new Vector(i, j); foundEnd = true; break; case 'A': Entity ai = new Entity(); ai.pos = new Vector(32 * i, 32 * j); ai.color = Color.Red; ai.canPushCrates = true; ais.Add(ai); break; case 'C': Entity crate = new Entity(); crate.pos = new Vector(32 * i, 32 * j); crate.color = Color.Blue; crates.Add(crate); break; case 'N': Entity noCrate = new Entity(); noCrate.pos = new Vector(32 * i, 32 * j); noCrate.color = Color.LightBlue; noCrates.Add(noCrate); break; case 'G': Entity s = new Entity(); s.pos = new Vector(32 * i, 32 * j); s.color = Color.LightGray; safe.Add(s); break; } } if(!foundStart || !foundEnd) { levelLoaded = false; Console.WriteLine("INVALID LEVEL MISSING A START OR END. OH GOD WHAT DO I DO"); return; } moving = false; levelLoaded = true; }
public void loadCustomLevel() { FileStream stream = File.Open("mapeditor.xml", FileMode.OpenOrCreate, FileAccess.Read); XmlSerializer serializer = new XmlSerializer(typeof(string[])); string[] map = (string[]) serializer.Deserialize(stream); levelLoaded = false; isTest = false; isCustom = true; trails.Clear(); ais.Clear(); crates.Clear(); noCrates.Clear(); safe.Clear(); blocks = new bool[21, 21]; for(int i = 0; i < 21; i++) for(int j = 0; j < 21; j++) { blocks[i, j] = false; if(map[j].Length == 0) continue; switch(map[j][i]) { case '#': blocks[i, j] = true; break; case 'S': player.pos = new Vector(32 * i, 32 * j); break; case 'E': end = new Vector(i, j); break; case 'A': Entity ai = new Entity(); ai.pos = new Vector(32 * i, 32 * j); ai.color = Color.Red; ai.canPushCrates = true; ais.Add(ai); break; case 'C': Entity crate = new Entity(); crate.pos = new Vector(32 * i, 32 * j); crate.color = Color.Blue; crates.Add(crate); break; case 'N': Entity noCrate = new Entity(); noCrate.pos = new Vector(32 * i, 32 * j); noCrate.color = Color.LightBlue; noCrates.Add(noCrate); break; case 'G': Entity s = new Entity(); s.pos = new Vector(32 * i, 32 * j); s.color = Color.LightGray; safe.Add(s); break; } } moving = false; levelLoaded = true; stream.Close(); }
private Vector getLowestPointIn(List<Vector> list) { int lowest = -1; Vector found = new Vector(-1, -1); foreach(Vector p in list) { Vector c = cameFrom[p.x, p.y]; int dist = c == new Vector(-1, -1) ? 0 : gScore[c.x, c.y] + distanceBetween(p, c) + calculateHeuristic(p); if(dist <= lowest || lowest == -1) { lowest = dist; found = p; } } return found; }
private int distanceBetween(Vector pos1, Vector pos2) { return (int) Math.Round(10 * Math.Sqrt(Math.Pow(pos1.x - pos2.x, 2) + Math.Pow(pos1.y - pos2.y, 2))); }
private int calculateHeuristic(Vector pos) { return 10 * (Math.Abs(pos.x - end.x) + Math.Abs(pos.y - end.y)); }
private List<Vector> reconstructPath(Vector p) { if(p != start) { List<Vector> path = reconstructPath(cameFrom[p.x, p.y]); path.Add(p); return path; } else return new List<Vector>(); }
private List<Vector> getNeighbourPoints(Vector p) { List<Vector> found = new List<Vector>(); if(canMoveTo(p.x + 1, p.y, p.x, p.y)) found.Add(new Vector(p.x + 1, p.y)); if(canMoveTo(p.x - 1, p.y, p.x, p.y)) found.Add(new Vector(p.x - 1, p.y)); if(canMoveTo(p.x, p.y + 1, p.x, p.y)) found.Add(new Vector(p.x, p.y + 1)); if(canMoveTo(p.x, p.y - 1, p.x, p.y)) found.Add(new Vector(p.x, p.y - 1)); return found; }