/*
* JavaXYQ Source Code
* by kylixs
* at 2009-11-25
* please visit http://javaxyq.googlecode.com
* or mail to kylixs@qq.com
*/
package com.javaxyq.search;
import java.awt.Point;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* �Ż���AStar�㷨��������E���Դ���
*
* @author dewitt
* @date 2009-11-25 create
*/
public class OptimizeAStar implements Searcher {
private int width;
private int height;
private byte[] maskdata;
public void init(int width, int height, byte[] maskdata) {
this.width = width;
this.height = height;
this.maskdata = convertData(maskdata);
}
public boolean pass(int x, int y) {
return maskdata[x + y * width] == 0;
}
/**
* ����ϵ�任
*
* @param maskdata
* @return
*/
private byte[] convertData(byte[] maskdata) {
byte[] data = new byte[maskdata.length];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
data[x + y * width] = maskdata[x + (height - 1 - y) * width];
}
}
return data;
}
public List<Point> findPath(int x1, int y1, int x2, int y2) {
List<Point> openlist = new ArrayList<Point>();
List<Point> closelist = new ArrayList<Point>();
// ���
List<Point> path = new ArrayList<Point>();
// �����б�_ֵ
byte[][] openlistV = new byte[width][height];
// �����б�_������_x
int[][] parentX = new int[width][height];
// �����б�_������_y
int[][] parentY = new int[width][height];
// �����б�_Gֵ
int[][] openlistG = new int[width][height];
// �����б�_Hֵ
int[][] openlistH = new int[width][height];
// ����б�_ֵ
byte[][] closelistV = new byte[width][height];
// Fֵ��ʷ
int oldF = -1;
// F��ǰֵ
int currF;
// ��ʱ����x,y
Point tmpCoords = new Point(x1, y1);
int tmp = 0;
int currX = 0;
int currY = 0;
int tmpX = 0;
int tmpY = 0;
int[] xdirs = new int[] { -1, 1, -1, 1, 0, -1, 1, 0 };
int[] ydirs = new int[] { -1, -1, 1, 1, -1, 0, 0, 1 };
openlist.add(tmpCoords);
while (openlistG[x2][y2] == 0) {
if (openlist.isEmpty()) {
// ���ִ���
System.err.println("���ִ������б�Ϊ��");
return null;
}
for (int i = 0; i < openlist.size(); i++) {
Point a = openlist.get(i);
if (i == 0) {
oldF = openlistG[a.x][a.y] + openlistH[a.x][a.y];
tmp = i;
currX = a.x;
currY = a.y;
} else {
currF = openlistG[a.x][a.y] + openlistH[a.x][a.y];
if (oldF >= currF) {
oldF = currF;
tmp = i;
currX = a.x;
currY = a.y;
}
}
}
System.out.println("select: " + tmp);
openlist.remove(tmp);
openlistV[currX][currY] = 0;
tmpCoords = new Point(currX, currY);
closelist.add(tmpCoords);
closelistV[currX][currY] = 1;
for (int d = 0; d < 8; d++) {
tmpX = currX + xdirs[d];
tmpY = currY + ydirs[d];
if (tmpX < 1 || tmpY < 1) {
} else if (maskdata[tmpX + tmpY * width] == 0) {
} else if (closelistV[tmpX][tmpY] == 1) {
} else {
if (openlistV[tmpX][tmpY] == 1) {
tmp = openlistG[currX][currY] + d > 3 ? 10 : 14;
if (openlistG[tmpX][tmpY] > tmp) {
openlistG[tmpX][tmpY] = openlistG[currX][currY] + d > 3 ? 10 : 14;
parentX[tmpX][tmpY] = currX;
parentY[tmpX][tmpY] = currY;
}
} else {
openlistV[tmpX][tmpY] = 1;
tmpCoords = new Point(tmpX, tmpY);
openlist.add(tmpCoords);
parentX[tmpX][tmpY] = currX;
parentY[tmpX][tmpY] = currY;
openlistG[tmpX][tmpY] = openlistG[currX][currY] + d > 3 ? 10 : 14;
openlistH[tmpX][tmpY] = (Math.abs(x2 - tmpX) + Math.abs(y2 - tmpY)) * 10;
if (currX > 0) {
}
}
}
}
}
tmpCoords = new Point(x2, y2);
path.add(tmpCoords);
tmpCoords = new Point(parentX[x2][y2], parentY[x2][y2]);
while (!(tmpCoords.x == 0 && tmpCoords.y == 0)) {
path.add(tmpCoords);
if (tmpCoords.x > 0 && tmpCoords.y > 0) {
tmpX = parentX[tmpCoords.x][tmpCoords.y];
tmpY = parentY[tmpCoords.x][tmpCoords.y];
tmpCoords = new Point(tmpX, tmpY);
} else {
System.out.println("���ɵ���㣺" + tmpCoords.x + "," + tmpCoords.y);
}
}
Collections.reverse(path);
return path;
}
}