package rpg.stage.path;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator; import rpg.objs.Point; public class BFinding { public BFinding() {
} protected HashSet<Point> openList = new HashSet<Point>();
protected HashSet<Point> leftList = new HashSet<Point>();
protected HashSet<Point> rightList = new HashSet<Point>();
protected HashSet<Point> closeList = new HashSet<Point>(); public synchronized ArrayList<int[]> find(Point start,Point end,boolean canPenetrate){
if(end == null){
return new ArrayList<int[]>();
}
if(start == null){
return new ArrayList<int[]>();
}
end.clear();
start.clear();
openList.clear();
openList.add(start);
leftList.clear();
rightList.clear();
closeList.clear(); int count = 0; while(!openList.isEmpty() || !leftList.isEmpty() || !rightList.isEmpty()){
count ++;
if(count>1000)
break;
Iterator<Point> it = openList.iterator();
if(it.hasNext()){
Point p = it.next();
it.remove();
if(sideNext(p,end,0,canPenetrate))break;
}
it = leftList.iterator();
if(it.hasNext()){
Point p = it.next();
it.remove();
if(sideNext(p,end,1,canPenetrate))break;
}
it = rightList.iterator();
if(it.hasNext()){
Point p = it.next();
it.remove();
if(sideNext(p,end,-1,canPenetrate))break;
}
}
final ArrayList<int[]> list = new ArrayList<int[]>();
while(end.parent!=null){
list.add(0,new int[]{end.x,end.y});
end = end.parent;
}
return list;
} /**
*
* @param p
* @param end 目标点
* @param side 0 direct -1 right 1 left
* @param canPenetrate 可否穿透
*/
protected boolean sideNext(Point p,Point end,int side,boolean canPenetrate){
int dir = Point.getDirSimple(p, end);
Point nextp = null; if(closeList.contains(p)){
nextp = nextPassPointSide(p,end,-1,canPenetrate);
if(nextp != null){
if(nextp == end){
nextp.parent = p;
return true;
}
if(this.closeList.contains(nextp))
// return sideNext(nextp, end, side, canPenetrate);
return false;
else if(!this.leftList.contains(nextp))
addToSearch(p,nextp,this.rightList);
}
nextp = nextPassPointSide(p,end,1,canPenetrate);
if(nextp != null){
if(nextp == end){
nextp.parent = p;
return true;
}
if(this.closeList.contains(nextp))
// return sideNext(nextp, end, side, canPenetrate);
return false;
else if(!this.rightList.contains(nextp))
addToSearch(p,nextp,this.leftList);
}
return false;
}
this.closeList.add(p);
if(side == 0){
if(p.canWalkDir(dir,canPenetrate)){//下一个点可以走
nextp = p.getPassPointByDir(dir);
if(nextp == end){
nextp.parent = p;
return true;
}
if(!this.closeList.contains(nextp)){
addToSearch(p,nextp,this.openList);
}
}
else//不可走,就分支出两个围绕探索点
{
nextp = nextPassPointSide(p,end,-1,canPenetrate);
if(nextp == end){
nextp.parent = p;
return true;
}
if(nextp != null){
if(this.closeList.contains(nextp))
return sideNext(nextp, end, side, canPenetrate);
// return false;
else if(!this.leftList.contains(nextp))
addToSearch(p,nextp,this.rightList);
}
nextp = nextPassPointSide(p,end,1,canPenetrate);
if(nextp == end){
nextp.parent = p;
return true;
}
if(nextp != null){
if(this.closeList.contains(nextp))
return sideNext(nextp, end, side, canPenetrate);
// return false;
else if(!this.rightList.contains(nextp))
addToSearch(p,nextp,this.leftList);
}
}
}
else if(side>0){
nextp = p.getPassPointByDir(dir);
if(nextp == end){
nextp.parent = p;
return true;
}
if(nextp != null && !this.closeList.contains(nextp)){
addToSearch(p,nextp,this.openList);
}
else
{
nextp = nextPassPointSide(p,end,1,canPenetrate);
if(nextp == end){
nextp.parent = p;
return true;
}
if(nextp != null && !this.closeList.contains(nextp) && !this.rightList.contains(nextp)){
addToSearch(p,nextp,this.leftList);
}
}
}
else if(side<0){
nextp = p.getPassPointByDir(dir);
if(nextp == end){
nextp.parent = p;
return true;
}
if(nextp != null && !this.closeList.contains(nextp)){
addToSearch(p,nextp,this.openList);
}
else
{
nextp = nextPassPointSide(p,end,-1,canPenetrate);
if(nextp == end){
nextp.parent = p;
return true;
}
if(nextp != null && !this.closeList.contains(nextp) && !this.leftList.contains(nextp)){
addToSearch(p,nextp,this.rightList);
}
}
}
return false;
} protected void addToSearch(Point parent,Point next,HashSet<Point> list){
next.clear();
next.parent = parent;
list.add(next);
} /**
*
* @param p
* @param side >0 或者 <0
* @param canPenetrate
* @return
*/
protected Point nextPassPointSide(Point p,Point end,int side,boolean canPenetrate){
int dir = Point.getDirSimple(p, end);
Point nextp = null;
if(side<0){
while(side>=-7){
dir = Point.rightdir(dir);
if(p.canWalkDir(dir,canPenetrate)){
nextp = p.getPassPointByDir(dir);
if(!this.closeList.contains(nextp)){
break;
}
}
side--;
}
}
else
{
while(side<=7){
dir = Point.leftdir(dir);
if(p.canWalkDir(dir,canPenetrate)){
nextp = p.getPassPointByDir(dir);
if(!this.closeList.contains(nextp)){
break;
}
}
side++;
}
}
return nextp;
}
}

