mirror of
https://github.com/Ellpeck/MLEM.git
synced 2024-12-24 01:09:23 +01:00
added pathfinding
This commit is contained in:
parent
1eeb536f09
commit
edb9b76f9d
3 changed files with 125 additions and 5 deletions
|
@ -10,11 +10,15 @@
|
|||
<PackageProjectUrl>https://github.com/Ellpeck/MLEM</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/Ellpeck/MLEM</RepositoryUrl>
|
||||
<PackageLicenseUrl>https://github.com/Ellpeck/MLEM/blob/master/LICENSE</PackageLicenseUrl>
|
||||
<Version>1.0.1</Version>
|
||||
<Version>1.0.2</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MonoGame.Extended" Version="3.6.0-beta0001" PrivateAssets="All" />
|
||||
<PackageReference Include="MonoGame.Framework.Portable" Version="3.7.0.1708" PrivateAssets="All" />
|
||||
<PackageReference Include="MonoGame.Extended" Version="3.6.0-beta0001">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="MonoGame.Framework.Portable" Version="3.7.0.1708">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -10,10 +10,12 @@
|
|||
<PackageProjectUrl>https://github.com/Ellpeck/MLEM</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/Ellpeck/MLEM</RepositoryUrl>
|
||||
<PackageLicenseUrl>https://github.com/Ellpeck/MLEM/blob/master/LICENSE</PackageLicenseUrl>
|
||||
<Version>1.0.4</Version>
|
||||
<Version>1.0.5</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MonoGame.Framework.Portable" Version="3.7.0.1708" PrivateAssets="All" />
|
||||
<PackageReference Include="MonoGame.Framework.Portable" Version="3.7.0.1708">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
</Project>
|
114
MLEM/Pathfinding/AStar.cs
Normal file
114
MLEM/Pathfinding/AStar.cs
Normal file
|
@ -0,0 +1,114 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace MLEM.Pathfinding {
|
||||
public static class AStar {
|
||||
|
||||
private static readonly Point[] AdjacentDirections = {
|
||||
new Point(1, 0),
|
||||
new Point(-1, 0),
|
||||
new Point(0, 1),
|
||||
new Point(0, -1)
|
||||
};
|
||||
|
||||
private static readonly Point[] AllDirections = AdjacentDirections.Concat(new[] {
|
||||
new Point(1, 1),
|
||||
new Point(-1, 1),
|
||||
new Point(1, -1),
|
||||
new Point(-1, -1)
|
||||
}).ToArray();
|
||||
|
||||
public static Stack<Point> FindPath(Point start, Point goal, int defaultCost, GetCost getCost, int maxTries = 10000, bool allowDiagonals = false) {
|
||||
var open = new List<PathPoint>();
|
||||
var closed = new List<PathPoint>();
|
||||
open.Add(new PathPoint(start, goal, null, 0, defaultCost));
|
||||
|
||||
var count = 0;
|
||||
while (open.Count > 0) {
|
||||
PathPoint current = null;
|
||||
var lowestF = int.MaxValue;
|
||||
foreach (var point in open)
|
||||
if (point.F < lowestF) {
|
||||
current = point;
|
||||
lowestF = point.F;
|
||||
}
|
||||
if (current == null)
|
||||
break;
|
||||
|
||||
open.Remove(current);
|
||||
closed.Add(current);
|
||||
|
||||
if (current.Pos.Equals(goal))
|
||||
return CompilePath(current);
|
||||
|
||||
var dirsUsed = allowDiagonals ? AllDirections : AdjacentDirections;
|
||||
foreach (var dir in dirsUsed) {
|
||||
var neighborPos = current.Pos + dir;
|
||||
var cost = getCost(neighborPos);
|
||||
if (cost < int.MaxValue) {
|
||||
var neighbor = new PathPoint(neighborPos, goal, current, cost, defaultCost);
|
||||
if (!closed.Contains(neighbor)) {
|
||||
var alreadyIndex = open.IndexOf(neighbor);
|
||||
if (alreadyIndex < 0) {
|
||||
open.Add(neighbor);
|
||||
} else {
|
||||
var alreadyNeighbor = open[alreadyIndex];
|
||||
if (neighbor.G < alreadyNeighbor.G) {
|
||||
open.Remove(alreadyNeighbor);
|
||||
open.Add(neighbor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
count++;
|
||||
if (count >= maxTries)
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Stack<Point> CompilePath(PathPoint current) {
|
||||
var path = new Stack<Point>();
|
||||
while (current != null) {
|
||||
path.Push(current.Pos);
|
||||
current = current.Parent;
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
public delegate int GetCost(Point pos);
|
||||
|
||||
}
|
||||
|
||||
public class PathPoint {
|
||||
|
||||
public readonly PathPoint Parent;
|
||||
public readonly Point Pos;
|
||||
public readonly int F;
|
||||
public readonly int G;
|
||||
|
||||
public PathPoint(Point pos, Point goal, PathPoint parent, int terrainCostForThisPos, int defaultCost) {
|
||||
this.Pos = pos;
|
||||
this.Parent = parent;
|
||||
|
||||
this.G = (parent == null ? 0 : parent.G) + terrainCostForThisPos;
|
||||
var manhattan = (Math.Abs(goal.X - pos.X) + Math.Abs(goal.Y - pos.Y)) * defaultCost;
|
||||
this.F = this.G + manhattan;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj) {
|
||||
if (obj == this)
|
||||
return true;
|
||||
return obj is PathPoint point && point.Pos.Equals(this.Pos);
|
||||
}
|
||||
|
||||
public override int GetHashCode() {
|
||||
return this.Pos.GetHashCode();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue