PriceAdvisor: Maximize your profits

Solens

New member
I tried using the script, but I keep getting this error:

Updating use_for_items.txt from '' to '2009-12-24T15:51:09-06:00'...
Unexpected error, debug log printed.
Failed to load file use_for_items.txt
 

xKiv

Active member
Are there any plans for special-casing items that grant +meat/+item effects on use?
Basing it off standard gains in the castle (roughly 1.22 meat/+1%meat and 1.21 meat/+1%items, afaik, according to my old spreadsheet - UniversalFarming says 1.25 meat/+1%meat and 1.3 meat/+1%item with olfaction, 0.95 meat/+1%item without olfaction).

So, say, red snowcone is worth about 20*50*1.25=1250 meat ...
 
I'm going to tentatively say "No" to that. Here are my concerns:

- Evaluation would have to be limited strictly to Castle-farming, at default ML, combat rate, etc., and would have to ignore the fact that there is a level of item-drop beyond which more does nothing.

- I don't think it's currently trivial to go from item -> effect in Mafia. Once you have the effect it's simple to get to the item / meat drop via numeric_modifier, but that ignores how many turns you get. (This might be fun to work on, though.)

- I'm also not sure what PA would report, since in its current paradigm it would do the math rather like this:
Code:
profit = ( (benefit of +meat or +item) - valueOfAdventure ) * # of effect turns
On the one hand this is reasonable, since it clearly costs an adventure to get the benefit of the effect. On the other hand, for any reasonable valueOfAdventure (default is 500) this would likely result in negative profit -- which is ridiculous, as the used adventures would also you be gaining whatever else you got farming the castle.

- There's no good way to take into account the fact that you might be running several beneficial effects for the "cost" of the same adventures. PA's basic unit is one item, one piece of advice -- it's not set up to give one piece of advice incorporating several items.

- I worry that this is a strange way to "value" an item in a larger script, in that it requires more than manipulation of your inventory. So do woking and some smithing, but these use up adventures in a very simple way.

On the other hand, using an item for the benefit of its effect is certainly a legitimate way to turn it into meat. I'd be pleased to hear any further thoughts on this!
 

Quincunx

New member
This is a great script, but what is the reasoning when it suggests this?

Code:
[B]asshat:[/B]
untinker asshat; acquire 1 bum cheek; combine 2 bum cheeks; mallsell asshat: 980.0 meat
mallsell asshat: 650.0 meat
smash asshat; mallsell cold powder; acquire 4 piles of sleaze powder; malus 5 piles of sleaze powder; mallsell sleaze nuggets; autosell twinkly powder: 131.33334 meat
autosell asshat: 45.0 meat
 
My initial guess is that it wants you to untinker the asshat, buy two more bum cheeks, make 2 asshats, and sell them, which is where it gets the bigger price. But it's not actually saying that, and besides that's a crazy sort of recommendation. I'll look into it.

Edit: Okay, 1.41 now gives clearer advice in this situation:
Code:
[B]asshat:[/B]
untinker asshat; then do 2 times: acquire 1 bum cheek; combine 2 bum cheeks; mallsell asshat: 740.0 meat
mallsell asshat: 650.0 meat
smash asshat; mallsell cold powder; mallsell sleaze powder; autosell twinkly powder: 83.333336 meat
autosell asshat: 45.0 meat

This fixes the "utterly confusing advice" issue but not the "that's a crazy thing to suggest" issue. It was such a quick fix for the one that I just went ahead and released it without worrying about a fix for the other, which is sillier but not as wrong/confusing.

Here's the logic:
asshat is untinkerable, so try untinkering it -- you get 2 bum cheeks. What's the best thing to do with a bum cheek? Acquire another and make an asshat (at least at the moment).

Because of PA's strict one-item evaluation, it's not smart enough to realize that hey, you just took apart a freakin' asshat. And at the moment, buying the pieces for another and selling two is going to net you more profit than just selling the first. It's just that this feels like very silly advice. It is very silly advice. I'll try to work in some special-casing for "if the final result is the same as the initial result (or a multiple), this is silly advice and you shouldn't give it".

Edit 2: Okay, that was a lot easier than I thought it would be. 1.42 catches this type of silly advice in "use" and "untinker" cases and refuses to give it as advice; if it shows up anywhere else, let me know! (And for anyone who downloaded 1.41, sorry for the necessity to redownload so quickly...)

