Back to project page TheFirstMyth02.
The source code is released under:
MIT License
If you think the Android project TheFirstMyth02 listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package com.game.commen; /* w ww .j a v a 2s.c o m*/ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class AStarMap { private List<AStarNode> openList = new ArrayList<AStarNode>(); private Map<String, AStarNode> closeMap = new HashMap<String, AStarNode>(); // private Set< AStarNode> closeSet = new HashSet< AStarNode>(); private boolean isFind = false; private List<AStarNode> path = new ArrayList<AStarNode>(); /** ???? */ public static final int STATE_BARRIER = 2; AStarNode target; AStarNode source; int[][] astarData; public AStarMap(int xGridNum, int yGridNum) { astarData = new int[yGridNum][xGridNum]; source = new AStarNode(0, 0); target = new AStarNode(xGridNum - 1, yGridNum - 1); } private int[][]data; public int[][] getData() { return data; } public void setData(int[][] data) { this.data = data; } // public static void main(String[] args) { // AStarMap asm = new AStarMap(100, 200); // // int[][]data= { // // {0,0,0,0,0},{0,0,0,0,0},{0,0,1,0,0},{0,0,0,0,0},{0,0,0,0,0}, // // {0,0,0,0,0},{0,0,0,0,0},{0,0,1,0,0},{0,0,0,0,0},{0,0,0,0,0}, // // {0,0,0,0,0},{0,0,0,0,0},{0,0,1,0,0},{0,0,0,0,0},{0,0,0,0,0}, // // {0,0,0,0,0},{0,0,1,0,0},{0,0,1,0,0},{0,0,0,0,0},{0,0,0,0,0}, // // {0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0}, // // }; // // asm.loadData(data, 1, -1); // List list1 = asm.find(); // // for (int i = 0; i < list1.size(); i++) { // AStarNode asn = (AStarNode) list1.get(i); // System.out.println(asn.getX() + " " + asn.getY()); // } // asm.toString(); // List list = asm.getOpenList(); // for (int i = 0; i < list.size(); i++) { // AStarNode asn = (AStarNode) list.get(i); // System.out.println(asn.getX() + " " + asn.getY() // + " ====== " + asn.getFather().getX() + " " // + asn.getFather().getY()); // } // // } public AStarNode getTarget() { return target; } public AStarNode getSource() { return source; } public int[][] getAStarData() { return astarData; } /** * ?????? */ public List<AStarNode> find() { init(); AStarNode current = null; while (!isEnd() && !isFind()) { current = getMinFNodeFromOpenList(); if (isAchieve(current)) { // ???????????? buildPath(current); isFind = true; } else { add2CloseMap(current); for (AStarNode neighbor : getNeighbor(current)) { if (neighbor == null || isInCloseMap(neighbor) || /* * ???????????? * ???? */ isCanNotGo(current, neighbor)) continue; boolean isBetter = true; AStarNode nodeFromOpenList = getNodeFromOpenList(neighbor); if (nodeFromOpenList != null) { // ?????????? neighbor = nodeFromOpenList; int tg = neighbor.distinctG(current); isBetter = tg > neighbor.getG() ? false : true; } else { add2OpenList(neighbor); } if (isBetter) { neighbor.reCalculatorGAndH(current, target); } } } } return path; } private AStarNode getNodeFromOpenList(AStarNode node) { for (AStarNode openNode : openList) { if (openNode.equals(node)) return openNode; } return null; } /** * ???from???to???????????? * * @param from * @param to * @return */ private boolean isCanNotGo(AStarNode from, AStarNode to) { if (isBarrier(to)) { /* ???????????????????? */ return true; } else { /* ?????? */ int offsetX = from.getX() - to.getX(); int offsetY = from.getY() - to.getY(); if (Math.abs(offsetX) == 1 && Math.abs(offsetY) == 1) { // ??????????????????? if ((offsetX == 1 && offsetY == -1 && (isValidX(from.getX() - 1) && STATE_BARRIER == astarData[from.getY()][from.getX() - 1] || isValidY(from .getY() + 1) && STATE_BARRIER == astarData[from.getY() + 1][from .getX()])) || (offsetX == 1 && offsetY == 1 && (isValidY(from .getY() - 1) && STATE_BARRIER == astarData[from.getY() - 1][from .getX()] || isValidX(from.getX() - 1) && STATE_BARRIER == astarData[from.getY()][from .getX() - 1])) || (offsetX == -1 && offsetY == 1 && (isValidX(from .getX() + 1) && STATE_BARRIER == astarData[from.getY()][from .getX() + 1] || isValidY(from.getY() - 1) && STATE_BARRIER == astarData[from.getY() - 1][from .getX()])) || (offsetX == -1 && offsetY == -1 && (isValidX(from .getX() + 1) && STATE_BARRIER == astarData[from.getY()][from .getX() + 1] || isValidY(from.getY() + 1) && STATE_BARRIER == astarData[from.getY() + 1][from .getX()]))) return true; } } return false; } private boolean isValidX(int x) { return x >= 0 && x < astarData[0].length; } private boolean isValidY(int y) { return y >= 0 && y < astarData.length; } private boolean isBarrier(AStarNode node) { return astarData[node.getY()][node.getX()] == STATE_BARRIER; } private List<AStarNode> buildPath(AStarNode current) { if (current != null) { do { path.add(0, current); current = current.getFather(); } while (current != null); } return path; } /** * ???????????????? * * @param node * @return */ private boolean isInOpenList(AStarNode node) { return openList.contains(node); } public List<AStarNode> getOpenList() { return openList; } /** * ?????????????? * * @param node * @return */ private boolean isInCloseMap(AStarNode node) { // return closeSet.contains(node); return closeMap.containsKey(node.toString()); } private AStarNode[] getNeighbor(AStarNode current) { AStarNode[] neighbors = new AStarNode[9]; for (int i = 0; i < neighbors.length; i++) { int x = current.getX() + i / 3 - 1; int y = current.getY() + i % 3 - 1; if (x < 0 || y < 0 || x >= astarData[0].length || y >= astarData.length || (x == current.getX() && y == current.getY())) continue; neighbors[i] = new AStarNode(x, y); } return neighbors; } /** * ???????????F????? * * @return */ private AStarNode getMinFNodeFromOpenList() { int index = 0; int minF = openList.get(index).getF(); int length = openList.size(); for (int i = 1; i < length; i++) { AStarNode aStarNode = openList.get(i); if (minF > aStarNode.getF()) { minF = aStarNode.getF(); index = i; } } return openList.remove(index); } /** * ??????????????? * * @param current * @return */ private boolean isAchieve(AStarNode current) { return current.equals(target); } /** * ???????? ??????????? ??????????????? */ private void init() { initParameter(); initOpenListAndCloseMap(); addSource2OpenList(); } private void initParameter() { isFind = false; source.init(target); path.removeAll(path); } private void initOpenListAndCloseMap() { clearOpenList(); closeMap.clear(); // closeSet.clear(); } public void clearOpenList() { openList.removeAll(openList); } private void addSource2OpenList() { add2OpenList(source); } private void add2OpenList(AStarNode node) { openList.add(node); } private void add2CloseMap(AStarNode node) { // closeSet.add(node); closeMap.put(node.toString(), node); } /** * ???????? * * @return */ private boolean isFind() { return isFind; } /** * ???????????? * * @return */ private boolean isEnd() { return openList.size() == 0; } public void loadData(int[][] data, int barrierVal, int clearVal) { if (data == null) return; if (data.length != astarData.length || astarData[0].length != data[0].length) throw new RuntimeException( "new data should be as large as the old astar map' data"); for (int i = 0; i < astarData.length; i++) { for (int j = 0; j < astarData[i].length; j++) { if (data[i][j] == barrierVal) astarData[i][j] = STATE_BARRIER; else if (data[i][j] == clearVal) astarData[i][j] = 0; } } } public void setTarget(AStarNode target) { this.target = target; } public void setSource(AStarNode source) { this.source = source; } public void initTargetAndSource(int x, int y) { this.source.setX(this.target.getX()); this.source.setY(this.target.getY()); this.target.setX(x); this.target.setY(y); } }