/*********************************************************************/ /* */ /* AgentService Framework */ /* www.agentservice.it */ /* */ /* Copyright (C) 2007 l.i.d.o. - DIST, University of Genoa, Italy */ /* GNU Lesser General Public License */ /* */ /* This library is free software; you can redistribute it and/or */ /* modify it under the terms of the GNU Lesser General Public */ /* License as published by the Free Software Foundation, */ /* version 2.1 of the License. */ /* */ /* This library 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 */ /* Lesser General Public License for more details. */ /* */ /* You should have received a copy of the GNU Lesser General Public */ /* License along with this library; if not, write to the */ /* Free Software Foundation, Inc., 59 Temple Place - Suite 330, */ /* Boston, MA 02111-1307, USA. */ /* */ /*********************************************************************/ using System; // this namespace defines the elements for the creation an management // of agents. using AgentService.Agent; // this namespace contains the elements for the instantiation // of new knowledges. using AgentService.Agent.Knowledge; // this namespac contains the elements for the instantiation // of new behaviours. using AgentService.Agent.Behaviour; // this namespace defines the interface for the runtime services using AgentService.Agent.Runtime; // this namespace defines the elements for the messaging system using AgentService.Platform.MTS; // this namespace defines the elements for the agent management system using AgentService.Platform.AMS; // this namespace contains the classes related to the directory facilitator. using AgentService.Platform.DF; namespace AuctionDemo { /// /// Implements the bidder agent behaviour. /// [Knowledge(typeof(Budget), typeof(Preferences))] public class Bid : Behaviour { /// /// the knowledge maintaining the information about the budget. /// private Budget budget; /// /// the knowledge maintaining the information about the preferences. /// private Preferences prefs; /// /// constructs an instance of the behaviour /// /// the name of the behaviour /// the knowledge maintaining the information about the budget. /// the knowledge maintaining the information about the preferences. public Bid(string name, Budget budget, Preferences prefs):base(name, budget) { this.budget = budget; this.prefs = prefs; } /// /// Behaviour entry point /// public override void Body() { this.Runtime.Console.AppendMessage("Bid Behaviour started by:" + this.Owner.Name); // it searches the auctioneer service using the DF DFAgentDescription[] agents = this.Runtime.YPageSvc.SearchAgent(new ServiceDescription("Auctioneer","Auction")); if ((agents != null) && (agents.Length > 0)) { AID auctioneer = agents[0].Aid; float price = 0.0f; // it opens the conversation with the auctioneer. IConversation conv = this.OpenAuction(auctioneer, out price); if (conv != null) { if (price >= 0.0f) { bool bRunning = true; bool bWinning = false; float bid = price; do { // it calculates the raising price bid = (bWinning ? bid : this.GetNewBid(price)); // if the raising price is 0, then the agent quits the auction if (bid == 0) { MessageBody body = this.CreateRetireBody(); this.Runtime.Console.AppendMessage("Retired : Budget Overflow"); conv.SendMessage(body); conv.Close(); bRunning = false; } else { // if the raising price is different from zero, then it sends the new price. MessageBody body = new MessageBody(); body.Add("Verb", "Offer"); body.Add("Price", bid); this.Runtime.Console.AppendMessage("Offer : {0}", bid); conv.SendMessage(body); System.Threading.Thread.Sleep(100); string verb = null; AgentMessage recMsg = conv.WaitForMessage(); verb = recMsg.Body["Verb"] as string; switch (verb) { case "Run": { price = (float)recMsg.Body["Price"]; AID winner = (AID)recMsg.Body["Winner"]; if (winner.Equals(this.Owner)) { bWinning = true; } else { bWinning = false; } } break; case "Close": { if (recMsg.Body["Winner"].Equals(this.Owner)) { Console.WriteLine("[{0}] I'm the winner", this.Owner.Name); bRunning = false; conv.Close(); } } break; } } } while (bRunning); } else { this.Runtime.Console.AppendMessage("Out of Auction"); } } else { this.Runtime.Console.AppendMessage("Auction Denied"); } } } /// /// Calculates the rasing price, depending on the information stored in the knowledge /// /// present price /// new price private float GetNewBid(float price) { float increment = 0.0f; float amount = 0.0f; try { this.LockKnowledge(this.budget); increment = (float) this.budget["Increment", this]; amount = (float) this.budget["Amount", this]; } finally { this.ReleaseKnowledge(true); } float bid = price+increment; return (bid > amount ? 0 : bid); } /// /// Opens the conversation and checks if the auction object is interesting /// /// auctioneer AID /// starting price /// Conversation object, null if the auction is rejected private IConversation OpenAuction(AID auctioneer, out float price) { IConversation conv = this.Runtime.MessageSvc.OpenConversation(auctioneer); while ((conv.State != ConversationState.Accepted) && (conv.State != ConversationState.Active) && (conv.State != ConversationState.Rejected) && (conv.State != ConversationState.Closed)) { System.Threading.Thread.Sleep(10); } if ((conv.State == ConversationState.Rejected) || (conv.State == ConversationState.Closed)) { price = -1.0f; return null; } AgentService.Platform.MTS.AgentMessage recMsg = conv.WaitForMessage(); // it checks if the auction object is interesting string item = recMsg.Body["Item"] as string; try { this.LockKnowledge(this.prefs); if (this.prefs.GetItems(this).Contains(item) == false) { MessageBody retireBody = this.CreateRetireBody(); conv.SendMessage(retireBody); conv.Close(); this.Runtime.Console.AppendMessage("Retired: No Item"); price = 0.0f; return null; } else { //recMsg = conv.WaitForMessage(); price = (float) recMsg.Body["StartPrice"]; } } finally { this.ReleaseKnowledge(true); } return conv; } /// /// Creates a messages for the auction exit. /// /// The message private MessageBody CreateRetireBody() { MessageBody body = new MessageBody(); body.Add("Verb","Retire"); return body; } } }