As a bonus, 1.42 eliminates some artifacts of the occasional overlap between my item_use map and "SUSE" type concoctions. Together, the 1.42 fixes eliminate some of the bizarre/repetitive advice you might have been getting for clovers.

And let me just say: Thank you Quincunx! There are so many weird edge cases in this script that I just can't test all the interactions, and rely very much on reports and questions like yours to point me at things that need fixing.
 
Last edited:

Spiny

Member
Using 1.42:

Code:
box:
acquire 1 nothing-in-the-box; combine 1 box, 1 nothing-in-the-box; acquire 1 spring; combine 1 box-in-the-box, 1 spring; mallsell nothing-in-the-box-in-the-box: 1700.0 meat
mallsell box: 775.0 meat
acquire 1 nothing-in-the-box-in-the-box; combine 1 box, 1 nothing-in-the-box-in-the-box; untinker box-in-the-box-in-the-box; mallsell box; mallsell nothing-in-the-box-in-the-box: 775.0 meat
acquire 1 wrapping paper; combine 1 box, 1 wrapping paper; mallsell present: 768.0 meat
smash box; autosell twinkly powder: 30.0 meat
autosell box: 19.0 meat
acquire 1 spring; combine 1 box, 1 spring; : 0.0 meat

I always thought the recipes involving boxes were confusing... and the wrapping paper to make a present was just precious... I would make a 768 meat profit buying wrapping paper that costs 26 mil? And a present costs minimum 28 mil in the mall atm... *thinks this one slipped thru the cracks*
 

dj_d

Member
Aqua, this is mega awesome. Can't wait to play with it, and eventually integrate in to farm.ash (which, if you don't have the password for, PM me and I will hook you up - of course).

Perhaps a future feature would be "make_it_so" - where it actually liquidates the item in the most profitable way?
 
Using 1.42:
I always thought the recipes involving boxes were confusing... and the wrapping paper to make a present was just precious... I would make a 768 meat profit buying wrapping paper that costs 26 mil? And a present costs minimum 28 mil in the mall atm... *thinks this one slipped thru the cracks*

First let's talk about wrapping paper. This is a consequence of, essentially, three things:
1) PA can only see the 5th price of an item, as per Mafia standard. Wrapping paper probably isn't selling at that price (or heck, maybe even at the lowest mall price), but that's more context than PA is capable of understanding.
2) PA has no common sense; if the math of selling prices and opportunity costs says you should buy wrapping paper in order to profit from a box, it thinks that's a dandy idea. Even though that's crazy. (This is one of the reasons the alias I suggest uses price_advice() rather than best_price() -- you have to use your own brain on top of PA's, so it's worth it to see all the options in case the first is crazy.) I think that it would be weird to hard-code special-case all "too expensive" items, so these recommendations stay.
3) As to why you're not making millions on the wrapping paper suggestion, I assume this is because the opportunity cost of the wrapping paper is higher than the mallsell price, thus making the eventual profit lower than you might expect.

That third piece of advice definitely looks like it needs to be taken care of, though. Bother. The simple fix wasn't good enough, alas.

Aqua, this is mega awesome. Can't wait to play with it, and eventually integrate in to farm.ash (which, if you don't have the password for, PM me and I will hook you up - of course).

Perhaps a future feature would be "make_it_so" - where it actually liquidates the item in the most profitable way?

Thank you! Farm.ash was one of the possible "embed in another script" applications I was thinking of when I wrote it, so I'm pleased you are thinking along the same lines.

