C# 如何根据g分数修正路径?
我构建了一个*引擎,用于在带有方形节点的网格中查找最佳路径。每个节点都有八个到其他节点的可能连接(上、下、左、右、左上、右上、左下、右下) 我无法根据节点的g分数更正路径。当我发现当前节点的连接节点(相邻节点)时,必须进行此更正,对于已经在开放列表中但不在封闭列表中或不可访问的每个相邻节点,我需要做一些事情来检查该节点是否更适合使用g-score进行决策的路径。问题是我不知道怎么做 我有一个简单的代码,用于查找相邻节点:C# 如何根据g分数修正路径?,c#,algorithm,artificial-intelligence,a-star,C#,Algorithm,Artificial Intelligence,A Star,我构建了一个*引擎,用于在带有方形节点的网格中查找最佳路径。每个节点都有八个到其他节点的可能连接(上、下、左、右、左上、右上、左下、右下) 我无法根据节点的g分数更正路径。当我发现当前节点的连接节点(相邻节点)时,必须进行此更正,对于已经在开放列表中但不在封闭列表中或不可访问的每个相邻节点,我需要做一些事情来检查该节点是否更适合使用g-score进行决策的路径。问题是我不知道怎么做 我有一个简单的代码,用于查找相邻节点: private ArrayList discoverChildren(No
private ArrayList discoverChildren(Node parent) {
ArrayList discoveredNodes = new ArrayList();
if (parent.upNode != null &&
parent.upNode.isWalkable &&
!closedList.Contains(parent.upNode)) {
if (!openList.Contains(parent.upNode)) {
openList.Add(parent.upNode);
parent.upNode.parent = parent;
calculateScores(parent.upNode);
discoveredNodes.Add(parent.upNode);
} else {
// Here i must check do I need to change path and update scores
}
} ...
我找到了解决方案,但这个解决方案并没有给出正确的路径。 我会把我所有的代码,所以人们可以改进和使用这个解决方案。如果您以任何方式改进此代码,请将其发布在此处,以便我们可以看到您的解决方案。谢谢 首先,我对calculateScore(…)方法和他调用的方法进行了更改。然后我实现了上一篇文章中缺少的代码 节点类:
using System;
using UnityEngine;
using System.Collections;
public class Node {
public Cell cell {get; set;} // Unity Component that is linked to this node
public bool isWalkable {get; set;}
public int x {get; set;}
public int z {get; set;}
public Node rightNode {get; set;}
public Node leftNode {get; set;}
public Node upNode {get; set;}
public Node downNode {get; set;}
public Node upLeftNode {get; set;}
public Node upRightNode {get; set;}
public Node downLeftNode {get; set;}
public Node downRightNode {get; set;}
public Node[] children {get; set;}
public Node parent {get; set;}
public int gScore {get; set;}
public int hScore {get; set;}
public int fScore {get; set;}
public void setGScore(Node start, bool isPenaltyApplied) {
if (start.parent == null) {
gScore = 0;
} else {
if (isPenaltyApplied) {
gScore = start.parent.gScore + 14;
} else {
gScore = start.parent.gScore + 10;
}
}
}
public void setHScore(Node destination, bool isPenaltyApplied) {
if (parent == null) {
hScore = 0;
return;
}
if (parent.hScore == 0) {
hScore = Node.calculateHeuristic(this, destination) * 10;
} else {
hScore = parent.hScore + 10;
}
if (isPenaltyApplied) {
hScore += 10;
}
}
public void updateFScore() {
fScore = gScore + hScore;
}
public Node[] getAllChildren() {
if (this.children == null) {
Node[] children = new Node[8];
children[0] = rightNode;
children[1] = leftNode;
children[2] = upNode;
children[3] = downNode;
children[4] = upLeftNode;
children[5] = upRightNode;
children[6] = downLeftNode;
children[7] = downRightNode;
this.children = children;
}
return this.children;
}
public static int calculateHeuristic(Node from, Node to) {
int distance = 0;
int startX = from.x;
int startZ = from.z;
int destinationX = to.x;
int destinationZ = to.z;
while (startX != destinationX) {
if (startX < destinationX) {
startX++;
} else if (startX > destinationX) {
startX--;
}
distance++;
}
while (startZ != destinationZ) {
if (startZ < destinationZ) {
startZ++;
} else if (startZ > destinationZ) {
startZ--;
}
distance++;
}
return distance;
}
}
using System;
using UnityEngine;
using System.Collections;
public class Engine {
private ArrayList openList;
private ArrayList closedList;
private ArrayList potentialPaths;
public ArrayList path {get; private set;}
public Node startNode {get; set;}
public Node destinationNode {get; set;}
public bool isPathFound {get; set;}
public void startEngine() {
if (startNode != null && destinationNode != null) {
openList = new ArrayList();
closedList = new ArrayList();
traverseNodes();
if (isPathFound) {
path = findPath();
}
}
}
private ArrayList findPath() {
ArrayList bestPath = new ArrayList();
Node currentNode = destinationNode;
while (!object.ReferenceEquals(currentNode, startNode)) {
bestPath.Add(currentNode);
clearUnnecessaryNode(currentNode);
currentNode = currentNode.parent;
}
bestPath.Add(currentNode);
return bestPath;
}
private void clearUnnecessaryNode(Node node) {
Node firstParent = node.parent;
if (object.ReferenceEquals(firstParent, startNode)) {
return;
}
Node secondParent = firstParent.parent;
if (object.ReferenceEquals(node.upRightNode, secondParent)) {
if (node.rightNode != null &&
node.upNode != null &&
node.rightNode.isWalkable &&
node.upNode.isWalkable) {
node.parent = secondParent;
path.Remove(firstParent);
}
}
if (object.ReferenceEquals(node.upLeftNode, secondParent)) {
if (node.leftNode != null &&
node.upNode != null &&
node.leftNode.isWalkable &&
node.upNode.isWalkable) {
node.parent = secondParent;
path.Remove(firstParent);
}
}
if (object.ReferenceEquals(node.downLeftNode, secondParent)) {
if (node.leftNode != null &&
node.downNode != null &&
node.leftNode.isWalkable &&
node.downNode.isWalkable) {
node.parent = secondParent;
path.Remove(firstParent);
}
}
if (object.ReferenceEquals(node.downRightNode, secondParent)) {
if (node.rightNode != null &&
node.downNode != null &&
node.rightNode.isWalkable &&
node.downNode.isWalkable) {
node.parent = secondParent;
path.Remove(firstParent);
}
}
}
private void traverseNodes() {
Node bestNode = startNode;
openList.Add(bestNode);
calculateScores(bestNode, false);
while (!object.ReferenceEquals(bestNode, destinationNode)) {
discoverChildren(bestNode);
closedList.Add(bestNode);
openList.Remove(bestNode);
bestNode = chooseBestNode(bestNode);
if (bestNode == null) {
// Path not found
return;
}
if (object.ReferenceEquals(bestNode, destinationNode)) {
closedList.Add(bestNode);
}
}
// Success
isPathFound = true;
}
private void calculateScores(Node node, bool isPenaltyApplied) {
node.setGScore(startNode, isPenaltyApplied);
node.setHScore(destinationNode, isPenaltyApplied);
node.updateFScore();
}
private ArrayList discoverChildren(Node parent) {
ArrayList discoveredNodes = new ArrayList();
int currentCost = 0;
int newCost = 0;
if (parent.upNode != null &&
parent.upNode.isWalkable &&
!closedList.Contains(parent.upNode)) {
if (!openList.Contains(parent.upNode)) {
openList.Add(parent.upNode);
parent.upNode.parent = parent;
calculateScores(parent.upNode, false);
discoveredNodes.Add(parent.upNode);
} else {
currentCost = parent.upNode.parent.gScore + parent.upNode.gScore;
newCost = parent.gScore + parent.upNode.gScore;
if (newCost < currentCost) {
parent.upNode.parent = parent;
calculateScores(parent.upNode, false);
}
}
}
if (parent.downNode != null &&
parent.downNode.isWalkable &&
!closedList.Contains(parent.downNode)) {
if (!openList.Contains(parent.downNode)) {
openList.Add(parent.downNode);
parent.downNode.parent = parent;
calculateScores(parent.downNode, false);
discoveredNodes.Add(parent.downNode);
} else {
currentCost = parent.downNode.parent.gScore + parent.downNode.gScore;
newCost = parent.gScore + parent.downNode.gScore;
if (newCost < currentCost) {
parent.downNode.parent = parent;
calculateScores(parent.downNode, false);
}
}
}
if (parent.leftNode != null &&
parent.leftNode.isWalkable &&
!closedList.Contains(parent.leftNode)) {
if (!openList.Contains(parent.leftNode)) {
openList.Add(parent.leftNode);
parent.leftNode.parent = parent;
calculateScores(parent.leftNode, false);
discoveredNodes.Add(parent.leftNode);
} else {
currentCost = parent.leftNode.parent.gScore + parent.leftNode.gScore;
newCost = parent.gScore + parent.leftNode.gScore;
if (newCost < currentCost) {
parent.leftNode.parent = parent;
calculateScores(parent.leftNode, false);
}
}
}
if (parent.rightNode != null &&
parent.rightNode.isWalkable &&
!closedList.Contains(parent.rightNode)) {
if (!openList.Contains(parent.rightNode)) {
openList.Add(parent.rightNode);
parent.rightNode.parent = parent;
calculateScores(parent.rightNode, false);
discoveredNodes.Add(parent.rightNode);
} else {
currentCost = parent.rightNode.parent.gScore + parent.rightNode.gScore;
newCost = parent.gScore + parent.rightNode.gScore;
if (newCost < currentCost) {
parent.rightNode.parent = parent;
calculateScores(parent.rightNode, false);
}
}
}
if (parent.upRightNode != null &&
parent.upNode != null &&
parent.rightNode != null &&
parent.upRightNode.isWalkable &&
parent.upNode.isWalkable &&
parent.rightNode.isWalkable &&
!closedList.Contains(parent.upRightNode)) {
if (!openList.Contains(parent.upRightNode)) {
openList.Add(parent.upRightNode);
parent.upRightNode.parent = parent;
calculateScores(parent.upRightNode, true);
discoveredNodes.Add(parent.upRightNode);
} else {
currentCost = parent.upRightNode.parent.gScore + parent.upRightNode.gScore;
newCost = parent.gScore + parent.upRightNode.gScore;
if (newCost < currentCost) {
parent.upRightNode.parent = parent;
calculateScores(parent.upRightNode, true);
}
}
}
if (parent.upLeftNode != null &&
parent.upNode != null &&
parent.leftNode != null &&
parent.upLeftNode.isWalkable &&
parent.upNode.isWalkable &&
parent.leftNode.isWalkable &&
!closedList.Contains(parent.upLeftNode)) {
if (!openList.Contains(parent.upLeftNode)) {
openList.Add(parent.upLeftNode);
parent.upLeftNode.parent = parent;
calculateScores(parent.upLeftNode, true);
discoveredNodes.Add(parent.upLeftNode);
} else {
currentCost = parent.upLeftNode.parent.gScore + parent.upLeftNode.gScore;
newCost = parent.gScore + parent.upLeftNode.gScore;
if (newCost < currentCost) {
parent.upLeftNode.parent = parent;
calculateScores(parent.upLeftNode, true);
}
}
}
if (parent.downRightNode != null &&
parent.downNode != null &&
parent.rightNode != null &&
parent.downRightNode.isWalkable &&
parent.downNode.isWalkable &&
parent.rightNode.isWalkable &&
!closedList.Contains(parent.downRightNode)) {
if (!openList.Contains(parent.downRightNode)) {
openList.Add(parent.downRightNode);
parent.downRightNode.parent = parent;
calculateScores(parent.downRightNode, true);
discoveredNodes.Add(parent.downRightNode);
} else {
currentCost = parent.downRightNode.parent.gScore + parent.downRightNode.gScore;
newCost = parent.gScore + parent.downRightNode.gScore;
if (newCost < currentCost) {
parent.downRightNode.parent = parent;
calculateScores(parent.downRightNode, true);
}
}
}
if (parent.downLeftNode != null &&
parent.downNode != null &&
parent.leftNode != null &&
parent.downLeftNode.isWalkable &&
parent.downNode.isWalkable &&
parent.leftNode.isWalkable &&
!closedList.Contains(parent.downLeftNode)) {
if (!openList.Contains(parent.downLeftNode)) {
openList.Add(parent.downLeftNode);
parent.downLeftNode.parent = parent;
calculateScores(parent.downLeftNode, true);
discoveredNodes.Add(parent.downLeftNode);
} else {
currentCost = parent.downLeftNode.parent.gScore + parent.downLeftNode.gScore;
newCost = parent.gScore + parent.downLeftNode.gScore;
if (newCost < currentCost) {
parent.downLeftNode.parent = parent;
calculateScores(parent.downLeftNode, true);
}
}
}
return discoveredNodes;
}
private Node chooseBestNode(Node closedNode) {
if (openList.Count == 0) {
return null;
}
Node bestNode = (Node)openList[0];
foreach (Node node in openList) {
if (node.fScore < bestNode.fScore) {
bestNode = node;
} else if (node.fScore == bestNode.fScore) {
if (node.gScore < bestNode.gScore) {
bestNode = node;
} else if (object.ReferenceEquals(node, closedNode.upNode) ||
object.ReferenceEquals(node, closedNode.leftNode) ||
object.ReferenceEquals(node, closedNode.rightNode) ||
object.ReferenceEquals(node, closedNode.downNode)) {
// priority have cell that is not in corner of current cell
bestNode = node;
}
}
}
return bestNode;
}
}
使用系统;
使用UnityEngine;
使用系统集合;
公共类节点{
公共单元单元{get;set;}//链接到此节点的Unity组件
公共bool可行走{get;set;}
公共整数x{get;set;}
公共int z{get;set;}
公共节点rightNode{get;set;}
公共节点leftNode{get;set;}
公共节点upNode{get;set;}
公共节点下节点{get;set;}
公共节点{get;set;}
公共节点垂直节点{get;set;}
公共节点downLeftNode{get;set;}
公共节点右下角节点{get;set;}
公共节点[]子节点{get;set;}
公共节点父节点{get;set;}
公共int gScore{get;set;}
公共int hScore{get;set;}
public int fScore{get;set;}
public void setGScore(节点启动,bool ispenaltyaapplied){
if(start.parent==null){
gScore=0;
}否则{
如果(isPenaltyApplied){
gScore=start.parent.gScore+14;
}否则{
gScore=start.parent.gScore+10;
}
}
}
public void setHScore(节点目标,bool ispenaltyaapplied){
如果(父项==null){
hScore=0;
返回;
}
if(parent.hScore==0){
hScore=Node.CalculateEuristic(此,目的地)*10;
}否则{
hScore=parent.hScore+10;
}
如果(isPenaltyApplied){
hScore+=10;
}
}
public void updateScore(){
fScore=gScore+hScore;
}
公共节点[]getAllChildren(){
if(this.children==null){
节点[]子节点=新节点[8];
子节点[0]=rightNode;
子节点[1]=leftNode;
子节点[2]=上节点;
子节点[3]=下行节点;
子节点[4]=upLeftNode;
子节点[5]=垂直节点;
子节点[6]=downLeftNode;
子节点[7]=右下节点;
这个。孩子=孩子;
}
把这个还给孩子们;
}
公共静态整数计算神经(节点自,节点至){
整数距离=0;
int startX=from.x;
int startZ=从.z开始;
int destinationX=到.x;
int destinationZ=to.z;
while(startX!=destinationX){
如果(startX<目的地X){
startX++;
}否则如果(startX>destinationX){
startX--;
}
距离++;
}
while(startZ!=destinationZ){
如果(开始<目的地Z){
startZ++;
}否则如果(开始>目的地Z){
斯塔茨--;
}
距离++;
}
返回距离;
}
}
发动机等级:
using System;
using UnityEngine;
using System.Collections;
public class Node {
public Cell cell {get; set;} // Unity Component that is linked to this node
public bool isWalkable {get; set;}
public int x {get; set;}
public int z {get; set;}
public Node rightNode {get; set;}
public Node leftNode {get; set;}
public Node upNode {get; set;}
public Node downNode {get; set;}
public Node upLeftNode {get; set;}
public Node upRightNode {get; set;}
public Node downLeftNode {get; set;}
public Node downRightNode {get; set;}
public Node[] children {get; set;}
public Node parent {get; set;}
public int gScore {get; set;}
public int hScore {get; set;}
public int fScore {get; set;}
public void setGScore(Node start, bool isPenaltyApplied) {
if (start.parent == null) {
gScore = 0;
} else {
if (isPenaltyApplied) {
gScore = start.parent.gScore + 14;
} else {
gScore = start.parent.gScore + 10;
}
}
}
public void setHScore(Node destination, bool isPenaltyApplied) {
if (parent == null) {
hScore = 0;
return;
}
if (parent.hScore == 0) {
hScore = Node.calculateHeuristic(this, destination) * 10;
} else {
hScore = parent.hScore + 10;
}
if (isPenaltyApplied) {
hScore += 10;
}
}
public void updateFScore() {
fScore = gScore + hScore;
}
public Node[] getAllChildren() {
if (this.children == null) {
Node[] children = new Node[8];
children[0] = rightNode;
children[1] = leftNode;
children[2] = upNode;
children[3] = downNode;
children[4] = upLeftNode;
children[5] = upRightNode;
children[6] = downLeftNode;
children[7] = downRightNode;
this.children = children;
}
return this.children;
}
public static int calculateHeuristic(Node from, Node to) {
int distance = 0;
int startX = from.x;
int startZ = from.z;
int destinationX = to.x;
int destinationZ = to.z;
while (startX != destinationX) {
if (startX < destinationX) {
startX++;
} else if (startX > destinationX) {
startX--;
}
distance++;
}
while (startZ != destinationZ) {
if (startZ < destinationZ) {
startZ++;
} else if (startZ > destinationZ) {
startZ--;
}
distance++;
}
return distance;
}
}
using System;
using UnityEngine;
using System.Collections;
public class Engine {
private ArrayList openList;
private ArrayList closedList;
private ArrayList potentialPaths;
public ArrayList path {get; private set;}
public Node startNode {get; set;}
public Node destinationNode {get; set;}
public bool isPathFound {get; set;}
public void startEngine() {
if (startNode != null && destinationNode != null) {
openList = new ArrayList();
closedList = new ArrayList();
traverseNodes();
if (isPathFound) {
path = findPath();
}
}
}
private ArrayList findPath() {
ArrayList bestPath = new ArrayList();
Node currentNode = destinationNode;
while (!object.ReferenceEquals(currentNode, startNode)) {
bestPath.Add(currentNode);
clearUnnecessaryNode(currentNode);
currentNode = currentNode.parent;
}
bestPath.Add(currentNode);
return bestPath;
}
private void clearUnnecessaryNode(Node node) {
Node firstParent = node.parent;
if (object.ReferenceEquals(firstParent, startNode)) {
return;
}
Node secondParent = firstParent.parent;
if (object.ReferenceEquals(node.upRightNode, secondParent)) {
if (node.rightNode != null &&
node.upNode != null &&
node.rightNode.isWalkable &&
node.upNode.isWalkable) {
node.parent = secondParent;
path.Remove(firstParent);
}
}
if (object.ReferenceEquals(node.upLeftNode, secondParent)) {
if (node.leftNode != null &&
node.upNode != null &&
node.leftNode.isWalkable &&
node.upNode.isWalkable) {
node.parent = secondParent;
path.Remove(firstParent);
}
}
if (object.ReferenceEquals(node.downLeftNode, secondParent)) {
if (node.leftNode != null &&
node.downNode != null &&
node.leftNode.isWalkable &&
node.downNode.isWalkable) {
node.parent = secondParent;
path.Remove(firstParent);
}
}
if (object.ReferenceEquals(node.downRightNode, secondParent)) {
if (node.rightNode != null &&
node.downNode != null &&
node.rightNode.isWalkable &&
node.downNode.isWalkable) {
node.parent = secondParent;
path.Remove(firstParent);
}
}
}
private void traverseNodes() {
Node bestNode = startNode;
openList.Add(bestNode);
calculateScores(bestNode, false);
while (!object.ReferenceEquals(bestNode, destinationNode)) {
discoverChildren(bestNode);
closedList.Add(bestNode);
openList.Remove(bestNode);
bestNode = chooseBestNode(bestNode);
if (bestNode == null) {
// Path not found
return;
}
if (object.ReferenceEquals(bestNode, destinationNode)) {
closedList.Add(bestNode);
}
}
// Success
isPathFound = true;
}
private void calculateScores(Node node, bool isPenaltyApplied) {
node.setGScore(startNode, isPenaltyApplied);
node.setHScore(destinationNode, isPenaltyApplied);
node.updateFScore();
}
private ArrayList discoverChildren(Node parent) {
ArrayList discoveredNodes = new ArrayList();
int currentCost = 0;
int newCost = 0;
if (parent.upNode != null &&
parent.upNode.isWalkable &&
!closedList.Contains(parent.upNode)) {
if (!openList.Contains(parent.upNode)) {
openList.Add(parent.upNode);
parent.upNode.parent = parent;
calculateScores(parent.upNode, false);
discoveredNodes.Add(parent.upNode);
} else {
currentCost = parent.upNode.parent.gScore + parent.upNode.gScore;
newCost = parent.gScore + parent.upNode.gScore;
if (newCost < currentCost) {
parent.upNode.parent = parent;
calculateScores(parent.upNode, false);
}
}
}
if (parent.downNode != null &&
parent.downNode.isWalkable &&
!closedList.Contains(parent.downNode)) {
if (!openList.Contains(parent.downNode)) {
openList.Add(parent.downNode);
parent.downNode.parent = parent;
calculateScores(parent.downNode, false);
discoveredNodes.Add(parent.downNode);
} else {
currentCost = parent.downNode.parent.gScore + parent.downNode.gScore;
newCost = parent.gScore + parent.downNode.gScore;
if (newCost < currentCost) {
parent.downNode.parent = parent;
calculateScores(parent.downNode, false);
}
}
}
if (parent.leftNode != null &&
parent.leftNode.isWalkable &&
!closedList.Contains(parent.leftNode)) {
if (!openList.Contains(parent.leftNode)) {
openList.Add(parent.leftNode);
parent.leftNode.parent = parent;
calculateScores(parent.leftNode, false);
discoveredNodes.Add(parent.leftNode);
} else {
currentCost = parent.leftNode.parent.gScore + parent.leftNode.gScore;
newCost = parent.gScore + parent.leftNode.gScore;
if (newCost < currentCost) {
parent.leftNode.parent = parent;
calculateScores(parent.leftNode, false);
}
}
}
if (parent.rightNode != null &&
parent.rightNode.isWalkable &&
!closedList.Contains(parent.rightNode)) {
if (!openList.Contains(parent.rightNode)) {
openList.Add(parent.rightNode);
parent.rightNode.parent = parent;
calculateScores(parent.rightNode, false);
discoveredNodes.Add(parent.rightNode);
} else {
currentCost = parent.rightNode.parent.gScore + parent.rightNode.gScore;
newCost = parent.gScore + parent.rightNode.gScore;
if (newCost < currentCost) {
parent.rightNode.parent = parent;
calculateScores(parent.rightNode, false);
}
}
}
if (parent.upRightNode != null &&
parent.upNode != null &&
parent.rightNode != null &&
parent.upRightNode.isWalkable &&
parent.upNode.isWalkable &&
parent.rightNode.isWalkable &&
!closedList.Contains(parent.upRightNode)) {
if (!openList.Contains(parent.upRightNode)) {
openList.Add(parent.upRightNode);
parent.upRightNode.parent = parent;
calculateScores(parent.upRightNode, true);
discoveredNodes.Add(parent.upRightNode);
} else {
currentCost = parent.upRightNode.parent.gScore + parent.upRightNode.gScore;
newCost = parent.gScore + parent.upRightNode.gScore;
if (newCost < currentCost) {
parent.upRightNode.parent = parent;
calculateScores(parent.upRightNode, true);
}
}
}
if (parent.upLeftNode != null &&
parent.upNode != null &&
parent.leftNode != null &&
parent.upLeftNode.isWalkable &&
parent.upNode.isWalkable &&
parent.leftNode.isWalkable &&
!closedList.Contains(parent.upLeftNode)) {
if (!openList.Contains(parent.upLeftNode)) {
openList.Add(parent.upLeftNode);
parent.upLeftNode.parent = parent;
calculateScores(parent.upLeftNode, true);
discoveredNodes.Add(parent.upLeftNode);
} else {
currentCost = parent.upLeftNode.parent.gScore + parent.upLeftNode.gScore;
newCost = parent.gScore + parent.upLeftNode.gScore;
if (newCost < currentCost) {
parent.upLeftNode.parent = parent;
calculateScores(parent.upLeftNode, true);
}
}
}
if (parent.downRightNode != null &&
parent.downNode != null &&
parent.rightNode != null &&
parent.downRightNode.isWalkable &&
parent.downNode.isWalkable &&
parent.rightNode.isWalkable &&
!closedList.Contains(parent.downRightNode)) {
if (!openList.Contains(parent.downRightNode)) {
openList.Add(parent.downRightNode);
parent.downRightNode.parent = parent;
calculateScores(parent.downRightNode, true);
discoveredNodes.Add(parent.downRightNode);
} else {
currentCost = parent.downRightNode.parent.gScore + parent.downRightNode.gScore;
newCost = parent.gScore + parent.downRightNode.gScore;
if (newCost < currentCost) {
parent.downRightNode.parent = parent;
calculateScores(parent.downRightNode, true);
}
}
}
if (parent.downLeftNode != null &&
parent.downNode != null &&
parent.leftNode != null &&
parent.downLeftNode.isWalkable &&
parent.downNode.isWalkable &&
parent.leftNode.isWalkable &&
!closedList.Contains(parent.downLeftNode)) {
if (!openList.Contains(parent.downLeftNode)) {
openList.Add(parent.downLeftNode);
parent.downLeftNode.parent = parent;
calculateScores(parent.downLeftNode, true);
discoveredNodes.Add(parent.downLeftNode);
} else {
currentCost = parent.downLeftNode.parent.gScore + parent.downLeftNode.gScore;
newCost = parent.gScore + parent.downLeftNode.gScore;
if (newCost < currentCost) {
parent.downLeftNode.parent = parent;
calculateScores(parent.downLeftNode, true);
}
}
}
return discoveredNodes;
}
private Node chooseBestNode(Node closedNode) {
if (openList.Count == 0) {
return null;
}
Node bestNode = (Node)openList[0];
foreach (Node node in openList) {
if (node.fScore < bestNode.fScore) {
bestNode = node;
} else if (node.fScore == bestNode.fScore) {
if (node.gScore < bestNode.gScore) {
bestNode = node;
} else if (object.ReferenceEquals(node, closedNode.upNode) ||
object.ReferenceEquals(node, closedNode.leftNode) ||
object.ReferenceEquals(node, closedNode.rightNode) ||
object.ReferenceEquals(node, closedNode.downNode)) {
// priority have cell that is not in corner of current cell
bestNode = node;
}
}
}
return bestNode;
}
}
使用系统;
使用UnityEngine;
使用系统集合;
公共级引擎{
私有ArrayList开放列表;
私人ArrayList closedList;
私有数组列表潜在路径;
公共ArrayList路径{get;private set;}
公共节点开始节点{get;set;}
公共节点destinationNode{get;set;}
公共bool isPathFound{get;set;}
公共空间startEngine(){
if(startNode!=null&&destinationNode!=null){
openList=newarraylist();
closedList=newarraylist();
遍历节点();
如果(isPathFound){
path=findPath();
}
}
}
私有ArrayList findPath(){
ArrayList bestPath=新的ArrayList();
节点currentNode=目的节点;
而(!object.ReferenceEquals(currentNode,startNode)){
添加(当前节点);
clearUnnecessaryNode(当前节点);
currentNode=currentNode.parent;
}
添加(当前节点);
返回最佳路径;
}
私有无效clearUnnecessaryNode(节点节点){
Node firstParent=Node.parent;
if(object.ReferenceEquals(firstParent,startNode)){
返回;
}
节点secondParent=firstParent.parent;
if(object.ReferenceEquals(node.upRightNode,secondParent)){
如果(node.rightNode!=null&&
node.upNode!=null&&
node.rightNode.isWalkable&&
node.upNode.isWalkable){
node.parent=secondParent;
移除(第一父级);
}
}
if(object.ReferenceEquals(node.upLeftNode,secondParent)){
如果(node.leftNode!=null&&
node.upNode!=null&&
node.leftNode.isWalkable&&
node.upNode.isWalkable){
node.parent=secondParent;
移除(第一父级);
}
}
if(object.ReferenceEquals(node.downLeftNode,secondParent)){
如果(node.leftNode=