Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

increase kcal spent walking with carry weight #36862

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions src/character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6900,16 +6900,26 @@ int Character::height() const
return height;
}

float Character::weight_bmr_modifier() const
{
units::mass carried_weight = get_weight() - bodyweight();
const float weight_ratio = units::to_gram<float>( carried_weight )
/ units::to_gram<float>( bodyweight() );
const float percentage = 0.008f * units::to_kilogram( get_weight() ) * pow( weight_ratio, 2 );
return 1.0f + std::max( 0.0f, percentage );
}

int Character::get_bmr() const
{
/**
Values are for males, and average!
*/
const int age = 25;
const int equation_constant = 5;
return ceil( metabolic_rate_base() * activity_level * ( units::to_gram<int>
( bodyweight() / 100.0 ) +
( 6.25 * height() ) - ( 5 * age ) + equation_constant ) );
const double base_bmr = metabolic_rate_base() * activity_level * ( units::to_gram<int>
( bodyweight() / 100.0 ) +
( 6.25 * height() ) - ( 5 * age ) + equation_constant );
return ceil( base_bmr * weight_bmr_modifier() );
}

void Character::increase_activity_level( float new_level )
Expand Down
2 changes: 2 additions & 0 deletions src/character.h
Original file line number Diff line number Diff line change
Expand Up @@ -1567,6 +1567,8 @@ class Character : public Creature, public visitable<Character>
float get_bmi() const;
// returns amount of calories burned in a day given various metabolic factors
int get_bmr() const;
// redurns a modifier for bmr based on weight carried and weight of player
float weight_bmr_modifier() const;
// returns the height of the player character in cm
int height() const;
// returns bodyweight of the Character
Expand Down
8 changes: 4 additions & 4 deletions src/game_constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,10 +164,10 @@ constexpr int SIMPLEX_NOISE_RANDOM_SEED_LIMIT = 32768;
* did this activity for a longer period of time.
*/
constexpr float NO_EXERCISE = 1.2f;
constexpr float LIGHT_EXERCISE = 1.375f;
constexpr float MODERATE_EXERCISE = 1.55f;
constexpr float ACTIVE_EXERCISE = 1.725f;
constexpr float EXTRA_EXERCISE = 1.9f;
constexpr float LIGHT_EXERCISE = 1.375f * 2.5f;
constexpr float MODERATE_EXERCISE = 1.55f * 6;
constexpr float ACTIVE_EXERCISE = 1.725f * 9;
constexpr float EXTRA_EXERCISE = 1.9f * 14;

// these are the lower bounds of each of the weight classes.
namespace character_weight_category
Expand Down
134 changes: 134 additions & 0 deletions tests/hiking_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
#include "catch/catch.hpp"

#include "avatar.h"
#include "avatar_action.h"
#include "calendar.h"
#include "character.h"
#include "game.h"
#include "map.h"
#include "map_helpers.h"
#include "player_helpers.h"
#include "point.h"
#include "units.h"

static void remain_centered( const tripoint &center, avatar &dummy )
{
if( dummy.pos().x < SEEX * int( MAPSIZE / 2 ) ||
dummy.pos().y < SEEY * int( MAPSIZE / 2 ) ||
dummy.pos().x >= SEEX * ( 1 + int( MAPSIZE / 2 ) ) ||
dummy.pos().y >= SEEY * ( 1 + int( MAPSIZE / 2 ) ) ) {
dummy.setpos( center );
// Verify that only the player is present.
REQUIRE( g->num_creatures() == 1 );
}
}

static int distance_test( avatar &dummy, const time_duration &time_spent )
{
clear_map();
dummy.set_stored_kcal( dummy.get_healthy_kcal() );
dummy.stomach.empty();
dummy.guts.empty();
dummy.moves = dummy.get_speed();
const tripoint center{ 65, 65, 0 };
const time_point start = calendar::turn;
int calories_spent = 0;
int tiles_moved = 0;
while( start + time_spent > calendar::turn ) {
const int calories_before = dummy.get_stored_kcal();
avatar_action::move( dummy, g->m, dummy.pos() + tripoint_east );
++tiles_moved;
remain_centered( center, dummy );

dummy.update_body();
dummy.process_turn();
calendar::turn += 1_turns;
calories_spent += calories_before - dummy.get_stored_kcal();
}
printf( "player weight: %.2f kg, bmr: %d\n", units::to_kilogram( dummy.get_weight() ),
dummy.get_bmr() );
return calories_spent;
}

static bool between( const int num, const int lower, const int high )
{
return num < high && num > lower;
}

static void test_carry( units::mass carry_weight, int min_cal, int max_cal,
character_movemode mode = character_movemode::CMM_WALK )
{
item bag( "bigback" );
REQUIRE( carry_weight >= bag.weight() );
carry_weight -= bag.weight();
clear_avatar();
avatar &dummy = g->u;
dummy.reset_move_mode();
if( mode == character_movemode::CMM_RUN ) {
dummy.toggle_run_mode();
}
dummy.i_add( bag );
dummy.wear( bag, false );
dummy.i_add( item( "thread", calendar::turn, units::to_gram( carry_weight ) ) );
const int cal_spent = distance_test( dummy, 1_hours );
CAPTURE( cal_spent );
CHECK( between( cal_spent, min_cal, max_cal ) );
}

TEST_CASE( "naked_walk", "[hike]" )
{
clear_avatar();
avatar &dummy = g->u;
const int cal_spent = distance_test( dummy, 1_hours );
CAPTURE( cal_spent );
CHECK( between( cal_spent, 204, 234 ) );
}

TEST_CASE( "naked_run", "[hike]" )
{
clear_avatar();
avatar &dummy = g->u;
dummy.toggle_run_mode();
const int cal_spent = distance_test( dummy, 1_hours );
CAPTURE( cal_spent );
CHECK( between( cal_spent, 1032, 1200 ) );
}

TEST_CASE( "walk_carry", "[hike]" )
{
SECTION( "10 kg" ) {
test_carry( 10000_gram, 230, 260 );
}
SECTION( "20 kg" ) {
test_carry( 20000_gram, 242, 272 );
}
SECTION( "30 kg" ) {
test_carry( 30000_gram, 270, 300 );
}
SECTION( "40 kg" ) {
test_carry( 40000_gram, 306, 336 );
}
SECTION( "60 kg" ) {
test_carry( 60000_gram, 412, 442 );
}
}

TEST_CASE( "run_carry", "[hike]" )
{
const character_movemode run = character_movemode::CMM_RUN;
SECTION( "10 kg" ) {
test_carry( 10000_gram, 1120, 1140, run );
}
SECTION( "20 kg" ) {
test_carry( 20000_gram, 1180, 1200, run );
}
SECTION( "30 kg" ) {
test_carry( 30000_gram, 1260, 1280, run );
}
SECTION( "40 kg" ) {
test_carry( 40000_gram, 1400, 1420, run );
}
SECTION( "60 kg" ) {
test_carry( 60000_gram, 1880, 1900, run );
}
}
1 change: 1 addition & 0 deletions tests/player_helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ void clear_character( player &dummy, bool debug_storage )

const tripoint spot( 60, 60, 0 );
g->place_player( spot );
dummy.reset_activity_level();
}

void clear_avatar()
Expand Down