A make_it_so option is intriguing, but runs into the "sometimes PA has no common sense or sense of market movement" issue. (There's also the matter of letting PA mature a bit, as it clearly still needs some tweaking!)
One solution might be to specify a maximum price at which other ingredients could be bought, either as a strict maximum or as a percentage of the mallsell price of the initial item. Thoughts?
 

lostcalpolydude

Developer
Staff member
One solution might be to specify a maximum price at which other ingredients could be bought, either as a strict maximum or as a percentage of the mallsell price of the initial item. Thoughts?

I was going to suggest that. Maybe add some variable in the script that people can change if they really want to consider expensive ingredients, but that might not be a useful feature for anyone.
 

heeheehee

Developer
Staff member
- I don't think it's currently trivial to go from item -> effect in Mafia. Once you have the effect it's simple to get to the item / meat drop via numeric_modifier, but that ignores how many turns you get. (This might be fun to work on, though.)

I asked a related question in Scripting Discussion (thread: http://kolmafia.us/showthread.php?t=3192), and it turns out that the answer is to import statuseffects.txt and parse it.

One of the posts I linked to in the initial post (http://kolmafia.us/showpost.php?p=15442&postcount=5) has a snippet that does this, if you want to incorporate that into your script (just don't forget to credit jasonharper, of course!).
 
One of the posts I linked to in the initial post (http://kolmafia.us/showpost.php?p=15442&postcount=5) has a snippet that does this, if you want to incorporate that into your script (just don't forget to credit jasonharper, of course!).

That is an excellent snippet, thanks for the link. I thought I'd seen something about this issue lately -- it must have been your post!

It doesn't solve the "how many turns" issue, which is particularly annoying for, say, the gingerbread house, which has a maximum of infinite turns of +item/+meat. I think valuation of items via MPA is still looking like something that's not going into PriceAdvisor any time soon.

But if it does, I'll be glad to have that snippet!
 

dj_d

Member
aqua - regarding make_it_so, if it was me, I'd also have a _conservative flag. If set, then it would only recommend "simple" transactions, where it would only make purchases if they could be had for a reliable price - either from an NPC, or because the mallprice was the minimum (autosellx2 I think). So it would recommend buying fermenting solution for your orange, but it won't recommend buying another 124 floaty sands to go with the one you've already got. :)
 
I'm trying to handle some of the more esoteric advice types that PA can give.

There seems to be some inconsistency though, if you ask for advice from equipment it will tell you to smash it whether or not you have pulverize. But if you ask for advice from booze, it only suggests the still and cocktailcrafting if you have the relavant skills.

I couldn't see where this was happening so it might be something you don't have control over, i don't know.

Also in the case of crafting sugar items from sugar sheets, the action string you use is "fold ..." however the cli command fold only works for things like ice sickles and spooky putty sheets (which cycle a group of objects). For sugar sheets the cli command that works is "make ...".

(p.s. my preference would be for it to give all advice types ignoring current skills, if you control it. Also now i'm getting more into the script i love you even more)
 
Last edited:

lostcalpolydude

Developer
Staff member
There seems to be some inconsistency though, if you ask for advice from equipment it will tell you to smash it whether or not you have pulverize. But if you ask for advice from booze, it only suggests the still and cocktailcrafting if you have the relavant skills.

You can have wadbot or smashbot pulverize stuff for you, and I believe mafia automatically handles sending stuff to be smashed for you even. No equivalent exists for boozemaking. There's no inconsistency.
 
Regardless is this enforced by mafia or in your script, and if it's something you do, could you help me find it so i can change it in my copy? Thanks.
 

heeheehee

Developer
Staff member
That is an excellent snippet, thanks for the link. I thought I'd seen something about this issue lately -- it must have been your post!

It doesn't solve the "how many turns" issue, which is particularly annoying for, say, the gingerbread house, which has a maximum of infinite turns of +item/+meat. I think valuation of items via MPA is still looking like something that's not going into PriceAdvisor any time soon.

But if it does, I'll be glad to have that snippet!

Hmm. For my slime-buffing script, I got around this problem by using one instance of the item first, then calculating the difference between new duration and old duration. (Snipped to preserve more relevant portions.)

Code:
boolean consume(float qty,item it) { 
	switch(item_type(it)){
		case "food": eat(qty,it);
		case "booze": drink(qty,it);
		case "": use(qty,it); // Looks like item_type spits this out for usable items, spleen and non-spleen alike.
	}
} // I originally used if...elseif...else for this bit. Would else work in the place of 'case("")'?

foreach i in item_effect {
	int current_duration = have_effect(item_effect[i]);
	while(have_effect(item_effect[i])<duration) {
		consume(1,to_item[item_effect[i])];
		int new_duration = have_effect(item_effect[i]);
		consume(ceil((duration - new_duration)/(new_duration - current_duration)),to_item[item_effect[i]]); 
// Might take a bit longer, but always works. 
// [[Additional note: item_effect[] is made up of strings (saves a bit of space), so that's why I used to_item.]]
	}
}

Obviously that won't really work for what you have in mind, as you won't be wanting to use items beforehand. [Posting this bit to perhaps inspire someone to come up with a more elegant solution. Heh.]

Oh, and if I'm not mistaken, the cost of getting those turns of Holiday Bliss is 1 adventure (unless you have Disco [Power] Nap). Then it's just a matter of timing it so that your first free rest lines up with when you need the item/meat bonus.

Also, in this case, are you going to add in value of MP (for free rests, and by extension, items)? I'd say check it against MMJ if myst class; else against the next cheapest MP-restorer? Incidentally, for Jumbo Dr. Lucifers, you'd want to check it against other foods (i.e. is the loss of potential adventures worth it?). I guess for this, you could recycle Bale's recovery script map. [[Edit: "this" as it appears in the previous sentence should be read as "value of MP"]]

The potentially unlimited yield would most likely be fixed by adding a boolean "renewable" (Which would indicate whether the item was a daily or not). If true, you'd just add a "per day" to the output. After all, it's just an adviser, so the player would still be able to make his/her own decision. You'd probably have to compile the list of dailies on your own, though.
 
Last edited:
aqua - regarding make_it_so, if it was me, I'd also have a _conservative flag.

This is a good idea; combined with the percentage of original price idea it should provide decent levels of protection from crazy.

I won't be doing make_it_so until PA is a little more mature, but these are all things to keep in mind.

Also in the case of crafting sugar items from sugar sheets, the action string you use is "fold ..." however the cli command fold only works for things like ice sickles and spooky putty sheets (which cycle a group of objects). For sugar sheets the cli command that works is "make ...".

(p.s. my preference would be for it to give all advice types ignoring current skills, if you control it. Also now i'm getting more into the script i love you even more)

lostcalpolydude is correct about smashing/malusing; because wadbot can do them I consider them skills you always have.

However, because I create most "concoctions" advice depending on Mafia's get_ingredients(), which only returns ingredients if you can actually make the thing, it is smashing/malusing that is the special case. I have to add them back in. There's just no way I'm going to do this for all skills, etc. unless you can suggest some better way for me to create the ingredients[] map. The code is at roughly line 142 if you want to take a look.

So I can't tell you where to change it in your copy, because I'm not the one ruling things out. I'm the one ruling a few things back in. If you want this behavior, you'd have to make a Mafia feature request to change the way get_ingredients() works. (Maybe a get_ingredients(item it, boolean ignore_skills) variant?)

As for sugar-folding, that's hardly the only advice given by PA which doesn't correspond to Mafia CLI syntax. Even "cook" isn't proper CLI syntax! Even if I were to switch all the "wrong" commands to be readable by the CLI, there remain hacks like "then do x times" which Mafia doesn't understand. Right now, parsing the advice is non-trivial, I'm afraid.

I may in the future attempt to standardize it to be Mafia-readable, but right now it's meant to be human-readable.

Lots of helpful thoughts.

Yikes! So much to consider.

For Holiday Bliss and things like it, the "daily" variable, with the advice being "per day" is pretty darn good. The user would then have to do the math of how many days and decide. Unfortunately, that might result in an "incorrect" best_price(). Maybe if such an item is inquired about the script would have to prompt for a number of days?

Oh good lord. MP. Of course MP is worth it! And Bale has that snazzy new _meat_per_mp variable to look at, I wouldn't even have to do most of the math... (And then, is HP worth it?)

But really, I think this is all so complicated that the first step would be to create a separate library do deal with it (much like SmashLib was enough code that I farmed it out into a separate script). It's not something high on my list right now, although if someone else wants to tackle it...

(The hope is that the market correctly reflects the value of the item and so I don't have to calculate +item/+meat/MP value. Unfortunately, as we all know, this is not usually the case. If PA calculated them and everyone used PA, only then would the market properly reflect the "true value"... gah.))
 

heeheehee

Developer
Staff member
... create most "concoctions" advice depending on Mafia's get_ingredients() ... suggest some better way for me to create the ingredients[] map ... make a Mafia feature request to change the way get_ingredients() works. (Maybe a get_ingredients(item it, boolean ignore_skills) variant?)

You might want to look at concoctions.txt and do some parsing, not unlike that little snippet that I posted a link to earlier.
EDIT: I'm a moron and hadn't actually looked at the script itself carefully. Heh. Yeah, you do use concoctions.txt, but I guess I was recommending doing something sorta like what jasonharper did for item2effect (link's earlier up on this page). I'll see if I can modify it to do this

sugar-folding ... "cook" isn't proper CLI syntax ... switch all the "wrong" commands to be readable by the CLI => Mafia doesn't understand "then do x times".

If I were to do this, I'd do something similar to the universal consume() for cook/smith/fold/whatever. Or set aliases? I don't know -- you should be able to do that with ASH, right? [[New side project for me: create a little scriptlet to set all these aliases at once. Hehe.]]


... "daily" variable ... "per day" ... Maybe if such an item is inquired about the script would have to prompt for a number of days?

Regarding the dailies: you might want to add in support for demon summoning (if it's ever worth it... heh). Is there a way to check Daily Deeds to see if you've already summoned demons?

I also hacked together a .txt with all (most?) relevant effects and durations (but it'll need updating regularly, I suppose). I honestly don't know if it'll work, as I haven't tested it. Threw in AT Hobo skills in the event that the player is an AT, will be staying in aftercore for some time, and plans to sell the skills regularly. Note: no duration was given for these. Or Fishy, which is just too variable.

It uses these columns: effect number, effect name, source, duration, daily (boolean-esque), and underwater only (boolean-esque). For the last two columns, 1 indicates true; 0 indicates false. Need to add that into a library, eventually. Heh.

For the ASH script itself, I'd add in a sauce_duration variable, using a bit of the following code:
Code:
int sauce_duration = 5;
if(my_class()==$class[sauceror]) sauce_duration = sauce_duration + 5;
if(have_skill($skill[Impetuous])) sauce_duration = sauce_duration + 5;

Now that I think about it, you'd probably also have to prompt for a location, if you want to use mpa from effects -- perhaps incorporate parts of this script (http://kolmafia.us/showthread.php?t=2493)? An improvement that could be made would be taking residual effects into account -- that is, effects that you have currently active but are not planning to increase rounds for. Here's a little snippet from my slime-buffing script (again!):

Code:
float effect_ML(effect key) {
	float fx_ML = numeric_modifier(key,"Monster Level");
	if(ML_fam == "purse rat") {
		fx_ML = fx_ML + numeric_modifier(key,"Familiar Weight") / 2;
		// Special case for Bitterskin (Rather than assume immediately that you're running full slime-hate gear):
		if(key == $effect[Bitterskin]) {
			fx_ML = min(1000,(15 * (slime_hate + 1) * (slime_hate + 3))) - min(1000,(15 * (slime_hate) * (slime_hate + 2))); 
		}
		// Mafia doesn't do love songs too well.
		if(key == $effect[Cold Hearted]) fx_ML = 5; 
	}
	return fx_ML;
}

partialML = 0;
foreach c in allML {
	if(!(fx contains c)&&have_effect(allML[c])>0) {
		int has_fx = have_effect(allML[c]);
		if(PYEC) has_fx = has_fx + 5;
		partialML = partialML + min(has_fx,limit) * effect_ML(a[c]);
	}
}

Obviously it's for ML, as opposed to items or meat, but you could easily adopt this, I'd think. You wouldn't need the first function, and calculations for familiar weight would be slightly more complicated for fairy/leprechaun-types, but hey, there's a formula for that!

Oh good lord. MP. Of course MP is worth it! And Bale has that snazzy new _meat_per_mp variable to look at, I wouldn't even have to do most of the math... (And then, is HP worth it?)

HP isn't really worth it -- fully healing HP is trivial compared to MP.

But really, I think this is all so complicated that the first step would be to create a separate library do deal with it (much like SmashLib was enough code that I farmed it out into a separate script). It's not something high on my list right now, although if someone else wants to tackle it...

I might give that a shot if you give me a list of functions you might want.

(The hope is that the market correctly reflects the value of the item and so I don't have to calculate +item/+meat/MP value. Unfortunately, as we all know, this is not usually the case. If PA calculated them and everyone used PA, only then would the market properly reflect the "true value"... gah.))

Well, we better start spreading the word, then, eh?
 
Last edited:
Top