| package com.zy.acs.manager.core.service.astart.domain; | 
|   | 
| import lombok.Data; | 
| import lombok.extern.slf4j.Slf4j; | 
|   | 
| import java.io.Serializable; | 
| import java.util.*; | 
| import java.util.stream.Collectors; | 
|   | 
| /** | 
|  * A*寻路算法Node节点 | 
|  */ | 
| @Slf4j | 
| @Data | 
| public class AStarNavigateNode implements Comparable<AStarNavigateNode>, Cloneable, Serializable { | 
|   | 
|     private static final long serialVersionUID = 1L; | 
|   | 
|     private int x;  //坐标x | 
|     private int y;  //坐标y | 
|     private int turnCount;  //转弯次数 | 
|   | 
|     private int G;  //已经花费的步数 | 
|     private int H;  //将要花费的步数 | 
|     private int F;  //综合花费的步数 | 
|   | 
|     private AStarNavigateNode parent;    //父节点 | 
|     private Integer lastDistance;   // 距离上个节点距离 | 
|     private Integer weight;        // G 权重 | 
| //    private boolean turningPoint;   //是否为拐点 | 
| //    private Integer moveDistance;   // 总行走距离 | 
| //    private String direction;   //行走方向 | 
|   | 
|     private String codeData; | 
|   | 
|     public AStarNavigateNode(int x, int y) { | 
|         this.x = x; | 
|         this.y = y; | 
|         this.turnCount = 0; | 
|     } | 
|   | 
|     public AStarNavigateNode(int x, int y, String codeData) { | 
|         this.x = x; | 
|         this.y = y; | 
|         this.turnCount = 0; | 
|         this.codeData = codeData; | 
|     } | 
|   | 
|     //通过结点的坐标和目标结点的坐标可以计算出F, G, H三个属性 | 
|     //需要传入这个节点的上一个节点和最终的结点 | 
|     public void initNode(AStarNavigateNode father, AStarNavigateNode end) { | 
|         this.parent = father; | 
|         if (this.parent != null) { | 
|             //走过的步数等于父节点走过的步数加一 | 
|             this.G = this.parent.G | 
|                     + Optional.ofNullable(this.lastDistance).orElse(0) | 
|                     + Optional.ofNullable(this.weight).orElse(0); | 
|         } else { //父节点为空代表它是第一个结点 | 
|             this.G = 0; | 
|         } | 
|   | 
|         //以下计算方案为算法原始方案,没有去拐点方案。已被Solution计算时自动覆盖。 | 
|         //计算通过现在的结点的位置和最终结点的位置计算H值(曼哈顿法:坐标分别取差值相加) | 
|         this.H = Math.abs(this.x - end.x) + Math.abs(this.y - end.y); | 
|         this.F = this.G + this.H; | 
|     } | 
|   | 
|     @Override | 
|     public int compareTo(AStarNavigateNode o) { | 
|         return Integer.compare(this.F, o.F); | 
|     } | 
|   | 
|     @Override | 
|     public AStarNavigateNode clone() { | 
|         try { | 
|             return (AStarNavigateNode) super.clone(); | 
|         } catch (CloneNotSupportedException e) { | 
|             log.error(this.getClass().getSimpleName(), e); | 
|         } | 
|         return null; | 
|     } | 
|   | 
|     @Override | 
|     public boolean equals(Object obj) { | 
|         if (this == obj) return true; | 
|         if (!(obj instanceof AStarNavigateNode)) return false; | 
|         AStarNavigateNode that = (AStarNavigateNode) obj; | 
|         return this.x == that.x | 
|                 && this.y == that.y | 
| //                && this.turnCount == that.turnCount   // ** 转弯优化,严重影响性能 | 
|                 ; | 
|     } | 
|   | 
|     @Override | 
|     public int hashCode() { | 
|         return Objects.hash( | 
|                 this.x | 
|                 , this.y | 
| //                , this.turnCount  // ** 转弯优化,严重影响性能 | 
|         ); | 
|     } | 
|   | 
|   | 
|     private void print() { | 
|         AStarNavigateNode finishNode = this.clone(); | 
|         ArrayList<AStarNavigateNode> navigateNodes = new ArrayList<>(); | 
|   | 
|         while (finishNode != null) { | 
|             navigateNodes.add(finishNode); | 
|             System.out.println("node:" + finishNode.getCodeData() + ", g:" + finishNode.getG() + ", h:" + finishNode.getH() + ", f:" + finishNode.getF()); | 
|             finishNode = finishNode.getParent(); | 
|         } | 
|   | 
|         Collections.reverse(navigateNodes); | 
|   | 
|         List<String> navigatePath = navigateNodes.stream().map(AStarNavigateNode::getCodeData).collect(Collectors.toList()); | 
|         System.out.println(navigatePath.toString()); | 
|     } | 
|   | 
| } |