📄 aasterisk.java
字号:
import java.util.Vector;
/**
* <p>Title:A*寻路算法 </p>
*
* <p>Description: A*寻路算法</p>
*
* <p>Copyright: Copyright (c) 2005 wodead</p>
*
* <p>Company: wodead</p>
*
* @author wodead
* @version 1.0
*/
public class AAsterisk {
/**
* 开表
*/
private Vector openList = new Vector();
/**
* 闭表
*/
private BlockNode[][] closeList = new BlockNode[12][10];
/**
* 当前节点
*/
private BlockNode currentNode;
/**
* 构造一个算法
*
*/
public AAsterisk() {
}
/**
* 返回路径
* @param startRow
* @param startColumn
* @param targetRow
* @param targetColumn
* @param path, 假如无法找到路径,以及起点终点一样则将path置空,否则将路线填入该列表中,第一个节点为起点,最后一个节点为终点
*/
public void find(int startRow, int startColumn, int targetRow, int targetColumn, Vector path) {
path.removeAllElements();
//起点终点一样返回
if (startRow == targetRow && startColumn == targetColumn)
return;
//清空开和闭表
openList.removeAllElements();
for (int i = 0; i < 12; i++)
for (int j = 0; j < 10; j++)
closeList[i][j] = null;
//添加起始节点到开启列表
BlockNode startNode = new BlockNode(startRow, startColumn, null);
addToOpenList(startNode);
while(!openList.isEmpty()) {
//选取F值最小的节点为当前节点
currentNode = (BlockNode)openList.firstElement();
int curRow = currentNode.row;
int curColumn = currentNode.column;
//切换当前节点到关闭列表中
openList.removeElement(currentNode);
closeList[curRow][curColumn] = currentNode;
//处理当前节点的相邻节点
int sRow = (curRow > 1) ? curRow - 1 : 0;
int sColumn = (curColumn > 1) ? curColumn - 1 : 0;
int eRow = (curRow < 10) ? curRow + 1 : 11;
int eColumn = (curColumn < 8) ? curColumn + 1 : 9;
for (int i = sRow; i <= eRow; i++) {
for (int j = sColumn; j <= eColumn; j++) {
//是自己或者该节点不可达,循环继续
if ((i == curRow && j == curColumn) ||
!Main.canCross(i, j))
continue;
//创建一个节点,指定其父结点
BlockNode node = new BlockNode(i ,j, currentNode);
//设置G值,水平和垂直方向为10,对角线为14
node.g = currentNode.g + ((i == curRow || j == curColumn) ? 10 : 14);
//目标节点被添加到开启列表中,搜索可以结束了,路径找到了
if (targetRow == i && targetColumn == j) {
while (node.parent != null) {
path.insertElementAt(node, 0);
node = node.parent;
}
path.insertElementAt(node, 0);
return;
}
//该节点在关闭列表中,不做处理
if (closeList[i][j] != null)
continue;
BlockNode openBlock = listContains(node, openList);
if(openBlock == null) {
//节点不在开列表中,设置H值并添加到开表中
//设置H值,G值已经在建立node时应该已经被设置好了,并且父结点已经为currentNode
node.h = 10*(Math.abs(targetRow - i) +
Math.abs(targetColumn - j));
addToOpenList(node);
} else if (openBlock.g > node.g) {
//节点在开列表中,假如g更小则改变其父结点为当前节点
openList.removeElement(openBlock);
addToOpenList(node);
}
}
}
}
}
/**
* 添加节点到开表中,并按F值进行排序,从小到大
* @param node
*/
private void addToOpenList(BlockNode node) {
int count = openList.size();
for (int i = 0; i < count; i++) {
BlockNode openNode = (BlockNode)openList.elementAt(i);
if (node.getF() <= openNode.getF()) {
openList.insertElementAt(node, i);
return;
}
}
openList.addElement(node);
}
/**
* 表中是否已经包含新添的节点
* @param node
* @param list
* @return 表中的节点
*/
private BlockNode listContains(BlockNode node, Vector list) {
int count = list.size();
for (int i = 0; i < count; i++) {
BlockNode listNode = (BlockNode) list.elementAt(i);
if (node.row == listNode.row &&
node.column == listNode.column)
return listNode;
}
return null;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -