Skip to content

Commit

Permalink
Reduce weariness instability (includes tests); clarified (#47653)
Browse files Browse the repository at this point in the history
Co-authored-by: anothersimulacrum <anothersimulacrum@gmail.com>
  • Loading branch information
actual-nh and anothersimulacrum authored Apr 7, 2021
1 parent 6c29c71 commit a728b7c
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 27 deletions.
20 changes: 11 additions & 9 deletions src/activity_tracker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "options.h"
#include "string_formatter.h"

#include <cmath>
#include <limits>

int activity_tracker::weariness() const
Expand All @@ -28,22 +29,23 @@ void activity_tracker::try_reduce_weariness( int bmr, bool sleeping )

const float recovery_mult = get_option<float>( "WEARY_RECOVERY_MULT" );

if( low_activity_ticks >= 6 ) {
if( low_activity_ticks >= 1 ) {
int reduction = tracker;
// 1/20 of whichever's bigger
// 1/120 of whichever's bigger
if( bmr > reduction ) {
reduction = bmr * recovery_mult;
reduction = std::floor( bmr * recovery_mult * low_activity_ticks / 6.0f );
} else {
reduction *= recovery_mult;
reduction = std::ceil( reduction * recovery_mult * low_activity_ticks / 6.0f );
}
low_activity_ticks -= 6;
low_activity_ticks = 0;

tracker -= reduction;
tracker -= std::max( reduction, 1 );
}

if( tick_counter >= 12 ) {
intake *= 1 - recovery_mult;
tick_counter -= 12;
// If happens to be no reduction, character is not (as) hypoglycemic
if( tick_counter >= 3 ) {
intake *= std::pow( 1 - recovery_mult, 0.25f );
tick_counter -= 3;
}

// Normalize values, make sure we stay above 0
Expand Down
11 changes: 11 additions & 0 deletions tests/activity_scheduling_helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,17 @@ int weariness_events::transition_minutes( const int from, const int to,
return ret.first;
}

bool weariness_events::have_weary_decrease() const
{
for( const weary_transition &change : transitions ) {
if( change.from > change.to ) {
return true;
}
}

return false;
}

std::string weariness_events::summarize() const
{
std::string buffer;
Expand Down
2 changes: 2 additions & 0 deletions tests/activity_scheduling_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ struct weariness_events {
// if around = 0_seconds or equivalent, otherwise return the time closest to around
int transition_minutes( int from, int to, const time_duration &around ) const;

bool have_weary_decrease() const;

std::string summarize() const;

bool empty() const;
Expand Down
49 changes: 31 additions & 18 deletions tests/weary_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,32 +58,38 @@ TEST_CASE( "weary_assorted_tasks", "[weary][activities]" )
INFO( guy.debug_weary_info() );
REQUIRE( !info.empty() );
CHECK( info.transition_minutes( 0, 1, 370_minutes ) == Approx( 370 ).margin( 5 ) );
CHECK( !info.have_weary_decrease() );
CHECK( guy.weariness_level() == 1 );
}

SECTION( "Heavy tasks" ) {
INFO( "\nDigging Pits 8 hours:" );
SECTION( "Heavy tasks - Digging Pits 8 hours" ) {
clear_avatar();
INFO( guy.debug_weary_info() );
weariness_events info = do_activity( soldier_8h );
INFO( info.summarize() );
INFO( guy.debug_weary_info() );
REQUIRE( !info.empty() );
CHECK( info.transition_minutes( 0, 1, 120_minutes ) == Approx( 120 ).margin( 5 ) );
CHECK( info.transition_minutes( 1, 2, 255_minutes ) == Approx( 255 ).margin( 5 ) );
CHECK( info.transition_minutes( 1, 2, 250_minutes ) == Approx( 250 ).margin( 5 ) );
CHECK( info.transition_minutes( 2, 3, 360_minutes ) == Approx( 360 ).margin( 5 ) );
CHECK( info.transition_minutes( 3, 4, 470_minutes ) == Approx( 470 ).margin( 5 ) );
CHECK( info.transition_minutes( 3, 4, 465_minutes ) == Approx( 465 ).margin( 5 ) );
// CHECK( !info.have_weary_decrease() );
CHECK( guy.weariness_level() == 4 );
}

INFO( "\nDigging Pits 12 hours:" );
info = do_activity( soldier_12h );
SECTION( "Heavy tasks - Digging Pits 12 hours" ) {
clear_avatar();
INFO( guy.debug_weary_info() );
weariness_events info = do_activity( soldier_12h );
INFO( info.summarize() );
INFO( guy.debug_weary_info() );
REQUIRE( !info.empty() );
CHECK( info.transition_minutes( 0, 1, 120_minutes ) == Approx( 120 ).margin( 5 ) );
CHECK( info.transition_minutes( 1, 2, 245_minutes ) == Approx( 245 ).margin( 5 ) );
CHECK( info.transition_minutes( 2, 3, 355_minutes ) == Approx( 355 ).margin( 5 ) );
CHECK( info.transition_minutes( 1, 2, 250_minutes ) == Approx( 250 ).margin( 5 ) );
CHECK( info.transition_minutes( 2, 3, 360_minutes ) == Approx( 360 ).margin( 5 ) );
CHECK( info.transition_minutes( 3, 4, 465_minutes ) == Approx( 465 ).margin( 5 ) );
CHECK( info.transition_minutes( 4, 5, 595_minutes ) == Approx( 595 ).margin( 5 ) );
CHECK( info.transition_minutes( 4, 5, 600_minutes ) == Approx( 600 ).margin( 5 ) );
// CHECK( !info.have_weary_decrease() );
CHECK( guy.weariness_level() == 5 );
}
}
Expand Down Expand Up @@ -126,8 +132,13 @@ TEST_CASE( "weary_recovery", "[weary][activities]" )
INFO( info.summarize() );
INFO( guy.debug_weary_info() );
REQUIRE( !info.empty() );
CHECK( info.transition_minutes( 4, 3, 520_minutes ) == Approx( 520 ).margin( 5 ) );
CHECK( info.transition_minutes( 3, 2, 670_minutes ) == Approx( 670 ).margin( 5 ) );
CHECK( info.transition_minutes( 4, 3, 505_minutes ) == Approx( 505 ).margin( 5 ) );
CHECK( info.transition_minutes( 3, 2, 630_minutes ) == Approx( 630 ).margin( 5 ) );
CHECK( info.transition_minutes( 1, 0, 0_minutes ) > ( 8 * 60 ) ); // should be INT_MAX
CHECK( info.transition_minutes( 2, 1, 0_minutes ) > ( 8 * 60 ) );
CHECK( info.transition_minutes( 1, 2, 16_hours ) <= ( 8 * 60 ) );
CHECK( info.transition_minutes( 2, 3, 16_hours ) <= ( 8 * 60 ) );
CHECK( info.transition_minutes( 3, 4, 16_hours ) <= ( 8 * 60 ) );
CHECK( guy.weariness_level() == 1 );
}

Expand All @@ -140,8 +151,8 @@ TEST_CASE( "weary_recovery", "[weary][activities]" )
REQUIRE( !info.empty() );
CHECK( info.transition_minutes( 0, 1, 325_minutes ) == Approx( 325 ).margin( 5 ) );
CHECK( info.transition_minutes( 1, 2, 625_minutes ) == Approx( 625 ).margin( 5 ) );
CHECK( info.transition_minutes( 2, 1, 740_minutes ) == Approx( 740 ).margin( 5 ) );
CHECK( info.transition_minutes( 1, 0, 995_minutes ) == Approx( 995 ).margin( 5 ) );
CHECK( info.transition_minutes( 2, 1, 735_minutes ) == Approx( 735 ).margin( 5 ) );
CHECK( info.transition_minutes( 1, 0, 985_minutes ) == Approx( 985 ).margin( 5 ) );
}
}

Expand All @@ -166,6 +177,7 @@ TEST_CASE( "weary_24h_tasks", "[weary][activities]" )
}

