package robombs.game.ai; import robombs.game.model.*; import robombs.game.view.*; import com.threed.jpct.*; import java.util.*; public class TargetFinder { public TargetFinder() { } public GridPosition findTarget(Bot lpo, AStar as, MapMask mask, Level le, LocalBombManager lbm, List<SimpleVector> playerPos, int mode) { SimpleVector pos=new SimpleVector(lpo.getPosition()); GridPosition gp=mask.getGrid(pos.x, pos.z); int height=mask.getHeight(); int width=mask.getWidth(); int t=mask.getMaskAt(gp); boolean near=lbm.isTooClose(pos); int xp=gp.getX(); int yp=gp.getZ(); if ((t<0 || near) && mode!=Bot.NEW_TARGET_CAUSE_STUCK) { //System.out.println(mask); int i=1; GridPosition escapeTo=gp; do { // We are in danger, we have to escape to the nearest safe spot. for (int y=-i; y<=i; y++) { for (int x=-i; x<=i; x++) { int tt=mask.getMaskAt(x+xp, y+yp); if (tt>1) { // See, if there is a bomb in the way. If so, don't go that way... as.clear(); as.setDecisionMask(mask); AIGridPosition target=as.getPathToTarget(gp, new GridPosition(x+xp,y+yp)); if (target!=null) { GridPosition[] path=as.getPath(target); boolean ok=true; for (int ii=0; ii<path.length; ii++) { if (!path[ii].equals(gp) && (((mask.getMaskAt(path[ii])==-2 && lbm.getLocalBombAt(path[ii]).getValue()>LocalBombManager.VALUE_INACTIVE) || le.getCrateManager().hasCrateAt(path[ii], mask)))) { ok=false; break; } if (mask.getMaskAt(path[ii])<0) { // A blow/bomb on the way? Only cross it with a slight chance of 15%. if (Math.random()>0.15f) { ok=false; break; } } } if (ok && Math.random()>0.05f) { // Not always... return new GridPosition(x+xp,y+yp); } } } if (y>-i && y!=i && x==-i) { x=i-1; } } } i++; } while(i<5); return escapeTo; } else { if (mode==Bot.NEW_TARGET_CAUSE_STUCK) { // We are stuck. Only god knows, why this happens. We have to recover somehow... int i=1; do { // We are in danger, we have to escape to the nearest safe spot. for (int y=-i; y<=i; y++) { for (int x=-i; x<=i; x++) { int tt=mask.getMaskAt(x+xp, y+yp); if ((tt==-1 || tt==10 || t==5) && Math.random()>0.5f) { return new GridPosition(x+xp, y+yp); } } } i++; } while (i<4); } // Get the best target around a randomly choosen spot. If there is none, well...then don't move // look for a player first... if (Math.random()>0.3) { float mind=10000000; SimpleVector attack=null; for (SimpleVector p:playerPos) { float d=pos.calcSub(p).length(); if (d<mind) { mind=d; attack=p; } } if (attack!=null) { return mask.getGrid(attack.x, attack.z); } } // look for an item second... if (Math.random()>0.5f) { List<GridPosition> items=getItems(le); if (items!=null && items.size()>0) { // Go get it. return items.get((int)(Math.random()*items.size())); } } int max=0; GridPosition newPos=null; xp=(int)(Math.random()*width); yp=(int)(Math.random()*height); for (int y=-3; y<=3; y++) { for (int x=-3; x<=3; x++) { int tt=mask.getMaskAt(x+xp, y+yp); if (tt>max) { max=tt; newPos=new GridPosition(x+xp,y+yp); } } } return newPos; } } private List<GridPosition> getItems(Level le) { MapMask mask=le.getMask(); List<GridPosition> gps=null; int height=mask.getHeight(); int width=mask.getWidth(); for (int x=1; x<width; x++) { for (int y=1; y<height; y++) { int d=mask.getMaskAt(x, y); GridPosition gp=new GridPosition(x,y); if (MapMask.isItem(d) && !le.getCrateManager().hasCrateAt(gp, mask)) { if (gps==null) { gps=new ArrayList<GridPosition>(); } gps.add(gp); } } } return gps; } }