Skip to content

Commit

Permalink
tests: Overhaul running loop to count moves/steps
Browse files Browse the repository at this point in the history
WIP

To more correctly count the number of *steps* (tiles) when running,
check moves and increment turn only when moves go subzero.

Adjust test expectations to fit new actual results, which are slightly
less than before (and still substantially less than in-game running).
  • Loading branch information
wapcaplet committed Dec 28, 2021
1 parent 71c6ca5 commit ef74300
Showing 1 changed file with 62 additions and 39 deletions.
101 changes: 62 additions & 39 deletions tests/cardio_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ static void verify_default_cardio_options()
REQUIRE( cardiofit_stamina_scaling == 3 );
}

// Count how many turns of running it takes for character to run out of stamina or become winded
// Count the number of steps (tiles) until character runs out of stamina or becomes winded.
// FIXME: This underestimates total running distance by 10-15% relative to in-game measurement.
// (For example, a normal character can run 98 steps in-game, but only 87 with this function).
static int running_turns( Character &they, const ter_id &terrain = t_pavement )
static int running_steps( Character &they, const ter_id &terrain = t_pavement )
{
map &here = get_map();
// Please take off your shoes when entering, and no NPCs allowed
Expand All @@ -72,32 +72,53 @@ static int running_turns( Character &they, const ter_id &terrain = t_pavement )
here.ter_set( right, terrain );
REQUIRE( here.ter( left ) == terrain );
REQUIRE( here.ter( right ) == terrain );
// Count how many steps (1-tile moves) it takes to become winded
int steps = 0;
const int STOP_STEPS = 1000; // Safe exit in case of Superman
// Track changes to moves and stamina
int last_moves = they.get_speed();
int last_stamina = they.get_stamina_max();

// Take a deep breath and start running
they.set_stamina( they.get_stamina_max() );
they.moves = last_moves;
they.set_stamina( last_stamina );
they.set_movement_mode( move_mode_run );
they.update_body();
// Count how many turns it takes to become winded
int turns = 0;
int STOP = 1000; // Safe exit in case of Superman
int last_stamina = they.get_stamina_max();
// Run until out of stamina or winded (should happen at the same time)
while( they.get_stamina() > 0 && !they.has_effect( effect_winded ) && turns < STOP ) {
// Step right on even turns, left on odd turns
if( turns % 2 == 0 ) {
g->walk_move( right, false, false );
while( they.get_stamina() > 0 && !they.has_effect( effect_winded ) && steps < STOP_STEPS ) {
// Step right on even steps, left on odd steps
if( steps % 2 == 0 ) {
REQUIRE( they.pos() == left );
REQUIRE( g->walk_move( right, false, false ) );
} else {
g->walk_move( left, false, false );
REQUIRE( they.pos() == right );
REQUIRE( g->walk_move( left, false, false ) );
}
// Count the turns
++turns;
calendar::turn += 1_turns;
++steps;

// Ensure moves are decreasing, or else a turn will never pass
REQUIRE( they.moves < last_moves );
const int move_cost = last_moves - they.moves;
// When moves run out, one turn has passed
if( they.moves <= 0 ) {
// Get "speed" moves back each turn
they.moves += they.get_speed();
calendar::turn += 1_turns;
}
last_moves = they.moves;

// Update body for stamina regen
they.update_body();
// Stamina must be decreasing; if not, quit
CAPTURE( last_stamina - they.get_stamina() );
// NOTE: Stamina cost is always 100, 101, 120, or 121 ??
const int stamina_cost = last_stamina - they.get_stamina();
// Total stamina must also be decreasing; if not, quit
CAPTURE( move_cost );
CAPTURE( stamina_cost );
REQUIRE( they.get_stamina() < last_stamina );
last_stamina = they.get_stamina();
}
return turns;
// Reset to starting position
they.setpos( left );
return steps;
}

// Give character a trait, and verify their expected cardio, max stamina, and running distance.
Expand All @@ -114,7 +135,8 @@ static void check_trait_cardio_stamina_run( Character &they, std::string trait_n
CHECK( they.get_cardiofit() == Approx( expect_cardio_fit ).margin( 2 ) );
CHECK( they.get_stamina_max() == Approx( expect_stamina_max ).margin( 5 ) );
//CHECK( they.get_stamina_max() == Approx( 3500 + 3 * expect_cardio_fit ).margin( 2 ) );
CHECK( running_turns( they ) == Approx( expect_run_tiles ).margin( 1 ) );
// FIXME: May need a larger margin here
CHECK( running_steps( they ) == Approx( expect_run_tiles ).margin( 1 ) );
}
}

Expand Down Expand Up @@ -165,19 +187,20 @@ TEST_CASE( "cardio is affected by certain traits", "[cardio][traits]" )

SECTION( "Base character with no traits" ) {
// pre-Cardio, could run 96 steps
// post-Cardio, can run 84 steps in-game, test case reaches 87
check_trait_cardio_stamina_run( they, "", base_cardio, base_stamina, 87 ); //96
// post-Cardio, can run 84 steps in-game, test case reached 87
// correctly counting moves/steps instead of turns, test case reaches 83
check_trait_cardio_stamina_run( they, "", base_cardio, base_stamina, 83 ); //96
}

// Sprint distance for each body size is only slightly different than it was before cardio
SECTION( "Traits affecting body size" ) {
// Body size determines BMR, which affects base cardio fitness
// Pre-Cardio, body size did not affect how many steps you could run
check_trait_cardio_stamina_run( they, "SMALL2", 1088, 6764, 95 ); //97
check_trait_cardio_stamina_run( they, "SMALL2", 1088, 6764, 83 ); //97
// FIXME: But why the heck can SMALL2 run further than SMALL?
check_trait_cardio_stamina_run( they, "SMALL", 1376, 7628, 82 ); //97
check_trait_cardio_stamina_run( they, "LARGE", 2162, 9986, 97 ); //97
check_trait_cardio_stamina_run( they, "HUGE", 2663, 11489, 109 ); //97
check_trait_cardio_stamina_run( they, "SMALL", 1376, 7628, 77 ); //97
check_trait_cardio_stamina_run( they, "LARGE", 2162, 9986, 92 ); //97
check_trait_cardio_stamina_run( they, "HUGE", 2663, 11489, 106 ); //97
}

SECTION( "Traits with cardio_multiplier" ) {
Expand All @@ -187,35 +210,35 @@ TEST_CASE( "cardio is affected by certain traits", "[cardio][traits]" )
// Languorous
check_trait_cardio_stamina_run( they, "BADCARDIO", 0.7 * base_cardio, 7148, 67 ); //70
// Indefatigable
check_trait_cardio_stamina_run( they, "GOODCARDIO", 1.3 * base_cardio, 10277, 109 ); //126
check_trait_cardio_stamina_run( they, "GOODCARDIO", 1.3 * base_cardio, 10277, 103 ); //126
// Hyperactive
check_trait_cardio_stamina_run( they, "GOODCARDIO2", 1.6 * base_cardio, 11840, 134 ); //145
check_trait_cardio_stamina_run( they, "GOODCARDIO2", 1.6 * base_cardio, 11840, 125 ); //145
}

// FIXME: These traits need a significant nerf (-8 to -32) to reach their pre-Cardio balance
SECTION( "Traits with metabolism_modifier AND stamina_regen_modifier" ) {
// Fast Metabolism
check_trait_cardio_stamina_run( they, "HUNGER", 2173, 10019, 98 ); //76
check_trait_cardio_stamina_run( they, "HUNGER", 2173, 10019, 95 ); //76
// Very Fast Metabolism
check_trait_cardio_stamina_run( they, "HUNGER2", 2608, 11324, 112 ); //87
check_trait_cardio_stamina_run( they, "HUNGER2", 2608, 11324, 108 ); //87
// Extreme Metabolism
check_trait_cardio_stamina_run( they, "HUNGER3", 3477, 13931, 139 ); //107
check_trait_cardio_stamina_run( they, "HUNGER3", 3477, 13931, 132 ); //107
}

// FIXME: These traits need a significant nerf (-20) to reach their pre-Cardio balance
SECTION( "Traits with ONLY stamina_regen_modifier" ) {
check_trait_cardio_stamina_run( they, "PERSISTENCE_HUNTER", base_cardio, base_stamina, 89 ); //68
check_trait_cardio_stamina_run( they, "PERSISTENCE_HUNTER2", base_cardio, base_stamina, 90 ); //69
check_trait_cardio_stamina_run( they, "PERSISTENCE_HUNTER", base_cardio, base_stamina, 85 ); //68
check_trait_cardio_stamina_run( they, "PERSISTENCE_HUNTER2", base_cardio, base_stamina, 86 ); //69
}

// FIXME: These traits need a significant nerf (-20) to reach their pre-Cardio balance
SECTION( "Traits with ONLY metabolism_modifier" ) {
check_trait_cardio_stamina_run( they, "COLDBLOOD", 1449, 7847, 82 ); //63
check_trait_cardio_stamina_run( they, "COLDBLOOD2", 1304, 7412, 82 ); //62
check_trait_cardio_stamina_run( they, "COLDBLOOD3", 1304, 7412, 82 ); //62
check_trait_cardio_stamina_run( they, "COLDBLOOD4", 1304, 7412, 82 ); //62
check_trait_cardio_stamina_run( they, "LIGHTEATER", 1449, 7847, 82 ); //63
check_trait_cardio_stamina_run( they, "MET_RAT", 2028, 9584, 93 ); //72
check_trait_cardio_stamina_run( they, "COLDBLOOD", 1449, 7847, 78 ); //63
check_trait_cardio_stamina_run( they, "COLDBLOOD2", 1304, 7412, 77 ); //62
check_trait_cardio_stamina_run( they, "COLDBLOOD3", 1304, 7412, 77 ); //62
check_trait_cardio_stamina_run( they, "COLDBLOOD4", 1304, 7412, 77 ); //62
check_trait_cardio_stamina_run( they, "LIGHTEATER", 1449, 7847, 78 ); //63
check_trait_cardio_stamina_run( they, "MET_RAT", 2028, 9584, 90 ); //72
}
}

Expand Down

0 comments on commit ef74300

Please sign in to comment.