// Livreur: Ebauche de Robot Livreur pour Projet ift6802 // // Version 0.1 // Jean Vaucher // 13 mars 2003 // ============================================================================= import java.util.*; import jade.util.leap.List; import jade.util.leap.ArrayList; import jade.content.*; import jade.content.onto.*; import jade.content.onto.basic.*; import jade.content.lang.*; import jade.content.lang.sl.*; import jade.core.*; import jade.core.behaviours.*; import jade.lang.acl.ACLMessage; import jade.lang.acl.MessageTemplate; import jade.domain.FIPAAgentManagement.*; import jade.domain.*; import jade.proto.*; import java.awt.Point; //cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc // class LIVREUR: //cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc public class Livreur extends JVAgent implements Constants6802 { AID control; DFAgentDescription dfd; ServiceDescription sd; int id = 0; Point position = new Point(0,0), lastPos = new Point(-1,-1), dest ; int etat = 0, dir = 8; int NJOURS, NHEURES; ArrayList contracts = new ArrayList(); ArrayList load = new ArrayList(); protected void setup() { /** Registration with the DF */ sd = new ServiceDescription(); sd.setType( LIVREUR ); sd.setName("Speedy"); sd.setOwnership("Jean Vaucher"); register( sd ); control = getService( CONTROLEUR ); if ( control == null ) { System.out.println("Controleur est ABSENT... Demarrer Controleur avant les agents: "+ "\n"); } addBehaviour ( new HandleCtlMsg( this ) ); addBehaviour ( new Purchasing(this ) ); addBehaviour ( new HandlePickUps(this ) ); }// setup() String getID() { return "Livreur " + getLocalName() ; } //============================ BEHAVIOURS =============================== class HandleCtlMsg extends CyclicBehaviour { HandleCtlMsg( Agent a ) { super(a); } MessageTemplate InfoFromCtl = MessageTemplate.and( MessageTemplate.MatchPerformative(ACLMessage.INFORM), MessageTemplate.MatchSender( control )); public final void action() { ACLMessage msg, reply; msg = myAgent.receive( InfoFromCtl ); if (msg != null ) { String s = msg.getContent() ; trace( "INFO <-CTL: " + s ); String atr [] = s.split("="); if ( atr[0].equals( "ID" )) { String par [] = atr[1].split(","); id = Integer.parseInt( par[0]); position = new Point( Integer.parseInt( par[1]), Integer.parseInt( par[2]) ); NJOURS = Integer.parseInt( par[3]); NHEURES = Integer.parseInt( par[4]); } else if ( atr[0].equals( "STATE" )) { // System.out.println("Update State: " + atr[1]); majEtat( atr[1] ); reply = msg.createReply(); reply.setPerformative(ACLMessage.REQUEST); reply.setContent( "MOVE=" + pickMove()); send(reply); } // System.out.println("Update State"); } block(); } } //======================================================================= // -- C O N T R A C T N E T P U R C H A S I N G -- //======================================================================= MessageTemplate template = MessageTemplate.and( MessageTemplate.MatchProtocol(FIPANames.InteractionProtocol. FIPA_CONTRACT_NET), MessageTemplate.MatchPerformative(ACLMessage.CFP) ); class Purchasing extends ContractNetResponder { int proposal=0; public Purchasing ( Agent a ) { super( a, template ); } protected ACLMessage prepareResponse(ACLMessage cfp) throws NotUnderstoodException, RefuseException { // System.out.println("A_"+getLocalName()+" receives CFP from " // +cfp.getSender().getLocalName()+": "+cfp.getContent()); String msg = cfp.getContent(); String atr [] = msg.split("="); if ( atr[0].equals( "CONTRACT" ) && contracts.size() < 4 ) { // We provide a proposal proposal = (int) (Math.random() * 10); ACLMessage propose = cfp.createReply(); propose.setPerformative(ACLMessage.PROPOSE); propose.setContent(String.valueOf(proposal)); return propose; } else throw new RefuseException("evaluation-failed"); } protected ACLMessage prepareResultNotification( ACLMessage cfp, ACLMessage propose, ACLMessage accept) throws FailureException { try { Contrat contrat = (Contrat)accept.getContentObject() ; contracts.add( contrat ); System.out.println("-- " +getLocalName()+" $"+ proposal + " <- " + contrat); // System.out.println("Agent "+getLocalName()+" accept:" + contrat); } catch (Exception ex) { System.out.println("=== Problem CN Purchase"); ex.printStackTrace(); } return null; } } // =============================================================== // HandlePickUps // =============================================================== class HandlePickUps extends CyclicBehaviour { HandlePickUps( Agent a ) { super(a); } MessageTemplate mt = MessageTemplate.and( MessageTemplate.MatchPerformative(ACLMessage.ACCEPT_PROPOSAL), MessageTemplate.MatchProtocol( PICKUP )); public final void action() { ACLMessage msg = myAgent.receive( mt ); if (msg != null ) { try { Contrat contrat = (Contrat)msg.getContentObject() ; load.add( contrat ); if (contracts.remove( contrat )) System.out.println("=========== Remove worked"); etat = DELIVER; dest = ((Contrat) load.get(0)).dest ; System.out.println(" --- Pickup:" + contrat); } catch (Exception ex) { trace("=== Problem receiving Contract"); ex.printStackTrace(); } } block(); } } // =============================================================== // Methodes // =============================================================== void majEtat( String msg ) { String par [] = msg.split(","); /* par[0] = jour par[1] = heure par[2] = x par[3] = y par[4] = environs */ int x = Integer.parseInt( par[2]); int y = Integer.parseInt( par[3]); position.setLocation(x,y); } // ------------------------------------------------------------- int pickMove() // ------------------------------------------------------------- { Contrat c, c1, next; int newDir = dir; trace( " Move: " + contracts.size() + ", " + load.size() + (dest==null ? " no dest. " : " -> [" + dest.x + "-" + dest.y+ "]") ); if ( position.equals(lastPos) ) { newDir = rnd.nextInt( 8 ); } else if (dest == null) { if ( contracts.isEmpty() ) newDir = dir; else { etat = FETCH; c = (Contrat) contracts.get(0) ; dest = c.pos; newDir = dirOf( position, dest); trace(newDir + " -> [" + dest.x + "-" + dest.y+ "]" ); } } else if (position.equals( dest)) { if( etat == FETCH ) { c = (Contrat) contracts.remove(0) ; load.add( c ); c1 = (Contrat) load.get(0) ; etat = DELIVER; dest = c1.dest; newDir = dirOf( position, dest ); } else if( etat == DELIVER ) { ACLMessage msg = newMsg( ACLMessage.REQUEST, "LIVRER", control); send(msg); for (int i = 0; i < load.size(); ) { c = (Contrat) load.get(i); if( c.dest . equals( position)) { load.remove( i ); // r.argent += c.value; } else i++; } if ( ! load.isEmpty() ) { etat = DELIVER; dest = ((Contrat) load.get(0)).dest ; } else if (! contracts.isEmpty() ) { etat = FETCH; dest = ((Contrat) contracts.get(0)).pos ; } else { etat = WANDER; dest = null; } newDir = ( dest==null ? rnd.nextInt( 8 ) : dirOf( position, dest) ); } } else newDir = dirOf( position, dest); lastPos.setLocation( position ); dir = newDir; trace(" dir: " +dir ); return newDir; } // ================ Utilitaires "geometriques" ====================== Point nextPoint( Point p, int dir) { int x=p.x, y = p.y; int x2=x, y2=y; switch (dir) { case 0: x2=x-1; y2=y-1; break; case 1: x2=x ; y2=y-1; break; case 2: x2=x+1; y2=y-1; break; case 3: x2=x+1; y2=y; break; case 4: x2=x+1; y2=y+1; break; case 5: x2=x ; y2=y+1; break; case 6: x2=x-1; y2=y+1; break; case 7: x2=x-1; y2=y ; break; } return new Point(x2,y2); } static int newX ( int x, int dir ) { switch (dir) { case 0: case 6: case 7: return x-1; case 2: case 3: case 4: return x+1; } return x; } static int newY ( int y, int dir ) { switch (dir) { case 0: case 1: case 2: return y-1; case 4: case 5: case 6: return y+1; } return y; } static int inDir(Point p2, Point p1, int dir) { int dx = p2.x-p1.x; int dy = p1.y-p2.y; switch (dir) { case 0: return dy-dx; case 1: return dy; case 2: return dx+dy; case 3: return dx; case 4: return dx-dy; case 5: return -dy; case 6: return -dx-dy; case 7: return -dx; } return 0; } int distance( Point p1, Point p2 ) { return Math.max( Math.abs(p1.x-p2.x), Math.abs(p1.y-p2.y)); } int dirOf( Point pos, Point p) { int dx = p.x-pos.x; int dy = pos.y-p.y; // Note <0,0> et en haut a gauche ! if (dx==0) { if (dy>0) return 1; if (dy<0) return 5; return 8; } else if (dx > 0 ) if (dy > 0) { if (2*dx<=dy) return 1; else if (dx<=2*dy) return 2; else return 3; } else { if (-2*dy<=dx ) return 3; else if (-dy<= 2*dx) return 4; else return 5; } // dx < 0 else { if (dy < 0) { if (dy <= 2*dx) return 5; else if (2*dy<=dx) return 6; else return 7; } else { if (dx<= -2*dy) return 7; else if (2*dx<= -dy) return 0; else return 1; } } } }//end Acheteur