Example #1
0
/// want_list(user asking, user target) - Return a list of cards which target wants.
Data Server::want_list(const Data& args)
{
	if(!args.IsList(2) || !args[0].IsString() || !args[1].IsString())
		ArgumentError("want_list",args);

	if(!IsUser(args[0]))
		throw LangErr("want_list","invalid user "+tostr(args[0]).String());
	if(!IsUser(args[1]))
		throw LangErr("want_list","invalid user "+tostr(args[0]).String());

	VAR(asker,"users"); // asker=users{args}
	MAP(asker,args[0]); // asker=users{args[0]}
	VEC(asker,2);       // asker=users{args[0]}[2]
	VAR(user,"users");
	MAP(user,args[1]); // users=users{args[1]}

	// Check all cards
	Data ret;
	Data *cards,*entry;
	VECTO(user,2,cards); // cards=users{args}[2]

	ret.MakeList();
	for(size_t i=0; i<cards->Size(); i++)
	{
		// Add only cards that asker have
		MAPTO(asker,(*cards)[i][0],entry);
		if(entry->IsNull())
			*entry=NewCard();

		if((*cards)[i][1][1] < 0 && (*entry)[0] > 0)
			ret.AddList((*cards)[i][0]);
	}
	
	return ret;
}
Example #2
0
    Data Data::operator-(const Data& arg) const
    {
	if(type==NullType || arg.type==NullType)
	    return Null;
	if(type==IntegerType && arg.type==IntegerType)
	    return Data(n - arg.n);
	if(type==RealType && arg.type==RealType)
	    return Data(r - arg.r);
	if(type==IntegerType && arg.type==RealType)
	    return Data(double(n) - arg.r);
	if(arg.type==IntegerType && type==RealType)
	    return Data(r - double(arg.n));
	if(type==ListType)
	{
	    set<Data> remove;
	    Data ret;

	    if(arg.type!=ListType)
		throw LangErr("Data::operator-(const Data& )","Cannot substract list and non-list");
	    ret.MakeList();

	    if(IsDatabase() || arg.IsDatabase())
	    {
		for(size_t i=0; i<arg.Size(); i++)
		    remove.insert(arg[i]);
		for(size_t i=0; i<Size(); i++)
		    if(remove.find((*this)[i])==remove.end())
			ret.AddList((*this)[i]);
	    }
	    else
	    {
		vector<Data>::const_iterator i;
		for(i=arg.vec.begin(); i!=arg.vec.end(); i++)
		    remove.insert(*i);
		for(i=vec.begin(); i!=vec.end(); i++)
		    if(remove.find(*i)==remove.end())
			ret.AddList(*i);
	    }

	    return ret;
	}
		
	throw LangErr("Data::operator-const Data& )","Incompatible operands");
    }
