Mall manipulation functions

stat days!!! Yes!

Oh ummm another odd idea.

int my_shop_price(item it) would return the current price in my mall store for an item.

Code:
void shop_take(item ItemToPull)
  {
  if(shop_amount(ItemToPull) > 0){cli_execute("managestore.php?action=takeall&whichitem=" + item_to_int(ItemToPull));}
  }

int tempprice;
if(shop_amount($item[incredibly dense meat gem]) > 1)
  {
  tempprice = my_shop_price($item[incredibly dense meat gem]);
  shop_take($item[incredibly dense meat gem]);
  //equip the idmg then adventure
  put_shop(tempprice, 0, $item[incredibly dense meat gem]);
  }

Now this isn't actually internal data. I am aware of this, but it is data that stares kolmafia right in the face when querying shop_amount. I figured it can't hurt too much to ask.
 

picklish

Member
What about a function to find out the average mall price for purchasing n of a particular kind of item? It's not necessarily "internal data", but it's certainly "internal functions."

This ASH function would make it possible to optimize for meat or stat gains per fullness/drunkness in an ASH script, where previously it was impossible. You could call this function mall_price. I say average price for a number of items, because that seems easier to handle than getting back a map, but it still gives you the potential for more information than just a flat minimum price.

You could (theoretically ;)) even implement it in KoLmafiaASH.java by adding this code:
Code:
params = new ScriptType[] { ITEM_TYPE, INT_TYPE };
result.addElement( new ScriptExistingFunction( "mall_price", FLOAT_TYPE, params ) );

...and...

Code:
public ScriptValue mall_price( ScriptVariable item, ScriptVariable stores )
{
  ArrayList prices = new ArrayList();
  ( new SearchMallRequest( client, TradeableItemDatabase.getItemName( item.intValue() ), stores.intValue(), prices )).run();

  int itemTotal = 0;
  int meatTotal = 0;
  int maxItems = stores.intValue();

  for ( int i = 0; i < prices.size(); i++ )
  {
    MallPurchaseRequest req = (MallPurchaseRequest)prices.get( i );

    int quantity = req.getLimit();
    if ( itemTotal + quantity > maxItems )
      quantity = (maxItems - itemTotal);

    itemTotal += quantity;
    meatTotal += quantity * req.getPrice(); 

    if ( itemTotal >= maxItems )
      break;
  }

  if ( itemTotal > 0 )
    return new ScriptValue ( (float)meatTotal / (float)itemTotal );
  else
    return new ScriptValue ( 0 );
}

...and forgive me if I missed some more obvious way to do this that already exists or anything else. I'm kind of new to KoLmafia. :)
 

Nightmist

