package nl.tudelft.bw4t.client.controller; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Set; import javax.swing.SwingUtilities; import org.apache.log4j.Logger; import eis.exceptions.EntityException; import eis.iilang.Identifier; import eis.iilang.Parameter; import eis.iilang.ParameterList; import eis.iilang.Percept; import nl.tudelft.bw4t.client.agent.HumanAgent; import nl.tudelft.bw4t.client.environment.RemoteEnvironment; import nl.tudelft.bw4t.client.gui.BW4TClientGUI; import nl.tudelft.bw4t.client.gui.menu.EntityComboModelProvider; import nl.tudelft.bw4t.map.view.ViewEPartner; /** * The Class ClientController. DOC What is this? */ public class ClientController implements EntityComboModelProvider { private static final Logger LOGGER = Logger .getLogger(ClientController.class); /** * The map controller used by this client controller. */ private final ClientMapController mapController; /** The other players. */ private final Set<String> otherPlayers = new HashSet<>(); /** The bot chat history. */ private final List<String> botChatHistory = new LinkedList<>(); /** The epartner chat history. */ private final List<String> epartnerChatHistory = new LinkedList<>(); /** The human agent. */ private HumanAgent humanAgent; /** The to be performed action. */ private List<Percept> toBePerformedAction = new LinkedList<>(); /** The environment which should be read. */ private final RemoteEnvironment environment; /** * A reference to the client gui attached to this controller. */ private BW4TClientGUI gui = null; /** * Instantiates a new client controller. * * @param env * the environment * @param entityId * the entity id */ public ClientController(RemoteEnvironment env, String entityId) { environment = env; mapController = new ClientMapController(environment.getMap(), this); getMapController().getTheBot().setName(entityId); humanAgent = null; } /** * Instantiates a new client controller. * * @param env * the environment * @param entityId * the entity id * @param humanAgent * the human agent */ public ClientController(RemoteEnvironment env, String entityId, HumanAgent humanAgent) { this(env, entityId); this.humanAgent = humanAgent; } /** * Instantiate a default GUI. */ public void startupGUI() { this.setGui(new BW4TClientGUI(this)); } public ClientMapController getMapController() { return mapController; } public Set<String> getOtherPlayers() { return otherPlayers; } public List<String> getBotChatHistory() { return botChatHistory; } public List<String> getEpartnerChatHistory() { return epartnerChatHistory; } public boolean isHuman() { return humanAgent != null; } public HumanAgent getHumanAgent() { return humanAgent; } public RemoteEnvironment getEnvironment() { return environment; } /** * Add a new percept (containing an user action) to the list of percepts to * be returned in the next getPercept cycle * * @param toBePerformedAction */ public void addToBePerformedAction(Percept toBePerformedAction) { this.toBePerformedAction.add(toBePerformedAction); } protected void setToBePerformedAction(List<Percept> toBePerformedAction) { this.toBePerformedAction = toBePerformedAction; } /** * Method used for returning the next action that a human player wants the * bot to perform. This is received by the GOAL human bot, and then * forwarded to the entity on the server side. * * @return a percept containing the next action to be performed */ public List<Percept> getToBePerformedAction() { List<Percept> toBePerformedActionClone = toBePerformedAction; setToBePerformedAction(new LinkedList<Percept>()); return toBePerformedActionClone; } public BW4TClientGUI getGui() { return gui; } public void setGui(BW4TClientGUI gui) { this.gui = gui; } /** * Interprets the given list of {@link Percept}s and extracts the required * information. * * @param percepts * the list of percepts */ public void handlePercepts(Collection<Percept> percepts) { for (ViewEPartner ep : getMapController().getEPartners()) { ep.setVisible(false); } getMapController().clearVisible(); boolean clearedPositions = false; for (Percept percept : percepts) { String name = percept.getName(); List<Parameter> parameters = percept.getParameters(); if (name.equals("position") && !clearedPositions) { getMapController().clearVisiblePositions(); clearedPositions = true; } mapController.handlePercept(name, parameters); if ("player".equals(name)) { getOtherPlayers().add( ((Identifier) parameters.get(0)).getValue()); } else if ("message".equals(name)) { handleMessagePercept(parameters); } } } /** * Handles the message percept parameters. * * @param parameters * the parameters given to the message percept */ private void handleMessagePercept(List<Parameter> parameters) { ParameterList parameterList = (ParameterList) parameters.get(0); Iterator<Parameter> iterator = parameterList.iterator(); String sender = ((Identifier) iterator.next()).getValue(); String message = ((Identifier) iterator.next()).getValue(); if (message.contains("I want to go") || message.contains("You forgot me")) { getEpartnerChatHistory().add(sender + ": " + message); } else { getBotChatHistory().add(sender + ": " + message); } updateGUI(); } /** * the update the client GUI. */ protected void updateGUI() { BW4TClientGUI currentGui = this.getGui(); if (currentGui != null) { currentGui.update(); } } /** * stop the controller and dispose the GUI. */ public void stop() { mapController.setRunning(false); if (this.getGui() != null) { final BW4TClientGUI theGUI = gui; // copy for in Runnable setGui(null); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { theGUI.dispose(); } }); } } /** * Send paramenters to the GUI to be displayed in the chat window * * @param parameters * @return a null percept as no real percept should be returned */ public Percept sendToGUI(List<Parameter> parameters) { if (this.getGui() != null) { return this.getGui().sendToGUI(parameters); } return null; } @Override public Collection<String> getEntities() { Collection<String> ents = getEnvironment().getEntities(); Collection<String> ret = new ArrayList<>(ents.size()); String me = getMapController().getTheBot().getName(); for (String entity : ents) { try { if (!me.equals(entity) && !"epartner".equals(getEnvironment().getType(entity))) { ret.add(entity); } } catch (EntityException e) { LOGGER.warn("Unable to get the type of entity: " + entity, e); } } return ret; } }