Example #3
0
/// have_list(user asking, user target) - Return a list of cards which target user has more than
///   his trade_limit or has at least one for sale; and asking user has in his want list.
Data Server::have_list(const Data& args)
{
	if(!args.IsList(2) || !args[0].IsString() || !args[1].IsString())
		ArgumentError("have_list",args);

	if(!IsUser(args[0]))
		throw LangErr("have_list","invalid user "+tostr(args[0]).String());
	if(!IsUser(args[1]))
		throw LangErr("have_list","invalid user "+tostr(args[0]).String());

	VAR(asker,"users"); // asker=users{args}
	MAP(asker,args[0]); // asker=users{args[0]}
	VEC(asker,2);       // asker=users{args[0]}[2]
	VAR(user,"users");
	MAP(user,args[1]); // users=users{args[1]}

	// Find the limit
	Data *limit;
	VECTO(user,3,limit);          // limit=users{args[1]}[3]
	VEC(limit,0);                 // limit=users{args[1]}[3][0]
	MAP(limit,Data("trade_limit"));// limit=users{args[1]}[3][0]{"trade_limit"}

	int trade_limit;
	if(limit->IsNull())
		trade_limit=4;
	else
		trade_limit=limit->Integer();

	// Check all cards
	Data ret;
	Data *cards,*entry;
	VECTO(user,2,cards); // cards=users{args}[2]

	ret.MakeList();
	for(size_t i=0; i<cards->Size(); i++)
	{
		if((*cards)[i][1][1] > 0 || (*cards)[i][1][0].Integer() > trade_limit)
		{
			// Add only wanted cards
			MAPTO(asker,(*cards)[i][0],entry);
			if(entry->IsNull())
				*entry=NewCard();
			if((*entry)[1] < 0)
				ret.AddList((*cards)[i][0]);
		}
	}
	
	return ret;
}
Example #4
0
/// get_card_data(user,card list) - Return a list of full update entries for cards given.
///  check the validity of all arguments and return NULL if some of the arguments 
///  are not valid.
Data Server::get_card_data(const Data& args)
{
	if(!args.IsList(2) || !args[0].IsString())
		ArgumentError("get_card_data",args);
	if(!IsUser(args[0]))
		throw LangErr("get_card_data","invalid user "+args.String());

	if(!args[1].IsList())
	    return Data();

	VAR(collection,"users");
	MAP(collection,args[0]);
	VEC(collection,2);

	const Data& L=args[1];
	Data ret;
	ret.MakeList();
	Data entry;
	entry.MakeList(5);
	Data price;
	Data* card_data;

	for(size_t i=0; i<L.Size(); i++)
	{
	    if(!L[i].IsInteger())
		return Data();

	    int card=L[i].Integer();
	    if(card < 0)
		return Data();

	    // Get price data
	    price=price_list(L[i]);
	    if(price.IsNull())
	    {
		entry[1]=0.0;
		entry[2]="";
	    }
	    else
	    {
		entry[1]=price[1][1];
		entry[2]=price[1][0];
	    }
	    // Get collection data
	    if(collection->HasKey(L[i]))
	    {
		MAPTO(collection,L[i],card_data);
 		entry[0]=(*card_data)[0];
 		entry[3]=(*card_data)[2];
 		entry[4]=(*card_data)[1];
	    }
	    else
	    {
		entry[0]=0;
		entry[3]=0.0;
 		entry[4]=0;
	    }

	    ret.AddList(Data(L[i],entry));
	}

	if(ret.Size())
	    return ret;

	return Data();
}
Example #5
0
/// price_list(list of card numbers or single card number) - With 
///   single card number argument, return the best offer for the card
///   in format (card numer,(seller,price)). If there are not any
///   cards for sale, return NULL. If a list of card numbers
///   is given, return list of the prices for those cards. Without any
///   arguments, return the full list of all prices. NULLs are removed
///   when returning a list.
Data Server::price_list(const Data& args)
{
	if(args.IsInteger())
	{
		int card_number=args.Integer();
		
		VAR(prices,"prices");
	
		// Create empty return value entry:
		//
		//    (card number,("",0.0))
		//
		Data ret(card_number,Data(string(""),0.0));

		// Check if there are any prices.
		if(!prices->HasKey(card_number))
			return Null;

		// Price list for the card
		Data& P=(*prices->FindKey(args))[1];

		double price,minprice=0.0;
		bool first=true;
		list<string> sellers;
		list<int> seller_index;
		
		// Scan through pairs P[j]=(seller,price) and find the best offer
		for(size_t j=0; j<P.Size(); j++)
		{
			price=P[j][1].Real();
			if(first || price < minprice)
			{
				first=false;
				minprice=price;
				sellers.clear();
				seller_index.clear();
				sellers.push_back(P[j][0].String());
				seller_index.push_back(j);
			}
			else if(price==minprice)
			{
				sellers.push_back(P[j][0].String());
				seller_index.push_back(j);
			}
			
		}

		ret[1][1]=minprice;

		if(sellers.size()==0)
			return Null;
		else if(sellers.size()==1)
			ret[1][0]=sellers.front();
		else
			ret[1][0]=string(ToString(sellers.size())+" sellers");

		return ret;
	}
	else if(args.IsList())
	{
		Data ret;
		ret.MakeList();
		Data e;
		for(size_t i=0; i<args.Size(); i++)
		{
			e=price_list(args[i]);
			if(!e.IsNull())
				ret.AddList(e);
		}
		
		return ret;
	}
	else if(args.IsNull())
	{
		VAR(prices,"prices");
		return price_list(prices->Keys());
	}
	else
		ArgumentError("price_list",args);

	return Null;
}