private void addIfAllowed(AgentPosition position, ICollection <AgentPosition> positions) { if (allowedPositions.Contains(position)) { positions.Add(position); } }
public override bool Equals(object obj) { if (obj != null && GetType() == obj.GetType()) { AgentPosition other = (AgentPosition)obj; return((getX() == other.getX()) && (getY() == other.getY()) && (orientation == other.getOrientation())); } return(false); }
public ICollection <AgentPosition> getLocationsLinkedTo(AgentPosition fromLocation) { int x = fromLocation.getX(); int y = fromLocation.getY(); AgentPosition.Orientation orientation = fromLocation.getOrientation(); ICollection <AgentPosition> result = CollectionFactory.CreateQueue <AgentPosition>(); AgentPosition currentForwardNorth = new AgentPosition(x, y + 1, AgentPosition.Orientation.FACING_NORTH); AgentPosition currentForwardSouth = new AgentPosition(x, y - 1, AgentPosition.Orientation.FACING_SOUTH); AgentPosition currentForwardEast = new AgentPosition(x + 1, y, AgentPosition.Orientation.FACING_EAST); AgentPosition currentForwardWest = new AgentPosition(x - 1, y, AgentPosition.Orientation.FACING_WEST); AgentPosition currentNorth = new AgentPosition(x, y, AgentPosition.Orientation.FACING_NORTH); AgentPosition currentSouth = new AgentPosition(x, y, AgentPosition.Orientation.FACING_SOUTH); AgentPosition currentEast = new AgentPosition(x, y, AgentPosition.Orientation.FACING_EAST); AgentPosition currentWest = new AgentPosition(x, y, AgentPosition.Orientation.FACING_WEST); if (orientation.Equals(AgentPosition.Orientation.FACING_NORTH)) { addIfAllowed(currentForwardNorth, result); addIfAllowed(currentEast, result); addIfAllowed(currentWest, result); } else if (orientation.Equals(AgentPosition.Orientation.FACING_SOUTH)) { addIfAllowed(currentForwardSouth, result); addIfAllowed(currentEast, result); addIfAllowed(currentWest, result); } else if (orientation.Equals(AgentPosition.Orientation.FACING_EAST)) { addIfAllowed(currentNorth, result); addIfAllowed(currentSouth, result); addIfAllowed(currentForwardEast, result); } else if (orientation.Equals(AgentPosition.Orientation.FACING_WEST)) { addIfAllowed(currentNorth, result); addIfAllowed(currentSouth, result); addIfAllowed(currentForwardWest, result); } return(result); }
public AgentPosition askCurrentPosition(int t) { int locX = -1, locY = -1; for (int x = 1; x <= getCaveXDimension() && locX == -1; x++) { for (int y = 1; y <= getCaveYDimension() && locY == -1; y++) { if (ask(newSymbol(LOCATION, t, x, y))) { locX = x; locY = y; } } } if (locX == -1 || locY == -1) { throw new IllegalStateException("Inconsistent KB, unable to determine current room position."); } AgentPosition current = null; if (ask(newSymbol(FACING_NORTH, t))) { current = new AgentPosition(locX, locY, AgentPosition.Orientation.FACING_NORTH); } else if (ask(newSymbol(FACING_SOUTH, t))) { current = new AgentPosition(locX, locY, AgentPosition.Orientation.FACING_SOUTH); } else if (ask(newSymbol(FACING_EAST, t))) { current = new AgentPosition(locX, locY, AgentPosition.Orientation.FACING_EAST); } else if (ask(newSymbol(FACING_WEST, t))) { current = new AgentPosition(locX, locY, AgentPosition.Orientation.FACING_WEST); } else { throw new IllegalStateException("Inconsistent KB, unable to determine current room orientation."); } return(current); }
private ICollection <IAction> plan = CollectionFactory.CreateFifoQueue <IAction>(); // FIFOQueue /** * function HYBRID-WUMPUS-AGENT(percept) returns an action<br> * * @param percept * a list, [stench, breeze, glitter, bump, scream] * * @return an action the agent should take. */ public override IAction Execute(IPercept percept) { // TELL(KB, MAKE-PERCEPT-SENTENCE(percept, t)) kb.makePerceptSentence((AgentPercept)percept, t); // TELL the KB the temporal "physics" sentences for time t kb.tellTemporalPhysicsSentences(t); AgentPosition current = kb.askCurrentPosition(t); // safe <- {[x, y] : ASK(KB, OK<sup>t</sup><sub>x,y</sub>) = true} ISet <Room> safe = kb.askSafeRooms(t); // if ASK(KB, Glitter<sup>t</sup>) = true then if (kb.askGlitter(t)) { // plan <- [Grab] + PLAN-ROUTE(current, {[1,1]}, safe) + [Climb] ISet <Room> goals = CollectionFactory.CreateSet <Room>(); goals.Add(new Room(1, 1)); plan.Add(new Grab()); plan.AddAll(planRoute(current, goals, safe)); plan.Add(new Climb()); } // if plan is empty then // unvisited <- {[x, y] : ASK(KB, L<sup>t'</sup><sub>x,y</sub>) = false // for all t' ≤ t} ISet <Room> unvisited = kb.askUnvisitedRooms(t); if (plan.IsEmpty()) { // plan <- PLAN-ROUTE(current, unvisited ∩ safe, safe) plan.AddAll(planRoute(current, SetOps.intersection(unvisited, safe), safe)); } // if plan is empty and ASK(KB, HaveArrow<sup>t</sup>) = true then if (plan.IsEmpty() && kb.askHaveArrow(t)) { // possible_wumpus <- {[x, y] : ASK(KB, ~W<sub>x,y</sub>) = false} ISet <Room> possibleWumpus = kb.askPossibleWumpusRooms(t); // plan <- PLAN-SHOT(current, possible_wumpus, safe) plan.AddAll(planShot(current, possibleWumpus, safe)); } // if plan is empty then //no choice but to take a risk if (plan.IsEmpty()) { // not_unsafe <- {[x, y] : ASK(KB, ~OK<sup>t</sup><sub>x,y</sub>) = // false} ISet <Room> notUnsafe = kb.askNotUnsafeRooms(t); // plan <- PLAN-ROUTE(current, unvisited ∩ not_unsafe, safe) plan.AddAll(planRoute(current, SetOps.intersection(unvisited, notUnsafe), safe)); } // if plan is empty then if (plan.IsEmpty()) { // plan PLAN-ROUTE(current, {[1,1]}, safe) + [Climb] ISet <Room> start = CollectionFactory.CreateSet <Room>(); start.Add(new Room(1, 1)); plan.AddAll(planRoute(current, start, safe)); plan.Add(new Climb()); } // action <- POP(plan) IAction action = plan.Pop(); // TELL(KB, MAKE-ACTION-SENTENCE(action, t)) kb.makeActionSentence(action, t); // t <- t+1 t = t + 1; // return action return(action); }
/** * * @param current * the agent's current position * @param possibleWumpus * a set of squares where we don't know that there isn't the * wumpus. * @param allowed * a set of squares that can form part of the route * * @return the sequence of actions to reach the nearest square that is in * line with a possible wumpus position. The last action is a shot. */ public ICollection <IAction> planShot(AgentPosition current, ISet <Room> possibleWumpus, ISet <Room> allowed) { ISet <AgentPosition> shootingPositions = CollectionFactory.CreateSet <AgentPosition>(); foreach (Room p in possibleWumpus) { int x = p.getX(); int y = p.getY(); for (int i = 1; i <= kb.getCaveXDimension(); i++) { if (i < x) { shootingPositions.Add(new AgentPosition(i, y, AgentPosition.Orientation.FACING_EAST)); } if (i > x) { shootingPositions.Add(new AgentPosition(i, y, AgentPosition.Orientation.FACING_WEST)); } if (i < y) { shootingPositions.Add(new AgentPosition(x, i, AgentPosition.Orientation.FACING_NORTH)); } if (i > y) { shootingPositions.Add(new AgentPosition(x, i, AgentPosition.Orientation.FACING_SOUTH)); } } } // Can't have a shooting position from any of the rooms the wumpus could // reside foreach (Room p in possibleWumpus) { foreach (AgentPosition.Orientation orientation in AgentPosition.Orientation.values()) { shootingPositions.Remove(new AgentPosition(p.getX(), p.getY(), orientation)); } } ISet <Room> shootingPositionsArray = CollectionFactory.CreateSet <Room>(); foreach (AgentPosition tmp in shootingPositions) { shootingPositionsArray.Add(new Room(tmp.getX(), tmp.getY())); } ICollection <IAction> actions = planRoute(current, shootingPositionsArray, allowed); AgentPosition newPos = current; if (actions.Size() > 0) { newPos = ((Forward)actions.Get(actions.Size() - 1)).getToPosition(); } while (!shootingPositions.Contains(newPos)) { TurnLeft tLeft = new TurnLeft(newPos.getOrientation()); newPos = new AgentPosition(newPos.getX(), newPos.getY(), tLeft.getToOrientation()); actions.Add(tLeft); } actions.Add(new Shoot()); return(actions); }
/** * Returns a sequence of actions using A* Search. * * @param current * the agent's current position * @param goals * a set of squares; try to plan a route to one of them * @param allowed * a set of squares that can form part of the route * * @return the best sequence of actions that the agent have to do to reach a * goal from the current position. */ public ICollection <IAction> planRoute(AgentPosition current, ISet <Room> goals, ISet <Room> allowed) { // Every square represent 4 possible positions for the agent, it could // be in different orientations. For every square in allowed and goals // sets we add 4 squares. ISet <AgentPosition> allowedPositions = CollectionFactory.CreateSet <AgentPosition>(); foreach (Room allowedRoom in allowed) { int x = allowedRoom.getX(); int y = allowedRoom.getY(); allowedPositions.Add(new AgentPosition(x, y, AgentPosition.Orientation.FACING_WEST)); allowedPositions.Add(new AgentPosition(x, y, AgentPosition.Orientation.FACING_EAST)); allowedPositions.Add(new AgentPosition(x, y, AgentPosition.Orientation.FACING_NORTH)); allowedPositions.Add(new AgentPosition(x, y, AgentPosition.Orientation.FACING_SOUTH)); } ISet <AgentPosition> goalPositions = CollectionFactory.CreateSet <AgentPosition>(); foreach (Room goalRoom in goals) { int x = goalRoom.getX(); int y = goalRoom.getY(); goalPositions.Add(new AgentPosition(x, y, AgentPosition.Orientation.FACING_WEST)); goalPositions.Add(new AgentPosition(x, y, AgentPosition.Orientation.FACING_EAST)); goalPositions.Add(new AgentPosition(x, y, AgentPosition.Orientation.FACING_NORTH)); goalPositions.Add(new AgentPosition(x, y, AgentPosition.Orientation.FACING_SOUTH)); } WumpusCave cave = new WumpusCave(kb.getCaveXDimension(), kb.getCaveYDimension(), allowedPositions); GoalTest <AgentPosition> goalTest = goalPositions.Contains; IProblem <AgentPosition, IAction> problem = new GeneralProblem <AgentPosition, IAction>(current, WumpusFunctionFunctions.createActionsFunction(cave), WumpusFunctionFunctions.createResultFunction(), goalTest); IToDoubleFunction <Node <AgentPosition, IAction> > h = new ManhattanHeuristicFunction(goals); ISearchForActions <AgentPosition, IAction> search = new AStarSearch <AgentPosition, IAction>( new GraphSearch <AgentPosition, IAction>(), h); SearchAgent <AgentPosition, IAction> agent; ICollection <IAction> actions = null; try { agent = new SearchAgent <AgentPosition, IAction>(problem, search); actions = agent.getActions(); // Search agent can return a NoOp if already at goal, // in the context of this agent we will just return // no actions. if (actions.Size() == 1 && actions.Get(0).IsNoOp()) { actions = CollectionFactory.CreateQueue <IAction>(); } } catch (Exception e) { throw e; } return(actions); }