mirror of
https://github.com/Ellpeck/MLEM.git
synced 2024-11-22 12:58:33 +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>
|
<PackageProjectUrl>https://github.com/Ellpeck/MLEM</PackageProjectUrl>
|
||||||
<RepositoryUrl>https://github.com/Ellpeck/MLEM</RepositoryUrl>
|
<RepositoryUrl>https://github.com/Ellpeck/MLEM</RepositoryUrl>
|
||||||
<PackageLicenseUrl>https://github.com/Ellpeck/MLEM/blob/master/LICENSE</PackageLicenseUrl>
|
<PackageLicenseUrl>https://github.com/Ellpeck/MLEM/blob/master/LICENSE</PackageLicenseUrl>
|
||||||
<Version>1.0.1</Version>
|
<Version>1.0.2</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="MonoGame.Extended" Version="3.6.0-beta0001" PrivateAssets="All" />
|
<PackageReference Include="MonoGame.Extended" Version="3.6.0-beta0001">
|
||||||
<PackageReference Include="MonoGame.Framework.Portable" Version="3.7.0.1708" PrivateAssets="All" />
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="MonoGame.Framework.Portable" Version="3.7.0.1708">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
</PackageReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -10,10 +10,12 @@
|
||||||
<PackageProjectUrl>https://github.com/Ellpeck/MLEM</PackageProjectUrl>
|
<PackageProjectUrl>https://github.com/Ellpeck/MLEM</PackageProjectUrl>
|
||||||
<RepositoryUrl>https://github.com/Ellpeck/MLEM</RepositoryUrl>
|
<RepositoryUrl>https://github.com/Ellpeck/MLEM</RepositoryUrl>
|
||||||
<PackageLicenseUrl>https://github.com/Ellpeck/MLEM/blob/master/LICENSE</PackageLicenseUrl>
|
<PackageLicenseUrl>https://github.com/Ellpeck/MLEM/blob/master/LICENSE</PackageLicenseUrl>
|
||||||
<Version>1.0.4</Version>
|
<Version>1.0.5</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<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>
|
</ItemGroup>
|
||||||
</Project>
|
</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