vcon - Veracity's consumable library

Revision 118 excludes the following from consideration:

extra-greasy slider
jar of fermented pickle juice

Your autoByPriceLimit would have to be high for them to be considered, and if your Meat per Adventure is high enough, I suppose they could be cost-effective, but since they each have the side effect of cleaning 5 spleen, they seem like they are situationally useful for manual usage, not simply because of their adventure yield.
 
And revision 119 allows you to configure your own set of consumable items

// If you want to exclude specific items from consideration, add them here.
// For example, to exclude Hobopolis consumables:
//
// set VCON.ExcludedConsumables=frozen banguet|Hodgman's blanket|Tin cup of mulligan stew

item_set user_excluded_consumables = define_property( "VCON.ExcludedConsumables", "item", "", "set" ).to_set_of_item();
 
I'm going to take a look at xkiv's post to see if I can come up with an optimal organ-filling algorithm. I have a decent algorithm in VMF which I now use for food and spleen, but how about a general algorithm which will work on any "best" map (food, booze, spleen) and an "available" size which returns a collection of the item/quantities which, in total, gives the optimal expected adventure gain?

Code:
best_found_diet=[]; // dynamic array
for (i=1; i<= organ_size; i++) {
  best_found_diet[i] = [ vcon_best_foods[i] ];
}
for (i=1; i<= organ_size; i++) {
  for (j=1; j<i; j++) {
    // how do you concatenate arrays in ASH, again?
    combined_diet = best_found_diet[j] + best_found_diet[i-j]; // try beating the single food item of size i by eating multiple smaller foods
    if (profit(combined_diet) > profit(best_found_diet[i])) {
      best_found_diet[i] = combined_diet;
    }
  }
}
In other words, put the calculation into vcon, rather than having the users of vcon have to do (similar) calculations themselves.
 
I coded this up. vct.ash (vcon test):

Code:
import <vcon.ash>;

if ( count( vcon_best_boozes ) == 0 ) {
    calculate_best_boozes( vcon_mpa() );
}

consumable_diet diet = calculate_diet( vcon_best_boozes, 20 );

print( " " );
print( "vcon recommends the following 20-fullness diet:" );
print( " " );

foreach index, c in diet {
    print( c.it + " (" + c.profit + " profit)" );
}

print( "Done!" );
where calculate_diet is:

Code:
consumable_diet calculate_diet( consumables_by_size candidates, int capacity )
{
    consumable_diet concatenate( consumable_diet... diets )
    {
	consumable_diet combined;
	foreach i, diet in diets {
	    foreach i, c in diet {
		combined[ combined.count() ] = c;
	    }
	}
	return combined;
    }

    int profit( consumable_diet diet )
    {
	int meat = 0;
	foreach i, c in diet {
	    meat += c.profit;
	}
	return meat;
    }

    void print_diet( consumable_diet diet )
    {
	foreach index, c in diet {
	    print( c.it + " (" + c.profit + " profit)" );
	}
    }

    // An array of best diets from 1 to capacity
    consumable_diet[ int ] diets;

    // Preload it with the best consumables
    for ( int i = 1; i <= capacity; i++ ) {
	diets[ i ] = { candidates[ i ] };
    }

    foreach i, diet in diets {
	print( "Best diet for size " + i );
	print_diet( diet );
    }

    for ( int i = 1; i <= capacity; i++ ) {
	for ( int j = 1; j < i; j++ ) {
	    consumable_diet combined = concatenate( diets[ j ], diets[ i - j ] );
	    if ( combined.profit() > diets[ i ].profit() ) {
		diets[ i ] = combined;
	    }
	}
    }

    foreach i, diet in diets {
	print( "Best diet for size " + i + " (" + diet.profit() + " profit)" );
	print_diet( diet );
    }

    return diets[ capacity ];
}
Yields (removing the output from calculate_best_boozes):

