Skip to content

Commit

Permalink
Use COOKED and RAW flags in nutrient predictions
Browse files Browse the repository at this point in the history
To predict nutrient content we need to also predict changes to the item
flags that occur when cooking.  Implement that, and add a test to verify
that it works correctly for cooked wild veggies.
  • Loading branch information
jbytheway committed Dec 22, 2019
1 parent f5c1962 commit b196175
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 15 deletions.
30 changes: 20 additions & 10 deletions src/consumption.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ int player::stomach_capacity() const
}

// TODO: Move pizza scraping here.
static int compute_default_effective_kcal( const item &comest, const player &p )
static int compute_default_effective_kcal( const item &comest, const player &p,
const cata::flat_set<std::string> &extra_flags = {} )
{
static const trait_id trait_CARNIVORE( "CARNIVORE" );
static const trait_id trait_GIZZARD( "GIZZARD" );
Expand All @@ -113,7 +114,8 @@ static int compute_default_effective_kcal( const item &comest, const player &p )
float kcal = comest.get_comestible()->default_nutrition.kcal;

// Many raw foods give less calories, as your body has expends more energy digesting them.
if( comest.has_flag( "RAW" ) && !comest.has_flag( "COOKED" ) ) {
bool cooked = comest.has_flag( "COOKED" ) || extra_flags.count( "COOKED" );
if( comest.has_flag( "RAW" ) && !cooked ) {
kcal *= 0.75f;
}

Expand Down Expand Up @@ -179,9 +181,9 @@ static std::map<vitamin_id, int> compute_default_effective_vitamins(
// Calculate the effective nutrients for a given item, taking
// into account player traits but not item components.
static nutrients compute_default_effective_nutrients( const item &comest,
const player &p )
const player &p, const cata::flat_set<std::string> &extra_flags = {} )
{
return { compute_default_effective_kcal( comest, p ),
return { compute_default_effective_kcal( comest, p, extra_flags ),
compute_default_effective_vitamins( comest, p ) };
}

Expand Down Expand Up @@ -215,8 +217,9 @@ nutrients player::compute_effective_nutrients( const item &comest ) const

// Calculate range of nutrients obtainable for a given item when crafted via
// the given recipe
std::pair<nutrients, nutrients> player::compute_nutrient_range( const item &comest,
const recipe_id &recipe_i ) const
std::pair<nutrients, nutrients> player::compute_nutrient_range(
const item &comest, const recipe_id &recipe_i,
const cata::flat_set<std::string> &extra_flags ) const
{
if( !comest.is_comestible() ) {
return {};
Expand All @@ -233,6 +236,12 @@ std::pair<nutrients, nutrients> player::compute_nutrient_range( const item &come

const recipe &rec = *recipe_i;

cata::flat_set<std::string> our_extra_flags = extra_flags;

if( rec.hot_result() ) {
our_extra_flags.insert( "COOKED" );
}

const requirement_data requirements = rec.requirements();
const requirement_data::alter_item_comp_vector &component_requirements =
requirements.get_components();
Expand All @@ -243,7 +252,7 @@ std::pair<nutrients, nutrients> player::compute_nutrient_range( const item &come
bool first = true;
for( const item_comp &component_option : component_options ) {
std::pair<nutrients, nutrients> component_option_range =
compute_nutrient_range( component_option.type );
compute_nutrient_range( component_option.type, our_extra_flags );
component_option_range.first *= component_option.count;
component_option_range.second *= component_option.count;

Expand Down Expand Up @@ -272,7 +281,8 @@ std::pair<nutrients, nutrients> player::compute_nutrient_range( const item &come

// Calculate the range of nturients possible for a given item across all
// possible recipes
std::pair<nutrients, nutrients> player::compute_nutrient_range( const itype_id &comest_id ) const
std::pair<nutrients, nutrients> player::compute_nutrient_range(
const itype_id &comest_id, const cata::flat_set<std::string> &extra_flags ) const
{
const itype *comest = item::find_type( comest_id );
if( !comest->comestible ) {
Expand All @@ -281,7 +291,7 @@ std::pair<nutrients, nutrients> player::compute_nutrient_range( const itype_id &

item comest_it( comest, calendar::turn, 1 );
// The default nutrients are always a possibility
nutrients min_nutr = compute_default_effective_nutrients( comest_it, *this );
nutrients min_nutr = compute_default_effective_nutrients( comest_it, *this, extra_flags );

if( comest->item_tags.count( "NUTRIENT_OVERRIDE" ) ||
recipe_dict.is_item_on_loop( comest->get_id() ) ) {
Expand All @@ -305,7 +315,7 @@ std::pair<nutrients, nutrients> player::compute_nutrient_range( const itype_id &
debugmsg( "When creating recipe result expected %s, got %s\n",
comest_it.typeId(), result_it.typeId() );
}
std::tie( this_min, this_max ) = compute_nutrient_range( result_it, rec );
std::tie( this_min, this_max ) = compute_nutrient_range( result_it, rec, extra_flags );
min_nutr.min_in_place( this_min );
max_nutr.max_in_place( this_max );
}
Expand Down
8 changes: 5 additions & 3 deletions src/player.h
Original file line number Diff line number Diff line change
Expand Up @@ -673,10 +673,12 @@ class player : public Character
nutrients compute_effective_nutrients( const item & ) const;
/** Get range of possible nutrient content, for a particular recipe,
* depending on choice of ingredients */
std::pair<nutrients, nutrients> compute_nutrient_range( const item &,
const recipe_id & ) const;
std::pair<nutrients, nutrients> compute_nutrient_range(
const item &, const recipe_id &,
const cata::flat_set<std::string> &extra_flags = {} ) const;
/** Same, but across arbitrary recipes */
std::pair<nutrients, nutrients> compute_nutrient_range( const itype_id & ) const;
std::pair<nutrients, nutrients> compute_nutrient_range(
const itype_id &, const cata::flat_set<std::string> &extra_flags = {} ) const;

/** Get vitamin usage rate (minutes per unit) accounting for bionics, mutations and effects */
time_duration vitamin_rate( const vitamin_id &vit ) const;
Expand Down
21 changes: 20 additions & 1 deletion tests/comestible_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
#include <utility>
#include <vector>

#include "avatar.h"
#include "catch/catch.hpp"
#include "game.h"
#include "itype.h"
#include "recipe_dictionary.h"
#include "recipe.h"
Expand Down Expand Up @@ -108,7 +110,7 @@ static item food_or_food_container( const item &it )
return it.is_food_container() ? it.contents.front() : it;
}

TEST_CASE( "recipe_permutations" )
TEST_CASE( "recipe_permutations", "[recipe]" )
{
// Are these tests failing? Here's how to fix that:
// If the average is over the upper bound, you need to increase the calories for the item
Expand Down Expand Up @@ -155,3 +157,20 @@ TEST_CASE( "recipe_permutations" )
}
}
}

TEST_CASE( "cooked_veggies_get_correct_calorie_prediction", "[recipe]" )
{
// This test verifies that predicted calorie ranges properly take into
// account the "RAW"/"COOKED" flags.
const item veggy_wild_cooked( "veggy_wild_cooked" );
const recipe_id veggy_wild_cooked_recipe( "veggy_wild_cooked" );

const avatar &u = g->u;

nutrients default_nutrition = u.compute_effective_nutrients( veggy_wild_cooked );
std::pair<nutrients, nutrients> predicted_nutrition =
u.compute_nutrient_range( veggy_wild_cooked, veggy_wild_cooked_recipe );

CHECK( default_nutrition.kcal == predicted_nutrition.first.kcal );
CHECK( default_nutrition.kcal == predicted_nutrition.second.kcal );
}
2 changes: 1 addition & 1 deletion tests/iteminfo_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ TEST_CASE( "nutrient_ranges_for_recipe_exemplars", "[item][iteminfo]" )
i, q,
"--\n"
"Nutrition will <color_cyan>vary with chosen ingredients</color>.\n"
"<color_c_white>Calories (kcal)</color>: <color_c_yellow>313</color>-"
"<color_c_white>Calories (kcal)</color>: <color_c_yellow>317</color>-"
"<color_c_yellow>469</color> Quench: <color_c_yellow>0</color>\n"
"Vitamins (RDA): Calcium (7-28%), Iron (0-83%), "
"Vitamin A (3-11%), Vitamin B12 (2-6%), and Vitamin C (1-85%)\n" );
Expand Down

0 comments on commit b196175

Please sign in to comment.