Package cz.matfyz.aai.fantom.client

Source Code of cz.matfyz.aai.fantom.client.ClientRunner

/*
   This file is part of Fantom.

    Fantom is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Fantom is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Fantom.  If not, see <http://www.gnu.org/licenses/>.
*/
package cz.matfyz.aai.fantom.client;

import cz.matfyz.aai.fantom.game.Graph;
import cz.matfyz.aai.fantom.game.GraphReadOnly;
import cz.matfyz.aai.fantom.message.ClientType;
import cz.matfyz.aai.fantom.message.Message;
import cz.matfyz.aai.fantom.message.MessageMove;
import cz.matfyz.aai.fantom.message.MessageQuit;
import cz.matfyz.aai.fantom.message.MessageReady;
import cz.matfyz.aai.fantom.message.MessageStart;
import cz.matfyz.aai.fantom.message.MessageUpdate;
import cz.matfyz.aai.fantom.message.MessagingClientBase;
import cz.matfyz.aai.fantom.message.MessageMoveBase.ActorMove;
import cz.matfyz.aai.fantom.server.ProtocolException;
import cz.matfyz.aai.fantom.server.ServerException;

public class ClientRunner extends MessagingClientBase {
 
  /**
   * The user supplied agent that performs all the moves.
   */
  private Agent agent;
 
  /**
   * The game graph used by the client.
   */
  private Graph graph;
 
  /**
   * A read-only version of the graph, that is given to the clients.
   */
  private GraphReadOnly graphReadOnly;
 
  /**
   * Keeps track of whether the client already sent placement of
   * actors for the current game.
   */
  private boolean sentPlacement;
 
  /**
   * Processes the message 'update'. Updates the internal graph, and informs
   * the agent.
   *
   * @param msg the message to be processed.
   */
  protected void receiveUpdate(MessageUpdate msg) {
    graph.updateActors(msg);
   
    ActorMove[] moves = msg.getMoves().clone();
    for(int i = 0; i < moves.length; i++) {
      moves[i] = new ActorMove(graphReadOnly.getActor(moves[i].getActor().getId()),
                moves[i].getTargetNode(), moves[i].getTransportType());
    }
    agent.update(moves);
  }
 
  /**
   * Gets the movement for the current round from the agent, updates the internal
   * representation of the game, and sends a 'move' message to the server.
   *
   * @throws ServerException if the message to the server was not sent.
   */
  protected void sendMoves() throws ServerException {
    ActorMove[] moves;
    if(sentPlacement)
      moves = agent.move();
    else {
      moves = agent.place();
      sentPlacement = true;
    }
    MessageMove msg = new MessageMove(moves);
   
    sendMessage(msg);
   
    // Re-load the message for this graph
    msg = new MessageMove(graph, msg.serialize());
    graph.updateActors(msg);
  }
 
  /**
   * Gets placement of the actors from the agent, updates the internal representation
   * of the game, and sends a 'move' message to the server.
   *
   * @throws ServerException if the message to the server was not sent.
   */
  protected void sendPlacement() throws ServerException {
    ActorMove[] moves = agent.move();
    MessageMove msg = new MessageMove(moves);
   
    sendMessage(msg);
   
    msg = new MessageMove(graph, msg.serialize());
    graph.placeActors(msg);
  }
   
  /**
   * Runs the client using {@link #agent} for decision making.
   */
  public void run() throws ServerException {
    try {
      Message msg = null;
     
      setStreams(System.in, System.out, null);
     
      msg = new MessageReady(agent.getName(), agent.getClientType());
      sendMessage(msg);
     
      tournament_loop:
      while(true) {
        msg = receiveMessage(null);
        if(msg instanceof MessageStart) {
          this.graph = ((MessageStart)msg).getGraph();
          this.graphReadOnly = new GraphReadOnly(this.graph);
          agent.start(graphReadOnly);
         
          sentPlacement = false;
         
          if(agent.getClientType() == ClientType.DETECTIVE)
            sendMoves();
         
          while(true) {
            msg = receiveMessage(graph);
            if(!(msg instanceof MessageUpdate))
              throw new ProtocolException(String.format("Message 'update' was expected, got '%s'", msg.getMessageType()), null);

            MessageUpdate msgUpdate = (MessageUpdate)msg;
           
            // Update the agent, if nobody did win the game in the last round, or if there
            // is information about movements of the other agent (e.g. about the movement
            // of the detectives, that captured the phantom, or the movement of the phantom
            // that commited suicide).
            if(msgUpdate.getWinner() == null || msgUpdate.getMoves().length > 0)
              receiveUpdate(msgUpdate);
            // If there is a winner, end the round
            if(msgUpdate.getWinner() != null) {
              agent.end(msgUpdate.getWinner());
              continue tournament_loop;
            }
           
            sendMoves();
          }
        }
        else if(msg instanceof MessageQuit) {
          agent.quit();
          return;
        }
        else {
          throw new ProtocolException("Unexpected message type: " + msg.getMessageType(), null);
        }
      }
    }
    catch(Throwable e) {
      e.printStackTrace();
    }
  }
 
  /**
   * Creates a new client runner.
   *
   * @param agent the agent object used to make all the decisions.
   */
  public ClientRunner(Agent agent) {
    if(agent == null)
      throw new IllegalArgumentException("no agent was specified");
    this.agent = agent;
  }
}
TOP

Related Classes of cz.matfyz.aai.fantom.client.ClientRunner

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.