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

Cache pathfinding results to speed up calculations #1541

Merged
merged 40 commits into from
Sep 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
875ddd5
Add new files
idshibanov Aug 26, 2020
0da1c0b
Convert to class
idshibanov Aug 26, 2020
71a24c0
Move world files into new folder
idshibanov Aug 26, 2020
a8e1699
Update node structure
idshibanov Aug 26, 2020
2678b21
Add VS include directory
idshibanov Aug 26, 2020
91e15ec
Plug in pathfinder
idshibanov Aug 27, 2020
5155a28
Instant distance prediction
idshibanov Aug 27, 2020
c3a62e4
Test new pathfinding
idshibanov Sep 4, 2020
944ab10
Share tile passable call
idshibanov Sep 4, 2020
cd3fdc7
Fix move cost
idshibanov Sep 4, 2020
bf23401
Move passability rules to World class
idshibanov Sep 5, 2020
ec117e8
Fix the destination object logic
idshibanov Sep 5, 2020
706278e
Merge branch 'master' of https://github.com/ihhub/fheroes2.git into p…
idshibanov Sep 5, 2020
a8e635a
Remove unused code
idshibanov Sep 6, 2020
e4e3be7
Code style correction
ihhub Sep 7, 2020
bbcbb8b
Make clang-format happy
ihhub Sep 7, 2020
f5cf3d4
Address feedback
idshibanov Sep 7, 2020
cd4d988
Fix pathing bugs
idshibanov Sep 8, 2020
47046fd
Fix monster protection logic
idshibanov Sep 8, 2020
c0dfd18
Remove old code
idshibanov Sep 8, 2020
7ac6b19
Remove unused variable
ihhub Sep 8, 2020
1b2868d
Remove unused parameter
idshibanov Sep 8, 2020
5aa1683
Merge branch 'pathfinding-array' of git@github.com:idshibanov/fheroes…
idshibanov Sep 8, 2020
7bc5f9c
Fix boat check
idshibanov Sep 8, 2020
7be946c
Small speedup
ihhub Sep 8, 2020
27ebac8
Speed up monster protection logic
idshibanov Sep 9, 2020
023c775
Merge branch 'pathfinding-array' of git@github.com:idshibanov/fheroes…
idshibanov Sep 9, 2020
42482c2
Simplify old road logic
idshibanov Sep 9, 2020
af4d5cc
Don't need direction for road calculation
idshibanov Sep 9, 2020
aaf3a73
Set road boolean
idshibanov Sep 9, 2020
7e9a94f
Replace Direction::Get with faster Maps::GetDirection
idshibanov Sep 9, 2020
65ecebf
Add optimized version of Maps::isValidDirection
idshibanov Sep 9, 2020
eb9ee13
Unwrap loop in Maps::GetTilesUnderProtection
idshibanov Sep 9, 2020
c16e125
Optimize World::isValidPath
idshibanov Sep 9, 2020
6f66b8b
Cache direction offset
idshibanov Sep 9, 2020
03f10d3
Fix first step move cost
idshibanov Sep 9, 2020
2b417c0
Remove unused limit param
idshibanov Sep 9, 2020
f3237e8
Revert to use passable_disable
idshibanov Sep 9, 2020
1ce26fd
Formatting
idshibanov Sep 9, 2020
7b6a5ba
Use parent class method
ihhub Sep 9, 2020
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
2 changes: 1 addition & 1 deletion VisualStudio/common.props
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>src\engine;src\fheroes2\gui;src\fheroes2\maps;src\fheroes2\kingdom;src\fheroes2\game;src\fheroes2\dialog;src\fheroes2\system;src\fheroes2\spell;src\fheroes2\monster;src\fheroes2\castle;src\fheroes2\agg;src\fheroes2\heroes;src\fheroes2\resource;src\fheroes2\ai;src\fheroes2\army;src\fheroes2\battle;src\fheroes2\pocketpc;src\fheroes2\objects;src\fheroes2\test;src\fheroes2\image;src\thirdparty\libsmacker;..\zlib\include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>src\engine;src\fheroes2\gui;src\fheroes2\maps;src\fheroes2\kingdom;src\fheroes2\game;src\fheroes2\dialog;src\fheroes2\system;src\fheroes2\spell;src\fheroes2\monster;src\fheroes2\castle;src\fheroes2\agg;src\fheroes2\heroes;src\fheroes2\resource;src\fheroes2\ai;src\fheroes2\army;src\fheroes2\battle;src\fheroes2\pocketpc;src\fheroes2\objects;src\fheroes2\world;src\fheroes2\test;src\fheroes2\image;src\thirdparty\libsmacker;..\zlib\include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;WITH_ZLIB;WITH_MIXER;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
Expand Down
9 changes: 5 additions & 4 deletions fheroes2.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,6 @@
<ClCompile Include="src\fheroes2\heroes\heroes_recruits.cpp" />
<ClCompile Include="src\fheroes2\heroes\heroes_spell.cpp" />
<ClCompile Include="src\fheroes2\heroes\route.cpp" />
<ClCompile Include="src\fheroes2\heroes\route_pathfind.cpp" />
<ClCompile Include="src\fheroes2\heroes\skill.cpp" />
<ClCompile Include="src\fheroes2\kingdom\color.cpp" />
<ClCompile Include="src\fheroes2\kingdom\kingdom.cpp" />
Expand All @@ -332,8 +331,6 @@
<ClCompile Include="src\fheroes2\kingdom\race.cpp" />
<ClCompile Include="src\fheroes2\kingdom\speed.cpp" />
<ClCompile Include="src\fheroes2\kingdom\week.cpp" />
<ClCompile Include="src\fheroes2\kingdom\world.cpp" />
<ClCompile Include="src\fheroes2\kingdom\world_loadmap.cpp" />
<ClCompile Include="src\fheroes2\maps\ground.cpp" />
<ClCompile Include="src\fheroes2\maps\maps.cpp" />
<ClCompile Include="src\fheroes2\maps\maps_actions.cpp" />
Expand Down Expand Up @@ -371,6 +368,9 @@
<ClCompile Include="src\fheroes2\system\settings.cpp" />
<ClCompile Include="src\fheroes2\test\test.cpp" />
<ClCompile Include="src\fheroes2\test\test_monstersprite.cpp" />
<ClCompile Include="src\fheroes2\world\world.cpp" />
<ClCompile Include="src\fheroes2\world\world_loadmap.cpp" />
<ClCompile Include="src\fheroes2\world\world_pathfinding.cpp" />
<ClCompile Include="src\thirdparty\libsmacker\smacker.c" />
<ClCompile Include="src\thirdparty\libsmacker\smk_bitstream.c" />
<ClCompile Include="src\thirdparty\libsmacker\smk_hufftree.c" />
Expand Down Expand Up @@ -486,7 +486,6 @@
<ClInclude Include="src\fheroes2\kingdom\race.h" />
<ClInclude Include="src\fheroes2\kingdom\speed.h" />
<ClInclude Include="src\fheroes2\kingdom\week.h" />
<ClInclude Include="src\fheroes2\kingdom\world.h" />
<ClInclude Include="src\fheroes2\maps\ground.h" />
<ClInclude Include="src\fheroes2\maps\maps.h" />
<ClInclude Include="src\fheroes2\maps\maps_actions.h" />
Expand Down Expand Up @@ -524,6 +523,8 @@
<ClInclude Include="src\fheroes2\system\players.h" />
<ClInclude Include="src\fheroes2\system\settings.h" />
<ClInclude Include="src\fheroes2\test\test.h" />
<ClInclude Include="src\fheroes2\world\world.h" />
<ClInclude Include="src\fheroes2\world\world_pathfinding.h" />
<ClInclude Include="src\tools\palette_h2.h" />
<ClInclude Include="src\thirdparty\libsmacker\smacker.h" />
<ClInclude Include="src\thirdparty\libsmacker\smk_bitstream.h" />
Expand Down
4 changes: 2 additions & 2 deletions src/fheroes2/ai/simple/ai_simple_heroes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ namespace AI
if ( task.size() >= HERO_MAX_SHEDULED_TASK )
break;
const int positionIndex = ( *it ).first;
const uint32_t distance = hero.GetPath().Calculate( positionIndex, PATHFINDING_LIMIT );
const uint32_t distance = world.getDistance( hero.GetIndex(), positionIndex, hero.GetLevelSkill( Skill::Secondary::PATHFINDING ) );