Member
[quote author=picklish link=topic=250.msg1816#msg1816 date=1155267121]
What about a function to find out the average mall price for purchasing n of a particular kind of item? It's not necessarily "internal data", but it's certainly "internal functions."[/quote]
Although I can't say for sure, I am pretty confident that if this was added then so would "mallbot functionality", so I doubt this command will be added. (Make "n" 1 and then poof auto-checking for underpriced items, or even if its a "forced" number of shops, you can just loop and keep checking the returned average and wait for a sudden drop in average price which would signify underpriced item.)


Now for my request... Not really adding functions but I am curious where mafia currently stores the values for the ML mods and such (Since they are not currently in the .dat files as far as I know)??
 

picklish

Member
[quote author=Nightmist link=topic=250.msg1817#msg1817 date=1155267813]
Although I can't say for sure, I am pretty confident that if this was added then so would "mallbot functionality", so I doubt this command will be added.[/quote]
Hmm...*checks doc* *searches forum* Oh...it wasn't obvious to me that avoiding "mallbot functionality" was a mandate for the project until you said that and I searched the forum and saw somebody else mention it. Sorry about that. Are there any other things I should avoid? :-\

Perhaps it's just a philosophical disagreement, but it seems like useful functionality that can be used for non-evil. I'll just fork that change locally and merge going forward.
 

Veracity

Developer
Staff member
[quote author=picklish link=topic=250.msg1822#msg1822 date=1155269534]
Perhaps it's just a philosophical disagreement, but it seems like useful functionality that can be used for non-evil.[/quote]

I like your function. I have the personal philosophy that if something can be used primarly for good, it's a shame to withhold it from everybody because somebody could use it for evil. But holatuwol and I disagree about a fair number of things - and this is his baby and it's his reputation which will get tarnished if, for example, we put in stuff that made clan lootng efficient and then somebody used KoLmafia to do that.

(Which is probably a bad example, because now you CAN script taking stuff from the clan stash, although that wasn't true for quite a long time.)

Well, proper use of karma and permissions make clan looting essentially a failure of clan administration, these days, so that restriction got relaxed over time; the KoLmafia "philosophy" can and does evolve with the times.

Unfortunately,  the consequences for the whole community are a lot more severe if somebody writes a KoLmafia script which continually hammers the servers asking for the cheapest Mr.A until it finds a mispriced one that is cheap enough.

I still like your function and can definitely see how it could be used to make buying decisions in perfectly reasonable scripts. But I make a point of not submitting things that I know don't fit holatuwol's current philosophy on how the program should be used.
 

holatuwol

Developer
Veracity said:
I have the personal philosophy that if something can be used primarly for good, it's a shame to withhold it from everybody because somebody could use it for evil.

There's a lot of things that I've permitted, in spite of being dead-set against them for a very long time.  Among these are the store manager, the buffbot module, the familiar trainer, the flower hunter, the advanced script handler, and the local relay server. Of these, the store manager is the only one I actually regret adding.  So, in spite of my philosophies (which differ from Veracity's), a lot of things which go against my personal philosophies might get implemented if it seems like the main use is something which doesn't sound like "squeeze out optimization that no sane person would do by hand".

So far, the buy_cheapest() function doesn't satisfy this constraint.  Once implemented, people would (a) start writing "is it cheaper to make the item from sub-ingredients or buy this item" functions that call themselves recursively that no sane person would do by hand,  (b) use it to save ~100 meat per item during daily eat/drink scripts, or (c) write mallbots.  The user interface is uninteresting and requires zero knowledge of the way KoL works; all I'd have to do is do multiple mall searches, cache all the results in a single result array, sort it, and return the top item.

I usually don't remove functionality that's already been added unless I provide something equivalent.  So if Veracity or Umo feel like adding the feature, I'm open to the idea, and the same goes for the trapper quest.  In other news, my own reputation rarely gets tainted by something the program can do; it's far more often tainted by things it can't do right. ^_~  So no worries on that front.


Veracity said:
Well, proper use of karma and permissions make clan looting essentially a failure of clan administration, these days, so that restriction got relaxed over time; the KoLmafia "philosophy" can and does evolve with the times.

Actually, just a few days ago, I was trying to come up with a way to allow a friend to limit the number of each item available in their stash to 800 units per item.  I'm thinking, "Hm, stash_amount gives me how many of an item there is, so maybe just use that.  I can use int_to_item to loop over all items and just check against $item[none]."  I then came up with the following script:

Code:
int i = 1;
refresh_stash();
while ( i < 2000 )
{
    item it = int_to_item( i );
    if ( it != $item[none] )
        take_stash( stash_amount( it ) - 800, it );
    i = i + 1;
}

After writing this script, I'm sure it's trivial to discover why the clan stash display now allows mass select, mass take and all sorts of other enhancements.  A long time ago, it was suggested that int_to_item would have some bad repercussions.  I honestly didn't realize until very recently that clan looting was one of them.
 

picklish

Member
Re: Stasis & Combat Control & access to HTML output

[quote author=holatuwol link=topic=350.msg1915#msg1915 date=1155582751]
Mallbots are not possible with contains_text and visit_url alone; you need the actual indices where the matches occurred in order to determine which store had the price you wanted. Brute-forcing a million stores and an infinite number of price combinations is too slow and too useless for a mallbot.[/quote]
You really only need O(max price you care about) compares. If you wanted to be assured that mafia would buy from the right store and no more than that price, then you would just need another O(number of users) compares to grab that number as well. Something like:
Code:
int getNumber(string text, string prefix, string suffix, int start, int end)
{
  for i from start upto end
  {
    if (contains_text(text, prefix + i + suffix))
      return i;
  }
  return 0;
}

int getPrice(string text, int maxPrice)
{
  return getNumber(text, "searchprice=", '"', 100, maxPrice);
}

string searchMall(string item)
{
  return visit_url("searchmall.php?cheaponly=checked&shownum=1&whichitem=" + 
    item);
}

int getMallPrice(string item, int maxPrice)
{
  string text = searchMall(item);
  return getPrice(text, maxPrice);
}
 

peterbones

New member
Re: Stasis & Combat Control & access to HTML output

I actually wanted non-internal data (quests, trapper ores) though I thought at the time that using internal data to do it would be a good way.

Picklish, my mother always told me that O(N) may be linear but that doesn't help for large N. Couldn't your proposed mallbot do something more intelligent? Search with a limit of 1, and then to get the price instead of doing a linear search of 100-1,000,000 or whatever max price, it could search digit by digit. So now you're down to ~10*log_10(N) operations. Much better. And instead of searching through all players, you could similarly parse the link on the page to their mall store. So you're at O( log_10( maxPrice ) + log_10( #players ) ). Actually doable!

Man, you can do all kinds of evil stuff I hadn't thought about. If all that's cared about is the stasis, you could just allow a string/options to be attached to fight.php and then return the text.
 

holatuwol

Developer
Ouch.  First clan looting, now mallbots.  Now I kinda know how /dev felt when they looked back on the autosell values of gift items being used to fund speed-running.  Except, if I nerf it here, there probably won't be thousands of pages of text arguing over the merits of mallbots.  So, nerfed.  Search URLs will not be tolerated in the visit_url function in the public release.

Edit: In other news, the letter I've been waiting for finally arrived, so I'll probably not be mucking around with code over the next month. If you do find anything in visit_url which might be an exploit, please let me know with an in-game kmail. Thanks.
 

picklish

Member
Hehe...good point, peterbones. That thought had crossed my mind earlier, but when I sat down to write it, it slipped my mind.
 

holatuwol

Developer
By allowing for the automating of new content and permitting fully-automated, almost-optimal softcore ascensions, automating holidays is rather trivial by comparison. :p
 
heh! My post wanting to know my shops price of an item has turned into something I never imagined it would.

In other news, I have been looking at the GUI mall search function, and noticed that it totally re-sorts the results of a search. It's quite unfair that I have 1mil in advertising on kol, and my sister only has 100K but her store is at the top of the list in kolmafia...waa waa waa, blah blah blah...mer this isn't meant to be a whining post.

well let's consider this... I have it set to searh 1000 stores for scrolls of drastic healing. I want 1000, so I highlight enough stores to buy 1000, and click buy and say 1000. kolmafia then proceeds to buy 1 at a time from stores cuz that's ...OK I'm blowing it out of proportion.

anyway, I think it would reduce server hits if the mall search in the GUI sorted the stores first by price, then by quantity.
 
Top