Java tutorial
package geniuswebsocket; /* * socket.io-java-client Test.java * * Copyright (c) 2012, Enno Boland * socket.io-java-client is a implementation of the socket.io protocol in Java. * * See LICENSE file for more information */ import java.io.IOException; import java.util.*; import java.util.logging.Level; import io.socket.IOAcknowledge; import io.socket.IOCallback; import io.socket.SocketIO; import io.socket.SocketIOException; import negotiator.ActionListener; import negotiator.Agent; import negotiator.AgentID; import negotiator.Domain; import negotiator.WorldInformation; import negotiator.actions.*; import negotiator.exceptions.NegotiatorException; import negotiator.tournament.VariablesAndValues.AgentParamValue; import negotiator.tournament.VariablesAndValues.AgentParameterVariable; import negotiator.utility.UtilitySpace; import org.json.*; import agents.biu.KBAgent; /** * A socket.io client that negotiates with humans. * * @author Erel Segal-Halevi * @since 2013-02 */ public class NegotiationClient implements IOCallback, Cloneable { protected String roleOfThisAgent, roleOfOtherPlayer; protected AgentID agentIdOfThisAgent, agentIdOfOtherPlayer; /** * socket for connecting to the Node.js negotiation server: */ protected SocketIO negotiationSocket; /** * agent for strategic negotiation */ protected Agent agent; /** * Genius negotiation domain */ protected Domain domain; /** * full URL (http://host:port) of the socket.io server that handles the negotiation. */ protected String serverUrl; /** * name of the game-class to join - from the games available on the game-server */ protected String gameType; private String personalityOfThisAgent; /** * @param domainFile full path to the Genius XML file with the domain data. * @param serverUrl full URL (http://host:port) of the socket.io game-server that handles the negotiation. * @param gameType name of the game-class to join - from the games available on the game-server. * @throws Exception */ public NegotiationClient(Domain domain, String serverUrl, String gameType, String roleOfThisAgent, String personalityOfThisAgent, String roleOfOtherPlayer) { this.domain = domain; this.serverUrl = serverUrl; this.gameType = gameType; this.roleOfThisAgent = roleOfThisAgent; this.roleOfOtherPlayer = roleOfOtherPlayer; this.personalityOfThisAgent = personalityOfThisAgent; } @Override public NegotiationClient clone() { return new NegotiationClient(domain, serverUrl, gameType, roleOfThisAgent, personalityOfThisAgent, roleOfOtherPlayer); } public void start() throws JSONException, IOException, NegotiatorException { initializeAgent(roleOfThisAgent, personalityOfThisAgent, roleOfOtherPlayer); negotiationSocket = new SocketIO(); negotiationSocket.connect(serverUrl, this); String userid = "Java " + new Date().toString() + " " + (int) (Math.random() * 1000); System.out.println(gameType + " new client " + userid + " waiting"); negotiationSocket.emit("start_session", new JSONObject().put("userid", userid).put("gametype", gameType).put("role", roleOfThisAgent)); } BidAction partnerLatestBidAction = null, ourLatestBidAction = null; /** * @throws IOException * @throws NegotiatorException * @see negotiator.protocol.asyncoffers.AsyncOffersProtocol#runNegotiationSession * @see negotiator.protocol.asyncoffers.AsyncOffersBilateralAtomicNegoSession#run * @see negotiator.protocol.Protocol#loadWorldInformation */ protected void initializeAgent(String role, String personality, String partnerRole) throws IOException, NegotiatorException { agentIdOfThisAgent = new AgentID(role); agentIdOfOtherPlayer = new AgentID(partnerRole); agent = new KBAgent(); agent.setName(role); agent.setAgentID(agentIdOfThisAgent); /* handle actions from our agent to the partner */ agent.setActionListener(new ActionListener() { @Override public void actionSent(Action action) { if (action instanceof BidAction) ourLatestBidAction = (BidAction) action; try { JSONObject jsonActions = JsonToGeniusBridge.geniusActionToJsonObject(action, domain); System.out.println(gameType + " agent says: " + jsonActions); negotiationSocket.emit("negoactions", jsonActions); } catch (JSONException e) { sayToPartner("My strategic agent said something I didn't understand: " + agentIdOfThisAgent); } } }); int sessionNumber = 1; int sessionTotalNumber = 1; Date startTime = new Date(); Integer totalTimeSeconds = 30 * 60; Integer turnLengthSeconds = 2 * 60; HashMap<AgentParameterVariable, AgentParamValue> agentParams = new HashMap<AgentParameterVariable, AgentParamValue>(); UtilitySpace agentUtilitySpace = domain.getUtilitySpace(role.toLowerCase(), personality); WorldInformation agentWorldInformation = domain.getAllUtilitySpaces(partnerRole.toLowerCase()); agent.internalInit(sessionNumber, sessionTotalNumber, startTime, totalTimeSeconds, turnLengthSeconds, agentUtilitySpace, agentParams, agentWorldInformation); agent.init(); } @Override public void onConnect() { System.out.println("NegotiationClient Connection established."); } @Override public void onMessage(JSONObject arg0, IOAcknowledge ack) { try { System.out.println("NegotiationClient receives an object: " + arg0.toString(2)); } catch (JSONException e) { e.printStackTrace(); } } @Override public void onMessage(String data, IOAcknowledge ack) { System.out.println("NegotiationClient receives a message: " + data); } @Override public void onError(SocketIOException socketIOException) { System.out.println("NegotiationClient receives an error:"); socketIOException.printStackTrace(); } @Override public void onDisconnect() { System.out.println("NegotiationClient Connection terminated."); } /* Handle actions from the partner or from the server to our agent */ @Override public void on(String event, IOAcknowledge ack, Object... args) { System.out.println(gameType + " NegotiationClient receives event '" + event + "' arg0=" + args[0]); try { if (event.equals("status")) { // status sent by the server: JSONObject arg0 = (JSONObject) args[0]; if (arg0.get("key").equals("phase") && arg0.get("value").equals("")) { System.out.println(" " + gameType + " game starts - launching a new client!"); final NegotiationClient newClient = clone(); new Thread() { public void run() { try { newClient.start(); } catch (JSONException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (NegotiatorException e) { e.printStackTrace(); } } }.start(); } } else if (event.equals("EndTurn")) { int turnsFromStart = (Integer) args[0]; Action theAction = new EndTurn(turnsFromStart); agent.ReceiveMessage(theAction); } else if (event.equals("negoactions")) { // offer created by the partner (usually with menus GUI): onPartnerNegoActions(args[0]); } else if (event.equals("announcement")) { JSONObject arg0 = (JSONObject) args[0]; String speaker = (String) arg0.get("id"); String action = (String) arg0.get("action"); Object msg = arg0.get("msg"); // can be either a String or a JSON object boolean you = (Boolean) arg0.get("you"); System.out.println( " " + gameType + " " + speaker + (you ? " (you)" : "") + ": " + action + " " + msg); if (!you) { if (action.equals("Connect")) onPartnerConnect(); else if (action.equals("Disconnect")) onPartnerDisconnect(); } } } catch (Exception e) { e.printStackTrace(); } } /* * Negotiation-specific event handlers: */ public void onPartnerConnect() { sayToPartner("Hello! I am the " + agentIdOfThisAgent); } NaturalLanguageCollection replyToAccept = new NaturalLanguageCollection("Great, so we can sign the agreement", "I am happy that you agree", "It is a pleasure doing business with you"); NaturalLanguageCollection replyToReject = new NaturalLanguageCollection("Too bad you disagree", "Why did you reject my offer?", "This is a good offer, think about it again"); NaturalLanguageCollection replyToGreet = new NaturalLanguageCollection("Hello", "Hi", "Nice to meet you"); /** * The (human) partner sent some actions - forward them to the agent. * @param json a JSON object that represents the actions. */ public void onPartnerNegoActions(Object actions) { System.out.println(" " + gameType + " partner actions: " + actions); try { if (!(actions instanceof JSONObject)) { sayToPartner( "I didn't understand what you meant to say - I got a wrong-format action list: " + actions); return; } JSONObject actionsJson = (JSONObject) actions; if (!(actionsJson.keys().hasNext())) { sayToPartner( "I didn't understand what you meant to say - I got an empty action list: " + actionsJson); return; } List<Action> actionsGenius = JsonToGeniusBridge.jsonObjectToGeniusAction(actionsJson, domain, agentIdOfOtherPlayer, /*bidTime=*/null, ourLatestBidAction, partnerLatestBidAction); System.out.println(" " + gameType + " partner actions in Genius: " + actionsGenius); boolean actionIdentified = false; for (Action action : actionsGenius) { try { agent.ReceiveMessage(action); } catch (Exception ex) { sayToPartner("I could not handle the action '" + action + " because: " + ex + "!"); ex.printStackTrace(); } if (action instanceof BidAction) partnerLatestBidAction = (BidAction) action; if (action instanceof Accept) sayToPartner(replyToAccept.randomString()); if (action instanceof Reject) sayToPartner(replyToReject.randomString()); actionIdentified = true; } if (actionsJson.has("Greet")) { sayToPartner(replyToGreet.randomString()); actionIdentified = true; } if (!actionIdentified) { sayToPartner("I didn't understand what you meant to say - I couldn't identify any actions in: " + actionsJson); return; } } catch (NegotiatorException ex) { sayToPartner(ex.getMessage() + "!"); } catch (Exception ex) { sayToPartner("I could not understand you because: " + ex + "!"); ex.printStackTrace(); } } // onPartnerNegoActions public void onPartnerAccept() { agent.ReceiveMessage(new Accept()); } public void onPartnerReject() { agent.ReceiveMessage(new Reject()); } public void onPartnerQuit() { agent.ReceiveMessage(new EndNegotiation()); } public void onPartnerDisconnect() { sayToPartner("Bye!"); } public void sayToPartner(String message) { negotiationSocket.emit("message", message); } /* * Main program: */ private static String thisClassName = Thread.currentThread().getStackTrace()[1].getClassName(); public static void main(String[] args) throws Exception { if (args.length < 2) { System.err.println("SYNTAX: " + thisClassName + " <path-to-domain-folder> <url-of-negotiation-server> <game-types>"); System.exit(1); } java.util.logging.Logger.getLogger("io.socket").setLevel(Level.WARNING); String pathToDomainFolder = args[0]; String serverUrl = args[1]; new NegotiationClient(new Domain(pathToDomainFolder + "/JobCandiate/JobCanDomain.xml"), serverUrl, "negomenus", "Candidate", "short-term", "Employer").start(); // Start the first client. It will launch new clients as the need arises. new NegotiationClient(new Domain(pathToDomainFolder + "/JobCandiate/JobCanDomain.xml"), serverUrl, "negonlp", "Candidate", "short-term", "Employer").start(); // Start the first client. It will launch new clients as the need arises. // NOTE: currently we cannot play other domains, because we don't have the KBAgent configuration file: AgentConfigBneighbours_deniz.cfg // new NegotiationClient( // new Domain(pathToDomainFolder+"/neighbours_alex_deniz/neighbours_domain.xml"), // serverUrl, // "negomenus_neighbours", "Alex", "A", "Deniz").start(); // Start the first client. It will launch new clients as the need arises. } }