Code:
Best diet for size 1
elemental caipiroska (23926 profit)
Best diet for size 2
Sangria de Menthe (44180 profit)
Best diet for size 3
perfect mimosa (73038 profit)
Best diet for size 4
hacked gibson (81641 profit)
Best diet for size 5
none (0 profit)
Best diet for size 6
space wine (81543 profit)
Best diet for size 7
none (0 profit)
Best diet for size 8
none (0 profit)
Best diet for size 9
none (0 profit)
Best diet for size 10
none (0 profit)
Best diet for size 11
none (0 profit)
Best diet for size 12
none (0 profit)
Best diet for size 13
none (0 profit)
Best diet for size 14
none (0 profit)
Best diet for size 15
none (0 profit)
Best diet for size 16
none (0 profit)
Best diet for size 17
none (0 profit)
Best diet for size 18
none (0 profit)
Best diet for size 19
none (0 profit)
Best diet for size 20
none (0 profit)
Best diet for size 1 (23926 profit)
elemental caipiroska (23926 profit)
Best diet for size 2 (47852 profit)
elemental caipiroska (23926 profit)
elemental caipiroska (23926 profit)
Best diet for size 3 (73038 profit)
perfect mimosa (73038 profit)
Best diet for size 4 (96964 profit)
elemental caipiroska (23926 profit)
perfect mimosa (73038 profit)
Best diet for size 5 (120890 profit)
elemental caipiroska (23926 profit)
elemental caipiroska (23926 profit)
perfect mimosa (73038 profit)
Best diet for size 6 (146076 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
Best diet for size 7 (170002 profit)
elemental caipiroska (23926 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
Best diet for size 8 (193928 profit)
elemental caipiroska (23926 profit)
elemental caipiroska (23926 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
Best diet for size 9 (219114 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
Best diet for size 10 (243040 profit)
elemental caipiroska (23926 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
Best diet for size 11 (266966 profit)
elemental caipiroska (23926 profit)
elemental caipiroska (23926 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
Best diet for size 12 (292152 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
Best diet for size 13 (316078 profit)
elemental caipiroska (23926 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
Best diet for size 14 (340004 profit)
elemental caipiroska (23926 profit)
elemental caipiroska (23926 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
Best diet for size 15 (365190 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
Best diet for size 16 (389116 profit)
elemental caipiroska (23926 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
Best diet for size 17 (413042 profit)
elemental caipiroska (23926 profit)
elemental caipiroska (23926 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
Best diet for size 18 (438228 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
Best diet for size 19 (462154 profit)
elemental caipiroska (23926 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
Best diet for size 20 (486080 profit)
elemental caipiroska (23926 profit)
elemental caipiroska (23926 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)

vcon recommends the following 20-fullness diet:

elemental caipiroska (23926 profit)
elemental caipiroska (23926 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
perfect mimosa (73038 profit)
Done!
I'll remove the excess logging and will submit this and then try using it in VMF.
 
I realize that this suite of scripts is designed for use in aftercore but thought I'd ask...would you entertain the idea of allowing vcon to "work" in-run and consider food only from available sources?
 
I realize that this suite of scripts is designed for use in aftercore but thought I'd ask...would you entertain the idea of allowing vcon to "work" in-run and consider food only from available sources?

I too would be interested in VCON as an EatDrink replacement although my recollection is that I was able to do that with the earlier algorithm and so I expect I could do it now, as well.

Tangentially, that said, I would find fighting the tentacle, the NEP, if available, and using VMF to max the still all of interest in run. I have experimented with importing and had some success but last time I tried there were things with outfits that I chose not to resolve. As I recall, the script would use an outfit but the saved outfit of the name could not be equipped in run for any one of several reasons. Since the "best" outfit tends to vary between freeing the king and level 15, or so, and I tend to stash a lot of useful gear in my display case, my personal solution is going to be a script that pulls potentially useful items from the DC, runs the maximizer and then saves the outfit with the appropriate names. But I have not written that yet :-)
 
vcon didn't have an "algorithm" for calculating whole diets before. It calculated "most profitable" food of each size and VMF used that to decide what to consume of various sizes, starting from the largest and considering smaller and smaller foods until you were full.

vcon's current diet calculation recognizes that, say, 2 1-size consumables might be better than 1 2-size consumable and calculates the whole diet.

It's aftercore because:

1) It considers all awesome and EPIC foods
2) It maximizes adventures using "profitable" foods - the expected Meat return must be positive
3) It considers mall prices to decide whether it is profitable.
4) It finds a single best food of each size and uses that

Your diet might be 3 (of the same) size-4 foods and a size-3 food.

An in-run algorithm would need:

1) Consider all foods you have on hand.
2) It wants to maximize adventures; mall price is not a consideration
3) Should it consider storage for Nomal runs? A pull budget would complicate this a lot, I think.
4) For inventory-only, you might have multiple size-n foods with different yields and want to use more than 1 kind.

Your diet might be 3 different size-4 foods (that you have 1 each of) and a size-3 food.

It's an interesting problem, but perhaps would better to make a new library. An in-run-vcon, or something.
 
Revision 308 (which depends on KoLmafia revision 26257) uses retrieve_price() rather than mall_price(). This accounts for the fact that you might be able to craft consumables for less than the cost to buy them. Or, for that matter, simply use items you have in inventory (or storage or any other "allowed" place - which is why it depends on that KoLmafia revision, which fixes a bug).

Using this algorithm, my main, running VMF, is consistently bringing in an additional 300K Meat per day. Of course, she has years of accumulated Stuff in Storage, but I'm happy to use it.
 
Revision 319 works around a current KoLmafia bug:

Items which fill more than one organ reflect that in the proxy record fields.
vcon will not consider items like that, but, at the moment, it can't tell.

This revision adds the {red, green, yellow} drunki-bears to the exclude_list.

Which will be redundant, once the KoLmafia bug is fixed, but is necessary now and harmless in the future.
 
Today I migrated this from sourceforge using SVN to github using GIT.
Future updates will be pushed only to the latter.

I suggest you delete the SVN version (make sure you have KoLmafia r27304!) and then install it via GIT:

Code:
git checkout Veracity0/vcon/[code]
 
Again I am considering vcon as a replacement for eat_drink. I looked at the code and have a couple of questions, Will it consider tiny plastic sword drinks? Will it handle the various chocolates which give adventures but have no consumption cost? Could it value fermented pickle juice so that the cleaned spleen has a meat value related to adventures gained if the spleen were refilled with adventure generating items? Will it use ode and other skills or items that increase yield when consuming? I don't expect it to consider those when optimizing because that gets complex but using them when consuming has some benefit. Can it select the item to overdrink? Will it repair in-the-boxes that break? Now that I ask that I realize I am not certain whether valuation is based strictly on mall prices or on a make/buy tradeoff. In fact now I wonder if the make/buy is deferred to KoLmafia's acquisition logic?

I realize some of the questions are not about vcon as such but about vcon's behavior as observed by watching VMF use it.

Do you have any plans to expose VMF's consumption code?

eat_drink treats organs independently. I decide how full I want an organ and then ask it to fill that organ to that fullness. I usually want to fill to maximum but if need to play pool I choose to drink to 11 and if I am running VMF but not letting it consume then I leave some spleen space so VMF can synthesize.

I can probably figure out some questions on my own - writing this post was definitely a Rubber Ducky type experience but I am lazy enough to ask and adjust to your plans if you have any.

Thank you.
 
vcon is a library that can be used to implement a diet planner.

Based on your valueOfAdventure, it will look at all items that give adventures in exchange for liver/stomach/spleen and calculates the most cost effective consumable/per size for each organ. A diet planner could use that information and determine how to fill your various organs.

vcon also provides calculate_diet( consumables_by_size candidates, int capacity ), given a list of candidates for a single organ and the size you want to fill.

- it does not know about organ cleansers (hobopolis/batfellow items, mojo filters).
- it does not know about items that grant adventures without filling organs. (chocolates, blue mana + Ancestral Recall)
- it does not take items that provide Meat or Item buffs into account, since it does not know if you are Meat or Item farming - or neither.

I wrote it because VMF needed something better for planning a diet than the hard-coded consumables I started with.
And I was not willing to trust a 3rd-party script to do it for me. :)

eat_drink was the first published diet planner, I believe. I have never even looked at it.

VMF has a bespoke diet planner in it that uses vcon's calculate_diet. It has a function fill(ORGAN) which has a few hard-coded things in it: if you have jumping horseradishes - which you can generate 5 per day with free adventures and have a good meat buff - it considers them. (It also considers Dinsey food cones - if you have FunFunds and are farming Barf - for the Meat buff. I have just put that under a config property, since I now think I might be better off using my FunFunds for day passes - especially for characters who have to use day passes to go there.)

VMF's eat_up, drink_up and spleen_up functions cast Ode, use milk of magnesium, use Mayoflex, if appropriate, use (some of) your spleen for Sweet Synthesize and spacing out Calculate the Universe, if needed, and so on.

I am considering extracting VMF's diet planner + consumer into a stand-alone script - at least down to fill and consume, which use drink(), eat_food(), and chew() - which I can configure and tune as desired and use for different purposes.
For example, I am currently involved in a big spading project with the Beach Comb - whose turns generate no Meat. What IS my ValueOfAdventure for this project?

For you, I think I would recommend soolar's CONSUME - although I have never used that, either. It does all the things you asked about, and seems to be well supported and popular. And it is a stand-alone diet planner - and CONSUMER - unlike vmf's which is currently built-in to VMF.
 
Back
Top