if ( distance ) {
DEBUG( DBG_AI, DBG_INFO,
Expand Down Expand Up @@ -482,7 +482,7 @@ namespace AI

if ( HeroesValidObject( hero, index ) ) {
DEBUG( DBG_AI, DBG_TRACE, hero.GetName() << ", looking for: " << MP2::StringObject( world.GetTiles( index ).GetObject() ) << "(" << index << ")" );
if ( hero.GetPath().Calculate( index, PATHFINDING_LIMIT ) )
if ( hero.GetPath().Calculate( index ) )
break;

DEBUG( DBG_AI, DBG_TRACE, hero.GetName() << " say: unable to get object: " << index << ", remove task..." );
Expand Down
4 changes: 2 additions & 2 deletions src/fheroes2/dialog/dialog_quickinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -285,9 +285,9 @@ std::string ShowGroundInfo( const Maps::Tiles & tile, bool show, const Heroes *
std::string str = Maps::Ground::String( tile.GetGround() );

if ( show && hero ) {
int dir = Direction::Get( hero->GetIndex(), tile.GetIndex() );
int dir = Maps::GetDirection( hero->GetIndex(), tile.GetIndex() );
if ( dir != Direction::UNKNOWN ) {
uint32_t cost = ( tile.isRoad( dir ) ) ? Maps::Ground::roadPenalty : Maps::Ground::GetPenalty( tile, hero->GetLevelSkill( Skill::Secondary::PATHFINDING ) );
uint32_t cost = tile.isRoad() ? Maps::Ground::roadPenalty : Maps::Ground::GetPenalty( tile, hero->GetLevelSkill( Skill::Secondary::PATHFINDING ) );

if ( cost ) {
str.append( "\n" );
Expand Down
2 changes: 0 additions & 2 deletions src/fheroes2/game/game_io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,6 @@ bool Game::Load( const std::string & fn )

fz >> World::Get() >> Settings::Get() >> GameOver::Result::Get() >> GameStatic::Data::Get() >> MonsterStaticData::Get() >> end_check;

World::Get().PostFixLoad();

if ( fz.fail() || ( end_check != SAV2ID2 && end_check != SAV2ID3 ) ) {
DEBUG( DBG_GAME, DBG_WARN, "invalid load file: " << fn );
return false;
Expand Down
3 changes: 1 addition & 2 deletions src/fheroes2/gui/interface_gamearea.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,9 +259,8 @@ void Interface::GameArea::Redraw( fheroes2::Image & dst, int flag ) const
if ( pathEnd != nextStep ) {
const Maps::Tiles & tileTo = world.GetTiles( currentStep->GetIndex() );
uint32_t cost = Maps::Ground::GetPenalty( tileTo, pathfinding );
const int direction = currentStep->GetDirection();

if ( world.GetTiles( currentStep->GetFrom() ).isRoad( direction ) || tileTo.isRoad( Direction::Reflect( direction ) ) )
if ( world.GetTiles( currentStep->GetFrom() ).isRoad() && tileTo.isRoad() )
cost = Maps::Ground::roadPenalty;

index = Route::Path::GetIndexSprite( ( *currentStep ).GetDirection(), ( *nextStep ).GetDirection(), cost );
Expand Down
11 changes: 0 additions & 11 deletions src/fheroes2/heroes/direction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,6 @@ std::string Direction::String( int direct )
return res.empty() ? str_direct[0] : res;
}

int Direction::Get( s32 from, s32 to )
{
const Directions directions = Direction::All();

for ( Directions::const_iterator it = directions.begin(); it != directions.end(); ++it )
if ( to == Maps::GetDirectionIndex( from, *it ) )
return *it;

return to == from ? CENTER : UNKNOWN;
}

bool Direction::ShortDistanceClockWise( int from, int to )
{
switch ( from ) {
Expand Down
1 change: 0 additions & 1 deletion src/fheroes2/heroes/direction.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ namespace Direction

std::string String( int );

int Get( s32 from, s32 to );
int Reflect( int direct );

bool ShortDistanceClockWise( int direct1, int direct2 );
Expand Down
13 changes: 3 additions & 10 deletions src/fheroes2/heroes/heroes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1297,17 +1297,10 @@ int Heroes::GetDirection( void ) const
int Heroes::GetRangeRouteDays( s32 dst ) const
{
const u32 maxMovePoints = GetMaxMovePoints();
const u32 limit = maxMovePoints * 5 / 100; // limit ~5 day

// approximate distance, this restriction calculation
if ( ( 4 * maxMovePoints / 100 ) < Maps::GetApproximateDistance( GetIndex(), dst ) ) {
DEBUG( DBG_GAME, DBG_INFO, "distance limit" );
return 0;
}

Route::Path test( *this );
// approximate limit, this restriction path finding algorithm
uint32_t total = test.Calculate( dst, limit );
uint32_t total = world.getDistance( GetIndex(), dst, GetLevelSkill( Skill::Secondary::PATHFINDING ) );
DEBUG( DBG_GAME, DBG_TRACE, "path distance: " << total );
if ( total > 0 ) {
if ( move_point >= total )
return 1;
Expand All @@ -1323,7 +1316,7 @@ int Heroes::GetRangeRouteDays( s32 dst ) const
return 4;
}
else {
DEBUG( DBG_GAME, DBG_INFO, "iteration limit: " << limit );
DEBUG( DBG_GAME, DBG_TRACE, "unreachable point: " << dst );
}

return 0;
Expand Down
19 changes: 12 additions & 7 deletions src/fheroes2/heroes/route.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ Route::Path & Route::Path::operator=( const Path & p )

int Route::Path::GetFrontDirection( void ) const
{
return empty() ? ( dst != hero->GetIndex() ? Direction::Get( hero->GetIndex(), dst ) : Direction::CENTER ) : front().GetDirection();
return empty() ? ( dst != hero->GetIndex() ? Maps::GetDirection( hero->GetIndex(), dst ) : Direction::CENTER ) : front().GetDirection();
}

u32 Route::Path::GetFrontPenalty( void ) const
Expand Down Expand Up @@ -120,11 +120,16 @@ s32 Route::Path::GetDestinedIndex( void ) const
}

/* return length path */
uint32_t Route::Path::Calculate( const s32 & dst_index, int limit /* -1 */ )
uint32_t Route::Path::Calculate( const s32 & destIndex )
{
dst = dst_index;
const int fromIndex = hero->GetIndex();
const uint32_t skill = hero->GetLevelSkill( Skill::Secondary::PATHFINDING );

return Find( hero->GetIndex(), dst, hero->isShipMaster(), limit, hero->GetLevelSkill( Skill::Secondary::PATHFINDING ) );
dst = destIndex;

std::list<Step>::operator=( world.getPath( fromIndex, dst, skill, false ) );

return world.getDistance( fromIndex, dst, skill );
}

void Route::Path::Reset( void )
Expand All @@ -139,18 +144,18 @@ void Route::Path::Reset( void )

bool Route::Path::isComplete( void ) const
{
return dst == hero->GetIndex() || ( empty() && Direction::UNKNOWN != Direction::Get( hero->GetIndex(), dst ) );
return dst == hero->GetIndex() || ( empty() && Direction::UNKNOWN != Maps::GetDirection( hero->GetIndex(), dst ) );
}

bool Route::Path::isValid( void ) const
{
return !empty();
return !empty() && front().GetDirection() != Direction::UNKNOWN;
}

int Route::Path::GetIndexSprite( int from, int to, int mod )
{
// ICN::ROUTE
// start index 1, 25, 49, 73, 97, 121 (size arrow path)
// start index 1, 25, 49, 73, 97, 121 (path arrow size)
int index = 1;

switch ( mod ) {
Expand Down
3 changes: 1 addition & 2 deletions src/fheroes2/heroes/route.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ namespace Route
int GetFrontDirection( void ) const;
u32 GetFrontPenalty( void ) const;
u32 GetTotalPenalty( void ) const;
uint32_t Calculate( const s32 &, int limit = -1 );
uint32_t Calculate( const s32 & destIndex );

void Show( void )
{
Expand Down Expand Up @@ -105,7 +105,6 @@ namespace Route
static int GetIndexSprite( int from, int to, int mod );

private:
uint32_t Find( int32_t from, int32_t to, bool fromWater = false, int limit = -1, int pathfinding = Skill::Level::NONE );

friend StreamBase & operator<<( StreamBase &, const Path & );
friend StreamBase & operator>>( StreamBase &, Path & );
Expand Down
Loading