网站首页
JSP空间
动态资讯
开源项目
技术文档
资源下载
J2EE资源
客户论坛
在线支付
 
  技术文档>>JAVA>>新手入门>>基础入门>查看文档  
  基于binary heap的a*算法     
  文章作者:未知  文章来源:水木森林  
  查看:105次  录入:管理员--2007-11-17  
 

--------------代码来源于网络-----------------------

最近比较空闲,研究了一下手机游戏中的寻路算法

小地图中,解决的方式就不说了,怎么解决都差不多,如果地图比较大,就要好好考虑了

gameloft的彩虹六号里面的寻路算法就很经典,但据说他们是发明了一种专利算法,具体的我就不知道了~但我估计应该是在地图里面设置了一些路点之类的标志。。。。。

我今天贴的代码完全是别人的代码,我也没改动,也没有测试过内存占用,紧紧提供给大家一个大体思路,各位兄弟具体使用时肯定还需要修改的。尤其对于内存资源比较紧张的手机来说,a*算法的改进绝对值得各位好好研究

相关资料:

a*寻路算法(for 初学者)

在a*寻路中使用二*堆

enjoy:)

--------------------------source code----------------------------------------------

/**
* astar pathfinding algorithm
*/
public class astar {
private square[][] squares;

public static final byte wall = 0x1, blank = 0x0;

public static final byte wall_mask = (byte) 0xf;

public static final byte open_mask = (byte) 0x80;

public static final byte closed_mask = (byte) 0x40;

private byte[][] map;

private square lstart;

private square lend;

private static final byte orthogonal_cost = 1;

byte height;

byte width;

// binary heap
public square[] heaptree;

public int heapsize;

boolean first = true;

void updatemap(byte[][] mapmatrix) {
  if (map != null) {
   map = null;
   releasefind();
  } else {
   lstart = new square((byte) 0, (byte) 0, (byte) 0, (byte) 0);
   lend = new square((byte) 0, (byte) 0, (byte) 0, (byte) 0);

   heaptree = new square[height * width + 1];
   squares = new square[height][width];
  }
  map = mapmatrix;
}

public void releasefind() {
  int i, j;
  for (i = 0; i < height; i++) {
   for (j = 0; j < width; j++) {
    squares[i][j] = null;
   }
  }

  for (i = 0; i < heaptree.length; i++) {
   heaptree[i] = null;
  }
}

public square findpath(byte sy, byte sx, byte ey, byte ex, boolean canfly) {
  lstart.x = sx;
  lstart.y = sy;
  lend.x = ex;
  lend.y = ey;
  if (canfly) {
   square sqr, last;
   last = lstart;
   int sign;
   if (ex != sx) {
    sign = (ex - sx) / math.abs(ex - sx);
    for (byte i = (byte) (sx + sign); i != ex; i += sign) {
     sqr = new square(sy, i, (byte) 0, (byte) 0);
     sqr.parent = last;
     last = sqr;
    }
   }
   if (ey != sy) {
    sign = (ey - sy) / math.abs(ey - sy);
    for (byte i = (byte) (sy); i != ey; i += sign) {
     sqr = new square(i, ex, (byte) 0, (byte) 0);
     sqr.parent = last;
     last = sqr;
    }
   }
   lend.parent = last;
   return lend;
  }

  byte height = this.height;
  byte width = this.width;

  int i, j;
  for (i = 0; i < height; i++) {
   for (j = 0; j < width; j++) {
    map[i][j] &= wall_mask;
   }
  }
  heapsize = 0;

  openlistinsert(this.lstart.y, this.lstart.x, (byte) 0, null);
  square current = null;

  byte ty = 0, tx = 0, tg = 0, tmpg;

  while (heapsize != 0) {
   // 取出open表中第一个
   current = openlistremove();

   // 到达终点!
   if (current.y == this.lend.y && current.x == this.lend.x) {
    return current;
   }

   byte cy = current.y;
   byte cx = current.x;

   fl: for (i = 0; i < 4; i++) {
    switch (i) {
    case 0: // 上
     ty = (byte) (cy - 1);
     if (ty < 0)
      continue fl;
     tx = cx;
     tg = orthogonal_cost;
     break;
    case 1: // 左
     tx = (byte) (cx - 1);
     if (tx < 0)
      continue fl;
     ty = cy;
     tg = orthogonal_cost;
     break;
    case 2: // 右
     tx = (byte) (cx + 1);
     if (tx >= width)
      continue fl;
     ty = cy;
     tg = orthogonal_cost;
     break;
    case 3: // 下
     ty = (byte) (cy + 1);
     if (ty >= height)
      continue fl;
     tx = cx;
     tg = orthogonal_cost;
     break;
    default:
     break;
    }

    if ((this.map[ty][tx] & wall_mask) != wall
      && (this.map[ty][tx] & closed_mask) == 0) {
     if ((this.map[ty][tx] & open_mask) == 0) {
      openlistinsert(ty, tx, (byte) (current.g + tg), current);
     } else {
      tmpg = (byte) (current.g + tg);
      if (this.squares[ty][tx].g > tmpg) {

       this.squares[ty][tx].setg(tmpg);
       this.squares[ty][tx].parent = current;
       heappercolateup(squares[ty][tx].position);
      }
     }
    }
   }
   this.map[current.y][current.x] |= closed_mask;
  }
  return null;
}

private byte calculateh(byte y, byte x) {
  return (byte) (orthogonal_cost * (math.abs(this.lend.y - y) + math
    .abs(this.lend.x - x)));
}

public void openlistinsert(byte ty, byte tx, byte g, square parent) {
  this.squares[ty][tx] = new square(ty, tx, g, calculateh(ty, tx));
  this.squares[ty][tx].parent = parent;
  heapinsert(this.squares[ty][tx]);
  this.map[ty][tx] |= open_mask;
}

public square openlistremove() {
  square temp = heapdeletemin();
  this.map[temp.y][temp.x] |= open_mask;
  this.squares[temp.y][temp.x] = null;
  return temp;
}

// binary heap
public void heappercolateup(int position) {
  if (position <= this.heapsize) {
   while (position > 1) {
    if (this.heaptree[position].f < this.heaptree[position / 2].f) {
     square temp = this.heaptree[position];
     this.heaptree[position / 2].position = position;
     this.heaptree[position] = this.heaptree[position / 2];
     temp.position = position / 2;
     this.heaptree[position / 2] = temp;
     position = position / 2;
    } else
     return;
   }
  }
}

public boolean heapinsert(square element) {
  if (this.heapsize == heaptree.length - 1 || element == null) {
   return false;
  }

  this.heapsize++;
  int hole = this.heapsize;

  while (hole > 1 && element.f < this.heaptree[hole / 2].f) {
   this.heaptree[hole / 2].position = hole;
   this.heaptree[hole] = this.heaptree[hole / 2];
   hole = hole / 2;
  }

  this.heaptree[hole] = element;
  this.heaptree[hole].position = hole;

  return true;
}

public square heapdeletemin() {
  if (this.heapsize == 0) {
   return null;
  }

  square smallest = this.heaptree[1];
  this.heaptree[this.heapsize].position = 1;
  this.heaptree[1] = this.heaptree[this.heapsize];
  this.heaptree[this.heapsize] = null;
  this.heapsize--;

  int current = 1;
  int child;
  while (2 * current <= this.heapsize) {
   child = 2 * current;

   if (child != this.heapsize
     && this.heaptree[child].f > this.heaptree[child + 1].f) {
    child++;
   }

   if (this.heaptree[current].f > this.heaptree[child].f) {
    square temp = this.heaptree[current];
    this.heaptree[child].position = current;
    this.heaptree[current] = this.heaptree[child];
    temp.position = child;
    this.heaptree[child] = temp;
   } else {
    break;
   }
   current = child;
  }

  return smallest;
}

}

