Buyers and Sellers

Seller Agent

A seller registers its service (selling whiskey) with the local DF agent, then adds a seller behavior.

public class Seller extends Agent {

    protected void setup() {

      DFAgentDescription dfd = new DFAgentDescription();
      dfd.setName(getAID());

      ServiceDescription service  = new ServiceDescription();
         service.setType( "whiskey" );
         service.setName( getLocalName() );

      try {
        DFAgentDescription list[] = DFService.search( this, dfd );
         if ( list.length > 0 ) DFService.deregister(this);
            dfd.addServices(service);
         DFService.register(this, dfd);
      } catch (FIPAException fe) {
         System.err.println(fe.getMessage());
      }
      addBehaviour(new SellerBehavior(this));
   }
}

Seller Behavior

Selling whiskey is a cyclic behavior. It blocks until it receives an appropriate message, then creates an appropriate reply and sends it after some delay:

class SellerBehavior extends CyclicBehaviour {
   MessageTemplate template =
      MessageTemplate.MatchPerformative( ACLMessage.QUERY_REF );
   ACLMessage reply;
   Random generator = new Random();
  
public SellerBehavior(Agent a) { super(a); }

   public void action() {
      int price = generator.nextInt(500);  // price per bottle
      int delay = generator.nextInt(100); // respond after delay

      ACLMessage msg = myAgent.receive(template);

      if (msg != null) {
         reply = msg.createReply();
         reply.setPerformative( ACLMessage.INFORM );
            reply.setContent("" + price);

            System.out.print(myAgent.getLocalName());
            System.out.print(" will offer $" + price + " to ");
            System.out.print(msg.getSender().getLocalName());
            System.out.println(" in " + delay + " ms");

            myAgent.addBehaviour(
            new DelayBehaviour(myAgent, delay) {
                  public void handleElapsedTimeout() {
                           myAgent.send(reply);
                    }
                    });
         } // if
         block();
     } // action
}

Buyer Agent

A buyer finds out which agents sell whiskey. It adds each one to the receivers list for a request for whiskey. It creates a sequential behavior consisting of a parallel behavior followed by a one shot behavior that prints the lowest bid. The parallel behavior consists of a buyer behavior for each seller:

public class Buyer extends Agent {
   int bestPrice = 9999999;
   ACLMessage bestOffer = null;
   protected void setup() {

      AID[] providers = DFUtils.searchDF(this, "whiskey");
      if (providers != null) {

         SequentialBehaviour seq = new SequentialBehaviour();
        ParallelBehaviour par =
            new ParallelBehaviour( ParallelBehaviour.WHEN_ALL );

        ACLMessage msg = new ACLMessage(ACLMessage.QUERY_REF);
        String id = "whiskey request";
        msg.setConversationId(id);
        msg.setContent( "how much?" );

         for(int i = 0; i < providers.length; i++) {
             msg.addReceiver(providers[i]);
             MessageTemplate template = MessageTemplate.and(
               MessageTemplate.MatchPerformative(ACLMessage.INFORM),
               MessageTemplate.MatchConversationId(id));
             par.addSubBehaviour(
               new BuyerBehavior(this, 2000, template));
             send(msg);
         } // for

         seq.addSubBehaviour( par );
         addBehaviour( seq );

         seq.addSubBehaviour(
            new OneShotBehaviour() {
               public void action() {
                  if (bestOffer != null)
                     System.out.println("Best Price $" + bestPrice );
                  else
                     System.out.println("Got no quotes");
               }
         );
         send(msg);
      } // if
    } // setup
} // Buyer

Buyer Behavior

class BuyerBehavior extends MyReceiver {

   public BuyerBehavior(
      Agent a, int delay, MessageTemplate template ) {
         super(a, delay, template);
   }

   public void handle( ACLMessage msg) {
      if (msg == null) return;
      int offer = Integer.parseInt( msg.getContent());
      System.out.println("Buyer considering an offer for $" + offer);
      if (offer < ((Buyer)myAgent).bestPrice) {
         ((Buyer)myAgent).bestPrice = offer;
            ((Buyer)myAgent).bestOffer = msg;
      }
   }
}

Output

s1 will offer $227 to b1 in 66 ms
s3 will offer $173 to b1 in 86 ms
s2 will offer $75 to b1 in 65 ms
s1 will offer $323 to b1 in 29 ms
s3 will offer $105 to b1 in 44 ms
s2 will offer $114 to b1 in 18 ms
Buyer considering an offer for $114
Buyer considering an offer for $323
Buyer considering an offer for $105
Best Price $105