/*********************************************************************/
/* */
/* 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;
}
}
}