class square {
public byte f;

public byte g;

public byte h;

public int position; // heap position

public byte y;

public byte x;

public square parent;

public square(byte y, byte x, byte g, byte h) {
  this.y = y;
  this.x = x;

  if (!(g == 0 && h == 0)) {
   this.g = g;
   this.h = h;
   this.f = (byte) (this.g + this.h);
  }
}

public void setg(byte g) {
  this.g = g;
  this.f = (byte) (this.g + this.h);
}
}

 
 
上一篇: 候捷谈java反射机制    下一篇: 使用netbeans ide 5.0解决java me开发中的设备分裂问题
  相关文档
java咖啡馆(4)——品味第一杯咖啡 11-16
制作可以执行的jar文件包及jar命令详解 11-17
技巧实例:如何在.net中访问mysql数据库 (1) 09-25
java 学习之路 11-17
java调试技术 11-17
jmeter技巧集锦 11-17
java语言深入:对java.lang的研究上 11-17
对于java的打印问题 11-17
java的中文编程配置心得 11-17
struts原理、开发及项目实施 11-17
新手学堂:几个著名java开源缓存框架介绍 06-16
全面研读ejb 2.0(3) 11-17
java核心代码例程之:datagramclientdemo.java 11-17
在 jbuilder 中使用 log4j 11-17
java的声音处理介绍 11-17
国强-symix企业资源计划(erp) 11-16
this 关键字的理解--java学习笔记 11-17
jboss中myfaces与sitemesh的集成 11-17
struts+hibernate开发(源代码) 11-17
java语言深入:对 java.lang 的研究下 11-17
返回首页 | 关于我们 | J网章程 | JSP空间合租 | 客服中心 | 免责声明 | 常见问题 | 参观机房
本站主机空间代理至厦门市华众网络科技有限公司
《中华人民共和国增值电信业务经营许可证》
编号:闽B2-20050079
@2005-2008福建JSP技术网 版权所有 闽ICP备05000928号
技术电话:13616026886
邮箱:admin@fjjsp.com 站长QQ,点击这里给我发消息