/** * Get the best move. * * @param space The 2D space to move in. * @param sourcepos The source position. * @param eval The move evaluator. * @return The direction to go ('none', if no move at all is better than moving in any direction). */ public static String evaluateMoves(Grid2D space, IVector2 sourcepos, IMoveEvaluator eval) { String ret = null; Map moves = new HashMap(); moves.put(DIRECTION_NONE, new Vector2Int(sourcepos.getXAsInteger(), sourcepos.getYAsInteger())); moves.put( DIRECTION_LEFT, new Vector2Int(sourcepos.getXAsInteger() - 1, sourcepos.getYAsInteger())); moves.put( DIRECTION_RIGHT, new Vector2Int(sourcepos.getXAsInteger() + 1, sourcepos.getYAsInteger())); moves.put( DIRECTION_UP, new Vector2Int(sourcepos.getXAsInteger(), sourcepos.getYAsInteger() - 1)); moves.put( DIRECTION_DOWN, new Vector2Int(sourcepos.getXAsInteger(), sourcepos.getYAsInteger() + 1)); // Get max value of positions not filled with obstacles. double maxval = Double.NEGATIVE_INFINITY; for (Iterator it = moves.keySet().iterator(); it.hasNext(); ) { IVector2 pos = (IVector2) moves.get(it.next()); Collection obstacles = space.getSpaceObjectsByGridPosition(pos, "obstacle"); if (obstacles != null && !obstacles.isEmpty()) { it.remove(); } else { maxval = Math.max(maxval, eval.evaluateMove(pos)); } } // Retain only the best move(s). for (Iterator it = moves.keySet().iterator(); it.hasNext(); ) { IVector2 pos = (IVector2) moves.get(it.next()); if (eval.evaluateMove(pos) < maxval) { it.remove(); } } // System.out.println("Moves: "+moves); // Chose randomly one of the remaining equally good moves. if (moves.size() > 0) { int chosen = (int) (Math.random() * moves.size()); Iterator it = moves.keySet().iterator(); for (int i = 0; i <= chosen; i++) { ret = (String) it.next(); } } return ret; }
/** * Executes the task. Handles exceptions. Subclasses should implement doExecute() instead. * * @param space The environment in which the task is executing. * @param obj The object that is executing the task. * @param progress The time that has passed according to the environment executor. */ public void execute( IEnvironmentSpace space, ISpaceObject obj, long progress, IClockService clock) { ISpaceObject target = (ISpaceObject) getProperty(PROPERTY_TARGET); IVector2 loc = (IVector2) obj.getProperty(Space2D.PROPERTY_POSITION); IVector2 tloc = (IVector2) target.getProperty(Space2D.PROPERTY_POSITION); if (!loc.equals(tloc)) throw new RuntimeException("Not at location: " + obj + ", " + target); int ore = ((Number) target.getProperty(AnalyzeTargetTask.PROPERTY_ORE)).intValue(); int capacity = ((Number) target.getProperty(PROPERTY_CAPACITY)).intValue(); capacity += Math.min(ore, (time + progress) / TIME); ore -= Math.min(ore, (time + progress) / TIME); time = (time + progress) % TIME; target.setProperty(AnalyzeTargetTask.PROPERTY_ORE, new Integer(ore)); target.setProperty(PROPERTY_CAPACITY, new Integer(capacity)); if (ore == 0) { setFinished(space, obj, true); } }
/** * Get the possible moves. * * @param space The 2D space to move in. * @param sourcepos The source position. * @return The directions to go (i.e. all possible directions excluding 'none' or an array with * only 'none'). */ public static String[] getPossibleDirections(Grid2D space, IVector2 sourcepos) { Map moves = new HashMap(); moves.put( DIRECTION_LEFT, new Vector2Int(sourcepos.getXAsInteger() - 1, sourcepos.getYAsInteger())); moves.put( DIRECTION_RIGHT, new Vector2Int(sourcepos.getXAsInteger() + 1, sourcepos.getYAsInteger())); moves.put( DIRECTION_UP, new Vector2Int(sourcepos.getXAsInteger(), sourcepos.getYAsInteger() - 1)); moves.put( DIRECTION_DOWN, new Vector2Int(sourcepos.getXAsInteger(), sourcepos.getYAsInteger() + 1)); for (Iterator it = moves.keySet().iterator(); it.hasNext(); ) { IVector2 pos = (IVector2) moves.get(it.next()); Collection obstacles = space.getSpaceObjectsByGridPosition(pos, "obstacle"); if (obstacles != null && !obstacles.isEmpty()) { it.remove(); } } return moves.isEmpty() ? new String[] {DIRECTION_NONE} : (String[]) moves.keySet().toArray(new String[moves.size()]); }
/** * Performs the action. * * @param parameters parameters for the action * @param space the environment space * @return action return value */ public Object perform(Map parameters, IEnvironmentSpace space) { // System.out.println("move action: "+parameters); Grid2D grid = (Grid2D) space; IComponentIdentifier actor = (IComponentIdentifier) parameters.get(ISpaceAction.ACTOR_ID); String direction = (String) parameters.get(PARAMETER_DIRECTION); ISpaceObject avatar = grid.getAvatar(actor); if (null == space.getSpaceObject(avatar.getId())) { throw new RuntimeException("No such object in space: " + avatar); } IVector2 pos = (IVector2) avatar.getProperty(Space2D.PROPERTY_POSITION); boolean skip = false; if (DIRECTION_LEFT.equals(direction)) { pos = new Vector2Int(pos.getXAsInteger() - 1, pos.getYAsInteger()); } else if (DIRECTION_RIGHT.equals(direction)) { pos = new Vector2Int(pos.getXAsInteger() + 1, pos.getYAsInteger()); } else if (DIRECTION_UP.equals(direction)) { pos = new Vector2Int(pos.getXAsInteger(), pos.getYAsInteger() - 1); } else if (DIRECTION_DOWN.equals(direction)) { pos = new Vector2Int(pos.getXAsInteger(), pos.getYAsInteger() + 1); } else if (DIRECTION_NONE.equals(direction)) { skip = true; } else { throw new RuntimeException("Unknown move direction: " + direction); } if (!skip) { Collection obstacles = grid.getSpaceObjectsByGridPosition(pos, "obstacle"); if (obstacles != null && !obstacles.isEmpty()) { throw new RuntimeException( "Cannot move '" + direction + "' due to obstacles: " + obstacles); } // Preys can not "tunnel" through hunters, i.e. move from the field // where the hunter is now to the field where the hunter was before. if (avatar.getType().equals("prey")) { Collection hunters = grid.getSpaceObjectsByGridPosition( (IVector2) avatar.getProperty(Space2D.PROPERTY_POSITION), "hunter"); if (hunters != null) { pos = grid.adjustPosition(pos); // Hack!!! Position only converted in setPosition(). for (Iterator it = hunters.iterator(); it.hasNext(); ) { ISpaceObject hunter = (ISpaceObject) it.next(); if (pos.equals(hunter.getProperty(PROPERTY_LASTPOS))) { // System.out.println("Cannot move '"+direction+"' due to hunter: "+hunter); throw new RuntimeException( "Cannot move '" + direction + "' due to hunter: " + hunter); } } } } // Remember last position of hunter (required for detecting "tunneling"). else if (avatar.getType().equals("hunter")) { avatar.setProperty(PROPERTY_LASTPOS, avatar.getProperty(Space2D.PROPERTY_POSITION)); } grid.setPosition(avatar.getId(), pos); } return null; }