SECTION( "Digging 24 hours" ) {
clear_avatar();
INFO( guy.debug_weary_info() );
weariness_events info = do_activity( digging_24h );
INFO( info.summarize() );
Expand All @@ -174,11 +186,12 @@ TEST_CASE( "weary_24h_tasks", "[weary][activities]" )
CHECK( info.transition_minutes( 0, 1, 120_minutes ) == Approx( 120 ).margin( 5 ) );
CHECK( info.transition_minutes( 1, 2, 250_minutes ) == Approx( 250 ).margin( 5 ) );
CHECK( info.transition_minutes( 2, 3, 360_minutes ) == Approx( 360 ).margin( 5 ) );
CHECK( info.transition_minutes( 3, 4, 470_minutes ) == Approx( 470 ).margin( 5 ) );
CHECK( info.transition_minutes( 4, 5, 595_minutes ) == Approx( 595 ).margin( 5 ) );
CHECK( info.transition_minutes( 5, 6, 730_minutes ) == Approx( 730 ).margin( 5 ) );
CHECK( info.transition_minutes( 6, 7, 835_minutes ) == Approx( 835 ).margin( 5 ) );
CHECK( info.transition_minutes( 7, 8, 915_minutes ) == Approx( 915 ).margin( 10 ) );
CHECK( info.transition_minutes( 3, 4, 465_minutes ) == Approx( 465 ).margin( 5 ) );
CHECK( info.transition_minutes( 4, 5, 600_minutes ) == Approx( 600 ).margin( 5 ) );
CHECK( info.transition_minutes( 5, 6, 740_minutes ) == Approx( 740 ).margin( 5 ) );
CHECK( info.transition_minutes( 6, 7, 845_minutes ) == Approx( 845 ).margin( 5 ) );
CHECK( info.transition_minutes( 7, 8, 925_minutes ) == Approx( 925 ).margin( 10 ) );
CHECK( !info.have_weary_decrease() );
// TODO: You should collapse from this - currently we
// just get really high levels of weariness
CHECK( guy.weariness_level() > 8 );
Expand Down

0 comments on commit a728b7c

Please sign in to comment.