使用Java编写的B*算法的更多相关文章

  1. 「福利」Java Swing 编写的可视化算法工程,包含树、图和排序

    之前在整理<学习排序算法,结合这个方法太容易理解了>这篇文章时,发现了一个用 Java Swing 编写的可视化算法工程,真心不错!包含了常用数据结构和算法的动态演示,先来张图感受下: 可 ...

  2. 小学四则运算练习(JAVA编写)

    源码在Github的仓库主页链接地址:https://github.com/rucr9/rucr 看到这个题目,大概很多人会发出“切,这也太简单了吧!有必要小题大做?”的感叹!是的,仅仅作为一道数学运 ...

  3. 数据结构与算法【Java】05---排序算法总结

    前言 数据 data 结构(structure)是一门 研究组织数据方式的学科,有了编程语言也就有了数据结构.学好数据结构才可以编写出更加漂亮,更加有效率的代码. 要学习好数据结构就要多多考虑如何将生 ...

  4. Java中的经典算法之冒泡排序(Bubble Sort)

    Java中的经典算法之冒泡排序(Bubble Sort) 神话丿小王子的博客主页 原理:比较两个相邻的元素,将值大的元素交换至右端. 思路:依次比较相邻的两个数,将小数放在前面,大数放在后面.即在第一 ...

  5. Java中的查找算法之顺序查找(Sequential Search)

    Java中的查找算法之顺序查找(Sequential Search) 神话丿小王子的博客主页 a) 原理:顺序查找就是按顺序从头到尾依次往下查找,找到数据,则提前结束查找,找不到便一直查找下去,直到数 ...

  6. Java中的经典算法之选择排序(SelectionSort)

    Java中的经典算法之选择排序(SelectionSort) 神话丿小王子的博客主页 a) 原理:每一趟从待排序的记录中选出最小的元素,顺序放在已排好序的序列最后,直到全部记录排序完毕.也就是:每一趟 ...

  7. 网页动物园2.0发布,经过几个月的努力,采用JAVA编写!

    网页动物园2.0发布,经过几个月的努力,采用JAVA编写! 网页动物园2.0 正式发布!游戏发布 游戏名称: 网页动物园插件 游戏来源: 原创插件 适用版本: Discuz! X1.5 - X3.5 ...

  8. Java中的排序算法(2)

    Java中的排序算法(2) * 快速排序 * 快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为两个子序列(sub-lists). * 步骤为: * 1. 从数 ...

  9. 使用Java编写一个简单的Web的监控系统cpu利用率,cpu温度,总内存大小

    原文:http://www.jb51.net/article/75002.htm 这篇文章主要介绍了使用Java编写一个简单的Web的监控系统的例子,并且将重要信息转为XML通过网页前端显示,非常之实 ...

随机推荐

  1. Upgrade Ver 4.3.x from 4.2.x

    级到遇到个小问题.解决细节记录例如以下. [gpadmin@wx60 ~]$ gpmigrator /usr/local/greenplum-db-4.2.7.2 /usr/local/greenpl ...

  2. 3D数学学习笔记——笛卡尔坐标系

    本系列文章由birdlove1987编写.转载请注明出处. 文章链接: http://blog.csdn.net/zhurui_idea/article/details/24601215 1.3D数学 ...

  3. Html.Partial和Html. RenderPartial用法

    Html.Partial和Html. RenderPartial用法 Html.partial和RenderPartial的用法与区别Html.partial和RenderPartial都是输出htm ...

  4. BestCoder-Round#33

    写在前面 这是我第一次做BestCoder, 熟悉的外观BestCoder模式. BC上不仅能看到英文, 背部Chinese view是中文题目 交的次数是会影响得分的. 所以有了把握再交. 至少例子 ...

  5. ASP.NET AJAX简明教程

     当我们谈论Ajax时,首先想到的就是JavaScript下的Ajax,用来完成网页的交互,局部刷新工作,Microsoft的ASP.NET AJAX框架在Web的开发中承担着类似的角色,并简化了Ja ...

  6. 谷歌、火狐浏览器下实现JS跨域iframe高度自适应的完美解决方法,跨域调用JS不再是难题!

    谷歌.火狐浏览器下实现JS跨域iframe高度自适应的解决方法 导读:今天开发的时候遇到个iframe自适应高度的问题,相信大家对这个不陌生,但是一般我们都是在同一个项目使用iframe嵌套页面,这个 ...

  7. 【百度地图API】你看过房产地图吗?你知道房产标注是如何建立的吗?

    原文:[百度地图API]你看过房产地图吗?你知道房产标注是如何建立的吗? 你是不是看过很多房产网站?例如安居客,新浪乐居. 你是不是也想做一个能写文字的标注? 你知道怎么去实现麼? 其实,上图这样的标 ...

  8. CentOS-6.5-x86_64 最小化安装,已安装包的总数,这些包?

    一.我们怎么知道有多少的包被安装? [root@localhost ~]# rpm -qa | wc -l 217 二.怎样得知安装了那些软件包? [root@localhost ~]# rpm -q ...

  9. Socket 学习(三)

    前2节,说的是 Server 与 Client 的数据交互.服务端IP.端口固定,客户端 网服务端发送消息的时候,他的Socket对面被服务端获取到了,而且链接没有中断,他当然可以很容易回复信息. 现 ...

  10. PLSQL_监控有些SQL的执行次数和频率

    原文:PLSQL_监控有些SQL的执行次数和频率 2014-12-25 Created By 鲍新建