@ -0,0 +1,176 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
namespace GWConquest | |||
{ | |||
public class PathfindingGraph<T> where T : class | |||
{ | |||
public class Node | |||
{ | |||
public T zone; | |||
public List<Connection> connections = new List<Connection>(); | |||
} | |||
public class Connection | |||
{ | |||
public Node target; | |||
public float length; | |||
} | |||
public class Path | |||
{ | |||
public List<T> zones; | |||
public float totalDistance; | |||
public override string ToString() | |||
{ | |||
if(zones.Count == 0) | |||
{ | |||
return "Empty Path"; | |||
} | |||
else | |||
{ | |||
string str = zones[0].ToString(); | |||
for(int i = 1; i < zones.Count; i++) | |||
{ | |||
str = str + " -> " + zones[i].ToString(); | |||
} | |||
str += " (Distance: " + totalDistance + ")"; | |||
return str; | |||
} | |||
} | |||
} | |||
private Dictionary<T, Node> nodeMap = new Dictionary<T, Node>(); | |||
public PathfindingGraph(IEnumerable<T> zones) | |||
{ | |||
foreach(T zone in zones) | |||
{ | |||
Node n = new Node { zone = zone }; | |||
nodeMap.Add(zone, n); | |||
} | |||
} | |||
public void AddConnection(T zone1, T zone2, float length) | |||
{ | |||
nodeMap[zone1].connections.Add(new Connection | |||
{ | |||
target = nodeMap[zone2], | |||
length = length | |||
}); | |||
nodeMap[zone2].connections.Add(new Connection | |||
{ | |||
target = nodeMap[zone1], | |||
length = length | |||
}); | |||
} | |||
private class DjikstraResult | |||
{ | |||
public Dictionary<Node, float> distances; | |||
public Dictionary<Node, Node> previous; | |||
} | |||
private DjikstraResult Djikstra(IMovable<T> movable, Node startNode, Node endNode = null) | |||
{ | |||
//Initialisation | |||
Dictionary<Node, float> distances = new Dictionary<Node, float>(); | |||
Dictionary<Node, Node> previous = new Dictionary<Node, Node>(); | |||
foreach(Node n in nodeMap.Values) | |||
{ | |||
distances[n] = float.MaxValue; | |||
previous[n] = null; | |||
} | |||
distances[startNode] = 0f; | |||
List<Node> Q = new List<Node>(nodeMap.Values); | |||
//Loop | |||
while(Q.Count > 0) | |||
{ | |||
Node u = Q.ArgMin(n => distances[n]); | |||
Q.Remove(u); | |||
//Break condition | |||
if(endNode != null && endNode == u) | |||
{ | |||
break; | |||
} | |||
foreach(Connection c in u.connections) | |||
{ | |||
Node v = c.target; | |||
if(Q.Contains(v) && movable.CanMoveTo(u.zone,v.zone)) | |||
{ | |||
//Distance update | |||
float distanceBetween = c.length * movable.GetModifierForTransition(u.zone, v.zone); | |||
float alternate = distances[u] + distanceBetween; | |||
if(alternate < distances[v]) | |||
{ | |||
distances[v] = alternate; | |||
previous[v] = u; | |||
} | |||
} | |||
} | |||
} | |||
return new DjikstraResult { previous = previous, distances = distances }; | |||
} | |||
private Path GetPathFromResult(DjikstraResult result, Node node) | |||
{ | |||
List<T> list = new List<T>(); | |||
Node u = node; | |||
while(u != null) | |||
{ | |||
list.Insert(0, u.zone); | |||
u = result.previous[u]; | |||
} | |||
return new Path { zones = list, totalDistance = result.distances[node] }; | |||
} | |||
public Path FindShortestPath(IMovable<T> movable, T startZone, T endZone) | |||
{ | |||
Node startNode = nodeMap[startZone]; | |||
Node endNode = nodeMap[endZone]; | |||
var result = Djikstra(movable, startNode, endNode); | |||
if(result.distances[endNode] < float.MaxValue) | |||
{ | |||
return GetPathFromResult(result, endNode); | |||
} | |||
else | |||
{ | |||
return null; | |||
} | |||
} | |||
public Dictionary<T, Path> FindAllPaths(IMovable<T> movable, T startZone) | |||
{ | |||
Node startNode = nodeMap[startZone]; | |||
var result = Djikstra(movable, startNode); | |||
var dict = new Dictionary<T, Path>(); | |||
foreach(Node n in nodeMap.Values) | |||
{ | |||
if(n != startNode && result.distances[n] < float.MaxValue) | |||
{ | |||
dict.Add(n.zone, GetPathFromResult(result, n)); | |||
} | |||
} | |||
return dict; | |||
} | |||
} | |||
public interface IMovable<T> | |||
{ | |||
float GetModifierForTransition(T origin, T target); | |||
bool CanMoveTo(T origin, T target); | |||
} | |||
} |
@ -0,0 +1,11 @@ | |||
fileFormatVersion: 2 | |||
guid: a50f4e196eb757c458679394dd1cc5b9 | |||
MonoImporter: | |||
externalObjects: {} | |||
serializedVersion: 2 | |||
defaultReferences: [] | |||
executionOrder: 0 | |||
icon: {instanceID: 0} | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,324 @@ | |||
{ | |||
"dependencies": { | |||
"com.unity.2d.common": { | |||
"version": "2.0.2", | |||
"depth": 0, | |||
"source": "registry", | |||
"dependencies": { | |||
"com.unity.2d.sprite": "1.0.0" | |||
}, | |||
"url": "https://packages.unity.com" | |||
}, | |||
"com.unity.2d.sprite": { | |||
"version": "1.0.0", | |||
"depth": 0, | |||
"source": "builtin", | |||
"dependencies": {} | |||
}, | |||
"com.unity.collab-proxy": { | |||
"version": "1.2.16", | |||
"depth": 0, | |||
"source": "registry", | |||
"dependencies": {}, | |||
"url": "https://packages.unity.com" | |||
}, | |||
"com.unity.ext.nunit": { | |||
"version": "1.0.0", | |||
"depth": 1, | |||
"source": "registry", | |||
"dependencies": {}, | |||
"url": "https://packages.unity.com" | |||
}, | |||
"com.unity.ide.rider": { | |||
"version": "1.1.4", | |||
"depth": 0, | |||
"source": "registry", | |||
"dependencies": { | |||
"com.unity.test-framework": "1.1.1" | |||
}, | |||
"url": "https://packages.unity.com" | |||
}, | |||
"com.unity.ide.vscode": { | |||
"version": "1.2.1", | |||
"depth": 0, | |||
"source": "registry", | |||
"dependencies": {}, | |||
"url": "https://packages.unity.com" | |||
}, | |||
"com.unity.postprocessing": { | |||
"version": "2.3.0", | |||
"depth": 0, | |||
"source": "registry", | |||
"dependencies": {}, | |||
"url": "https://packages.unity.com" | |||
}, | |||
"com.unity.test-framework": { | |||
"version": "1.1.14", | |||
"depth": 0, | |||
"source": "registry", | |||
"dependencies": { | |||
"com.unity.ext.nunit": "1.0.0", | |||
"com.unity.modules.imgui": "1.0.0", | |||
"com.unity.modules.jsonserialize": "1.0.0" | |||
}, | |||
"url": "https://packages.unity.com" | |||
}, | |||
"com.unity.timeline": { | |||
"version": "1.2.10", | |||
"depth": 0, | |||
"source": "registry", | |||
"dependencies": {}, | |||
"url": "https://packages.unity.com" | |||
}, | |||
"com.unity.ugui": { | |||
"version": "1.0.0", | |||
"depth": 0, | |||
"source": "builtin", | |||
"dependencies": { | |||
"com.unity.modules.ui": "1.0.0" | |||
} | |||
}, | |||
"com.unity.modules.ai": { | |||
"version": "1.0.0", | |||
"depth": 0, | |||
"source": "builtin", | |||
"dependencies": {} | |||
}, | |||
"com.unity.modules.androidjni": { | |||
"version": "1.0.0", | |||
"depth": 0, | |||
"source": "builtin", | |||
"dependencies": {} | |||
}, | |||
"com.unity.modules.animation": { | |||
"version": "1.0.0", | |||
"depth": 0, | |||
"source": "builtin", | |||
"dependencies": {} | |||
}, | |||
"com.unity.modules.assetbundle": { | |||
"version": "1.0.0", | |||
"depth": 0, | |||
"source": "builtin", | |||
"dependencies": {} | |||
}, | |||
"com.unity.modules.audio": { | |||
"version": "1.0.0", | |||
"depth": 0, | |||
"source": "builtin", | |||
"dependencies": {} | |||
}, | |||
"com.unity.modules.cloth": { | |||
"version": "1.0.0", | |||
"depth": 0, | |||
"source": "builtin", | |||
"dependencies": { | |||
"com.unity.modules.physics": "1.0.0" | |||
} | |||
}, | |||
"com.unity.modules.director": { | |||
"version": "1.0.0", | |||
"depth": 0, | |||
"source": "builtin", | |||
"dependencies": { | |||
"com.unity.modules.audio": "1.0.0", | |||
"com.unity.modules.animation": "1.0.0" | |||
} | |||
}, | |||
"com.unity.modules.imageconversion": { | |||
"version": "1.0.0", | |||
"depth": 0, | |||
"source": "builtin", | |||
"dependencies": {} | |||
}, | |||
"com.unity.modules.imgui": { | |||
"version": "1.0.0", | |||
"depth": 0, | |||
"source": "builtin", | |||
"dependencies": {} | |||
}, | |||
"com.unity.modules.jsonserialize": { | |||
"version": "1.0.0", | |||
"depth": 0, | |||
"source": "builtin", | |||
"dependencies": {} | |||
}, | |||
"com.unity.modules.particlesystem": { | |||
"version": "1.0.0", | |||
"depth": 0, | |||
"source": "builtin", | |||
"dependencies": {} | |||
}, | |||
"com.unity.modules.physics": { | |||
"version": "1.0.0", | |||
"depth": 0, | |||
"source": "builtin", | |||
"dependencies": {} | |||
}, | |||
"com.unity.modules.physics2d": { | |||
"version": "1.0.0", | |||
"depth": 0, | |||
"source": "builtin", | |||
"dependencies": {} | |||
}, | |||
"com.unity.modules.screencapture": { | |||
"version": "1.0.0", | |||
"depth": 0, | |||
"source": "builtin", | |||
"dependencies": { | |||
"com.unity.modules.imageconversion": "1.0.0" | |||
} | |||
}, | |||
"com.unity.modules.subsystems": { | |||
"version": "1.0.0", | |||
"depth": 1, | |||
"source": "builtin", | |||
"dependencies": { | |||
"com.unity.modules.jsonserialize": "1.0.0" | |||
} | |||
}, | |||
"com.unity.modules.terrain": { | |||
"version": "1.0.0", | |||
"depth": 0, | |||
"source": "builtin", | |||
"dependencies": {} | |||
}, | |||
"com.unity.modules.terrainphysics": { | |||
"version": "1.0.0", | |||
"depth": 0, | |||
"source": "builtin", | |||
"dependencies": { | |||
"com.unity.modules.physics": "1.0.0", | |||
"com.unity.modules.terrain": "1.0.0" | |||
} | |||
}, | |||
"com.unity.modules.tilemap": { | |||
"version": "1.0.0", | |||
"depth": 0, | |||
"source": "builtin", | |||
"dependencies": { | |||
"com.unity.modules.physics2d": "1.0.0" | |||
} | |||
}, | |||
"com.unity.modules.ui": { | |||
"version": "1.0.0", | |||
"depth": 0, | |||
"source": "builtin", | |||
"dependencies": {} | |||
}, | |||
"com.unity.modules.uielements": { | |||
"version": "1.0.0", | |||
"depth": 0, | |||
"source": "builtin", | |||
"dependencies": { | |||
"com.unity.modules.imgui": "1.0.0", | |||
"com.unity.modules.jsonserialize": "1.0.0" | |||
} | |||
}, | |||
"com.unity.modules.umbra": { | |||
"version": "1.0.0", | |||
"depth": 0, | |||
"source": "builtin", | |||
"dependencies": {} | |||
}, | |||
"com.unity.modules.unityanalytics": { | |||
"version": "1.0.0", | |||
"depth": 0, | |||
"source": "builtin", | |||
"dependencies": { | |||
"com.unity.modules.unitywebrequest": "1.0.0", | |||
"com.unity.modules.jsonserialize": "1.0.0" | |||
} | |||
}, | |||
"com.unity.modules.unitywebrequest": { | |||
"version": "1.0.0", | |||
"depth": 0, | |||
"source": "builtin", | |||
"dependencies": {} | |||
}, | |||
"com.unity.modules.unitywebrequestassetbundle": { | |||
"version": "1.0.0", | |||
"depth": 0, | |||
"source": "builtin", | |||
"dependencies": { | |||
"com.unity.modules.assetbundle": "1.0.0", | |||
"com.unity.modules.unitywebrequest": "1.0.0" | |||
} | |||
}, | |||
"com.unity.modules.unitywebrequestaudio": { | |||
"version": "1.0.0", | |||
"depth": 0, | |||
"source": "builtin", | |||
"dependencies": { | |||
"com.unity.modules.unitywebrequest": "1.0.0", | |||
"com.unity.modules.audio": "1.0.0" | |||
} | |||
}, | |||
"com.unity.modules.unitywebrequesttexture": { | |||
"version": "1.0.0", | |||
"depth": 0, | |||
"source": "builtin", | |||
"dependencies": { | |||
"com.unity.modules.unitywebrequest": "1.0.0", | |||
"com.unity.modules.imageconversion": "1.0.0" | |||
} | |||
}, | |||
"com.unity.modules.unitywebrequestwww": { | |||
"version": "1.0.0", | |||
"depth": 0, | |||
"source": "builtin", | |||
"dependencies": { | |||
"com.unity.modules.unitywebrequest": "1.0.0", | |||
"com.unity.modules.unitywebrequestassetbundle": "1.0.0", | |||
"com.unity.modules.unitywebrequestaudio": "1.0.0", | |||
"com.unity.modules.audio": "1.0.0", | |||
"com.unity.modules.assetbundle": "1.0.0", | |||
"com.unity.modules.imageconversion": "1.0.0" | |||
} | |||
}, | |||
"com.unity.modules.vehicles": { | |||
"version": "1.0.0", | |||
"depth": 0, | |||
"source": "builtin", | |||
"dependencies": { | |||
"com.unity.modules.physics": "1.0.0" | |||
} | |||
}, | |||
"com.unity.modules.video": { | |||
"version": "1.0.0", | |||
"depth": 0, | |||
"source": "builtin", | |||
"dependencies": { | |||
"com.unity.modules.audio": "1.0.0", | |||
"com.unity.modules.ui": "1.0.0", | |||
"com.unity.modules.unitywebrequest": "1.0.0" | |||
} | |||
}, | |||
"com.unity.modules.vr": { | |||
"version": "1.0.0", | |||
"depth": 0, | |||
"source": "builtin", | |||
"dependencies": { | |||
"com.unity.modules.jsonserialize": "1.0.0", | |||
"com.unity.modules.physics": "1.0.0", | |||
"com.unity.modules.xr": "1.0.0" | |||
} | |||
}, | |||
"com.unity.modules.wind": { | |||
"version": "1.0.0", | |||
"depth": 0, | |||
"source": "builtin", | |||
"dependencies": {} | |||
}, | |||
"com.unity.modules.xr": { | |||
"version": "1.0.0", | |||
"depth": 0, | |||
"source": "builtin", | |||
"dependencies": { | |||
"com.unity.modules.physics": "1.0.0", | |||
"com.unity.modules.jsonserialize": "1.0.0", | |||
"com.unity.modules.subsystems": "1.0.0" | |||
} | |||
} | |||
} | |||
} |
@ -1,2 +1,2 @@ | |||
m_EditorVersion: 2019.3.14f1 | |||
m_EditorVersionWithRevision: 2019.3.14f1 (2b330bf6d2d8) | |||
m_EditorVersion: 2019.4.5f1 | |||
m_EditorVersionWithRevision: 2019.4.5f1 (81610f64359c) |