mirror of
https://github.com/wesnoth/wesnoth
synced 2025-05-09 04:16:56 +00:00
Little improvement of the pathfinding:
...now prefers using empty hexes This lowers the frequency of blocked units when doing multi-turn moves (on homogeneous terrains, because MP cost and defense have priority) and also help a little fog exploration (since you can't stop on friends) Was a one-liner but did some cleaning and comments.
This commit is contained in:
parent
a123b7c821
commit
3f180a0d1d
@ -26,7 +26,8 @@ Version 1.5.0-svn:
|
|||||||
* new history feature for entering searches, chat messages, commands, and
|
* new history feature for entering searches, chat messages, commands, and
|
||||||
AI formulas
|
AI formulas
|
||||||
* optional cancelling of unit orders in load-game dialog (patch #1024)
|
* optional cancelling of unit orders in load-game dialog (patch #1024)
|
||||||
* smarter pathfinding: if same MP cost, prefer terrains with better defense.
|
* smarter pathfinding: if same MP cost, prefer terrains with better defense
|
||||||
|
and empty hexes (less frequent multi-turn moves blocked by a friend)
|
||||||
* language and i18n:
|
* language and i18n:
|
||||||
* new translation: Croatian
|
* new translation: Croatian
|
||||||
* updated translations: Chinese, Czech, Danish, Dutch, Finnish, French,
|
* updated translations: Chinese, Czech, Danish, Dutch, Finnish, French,
|
||||||
|
@ -18,7 +18,8 @@ Version 1.5.0-svn:
|
|||||||
* Merged 4p A New Land by Bob_the_Mighty
|
* Merged 4p A New Land by Bob_the_Mighty
|
||||||
|
|
||||||
* User interface:
|
* User interface:
|
||||||
* Smarter pathfinding: if same MP cost, prefer terrains with better defense.
|
* Smarter pathfinding: if same MP cost, prefer terrains with better defense
|
||||||
|
and empty hexes (less frequent multi-turn moves blocked by a friend)
|
||||||
|
|
||||||
Version 1.4:
|
Version 1.4:
|
||||||
* Language and translations
|
* Language and translations
|
||||||
|
@ -292,15 +292,8 @@ double shortest_path_calculator::cost(const gamemap::location& /*src*/,const gam
|
|||||||
{
|
{
|
||||||
assert(map_.on_board(loc));
|
assert(map_.on_board(loc));
|
||||||
|
|
||||||
// The location is not valid
|
// loc is shrouded, consider it impassable
|
||||||
// 1. if the loc is shrouded, or
|
// NOTE: This is why AI must avoid to use shroud
|
||||||
// 2. if moving in it costs more than the total movement of the unit, or
|
|
||||||
// 3. if there is a visible enemy on the hex, or
|
|
||||||
// 4. if the unit is not a skirmisher and there is a visible enemy
|
|
||||||
// with a ZoC on an adjacent hex in the middle of the route
|
|
||||||
// #4 is a bad criteria! It should be that moving into a ZOC
|
|
||||||
// uses up the rest of your moves
|
|
||||||
|
|
||||||
if (viewing_team_.shrouded(loc))
|
if (viewing_team_.shrouded(loc))
|
||||||
return getNoPathValue();
|
return getNoPathValue();
|
||||||
|
|
||||||
@ -308,16 +301,28 @@ double shortest_path_calculator::cost(const gamemap::location& /*src*/,const gam
|
|||||||
int const base_cost = unit_.movement_cost(terrain);
|
int const base_cost = unit_.movement_cost(terrain);
|
||||||
// Pathfinding heuristic: the cost must be at least 1
|
// Pathfinding heuristic: the cost must be at least 1
|
||||||
VALIDATE(base_cost >= 1, _("Terrain with a movement cost less than 1 encountered."));
|
VALIDATE(base_cost >= 1, _("Terrain with a movement cost less than 1 encountered."));
|
||||||
|
|
||||||
|
// costs more than the total movement of the unit, impassbale
|
||||||
if (total_movement_ < base_cost)
|
if (total_movement_ < base_cost)
|
||||||
return getNoPathValue();
|
return getNoPathValue();
|
||||||
|
|
||||||
unit_map::const_iterator
|
unit_map::const_iterator
|
||||||
enemy_unit = find_visible_unit(units_, loc, map_, teams_, viewing_team_),
|
other_unit = find_visible_unit(units_, loc, map_, teams_, viewing_team_);
|
||||||
units_end = units_.end();
|
|
||||||
|
|
||||||
if (enemy_unit != units_end && teams_[unit_.side()-1].is_enemy(enemy_unit->second.side()))
|
|
||||||
return getNoPathValue();
|
|
||||||
|
|
||||||
|
// We can't traverse visible enemy and we also prefer empty hexes
|
||||||
|
// (less blocking in multi-turn moves and better when exploring fog,
|
||||||
|
// because we can't stop on a friend)
|
||||||
|
int other_unit_subcost = 0;
|
||||||
|
if (other_unit != units_.end()) {
|
||||||
|
if (teams_[unit_.side()-1].is_enemy(other_unit->second.side()))
|
||||||
|
return getNoPathValue();
|
||||||
|
else
|
||||||
|
// This value will be used with the defense_subcost (see below)
|
||||||
|
// The 1 here means: consider occupied hex as a -1% defense
|
||||||
|
// (less important than 10% defense because friends may move)
|
||||||
|
other_unit_subcost = 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Compute how many movement points are left in the game turn
|
// Compute how many movement points are left in the game turn
|
||||||
// needed to reach the previous hex.
|
// needed to reach the previous hex.
|
||||||
// total_movement_ is not zero, thanks to the pathfinding heuristic
|
// total_movement_ is not zero, thanks to the pathfinding heuristic
|
||||||
@ -344,14 +349,15 @@ double shortest_path_calculator::cost(const gamemap::location& /*src*/,const gam
|
|||||||
move_cost += need_new_turn ? total_movement_ : remaining_movement;
|
move_cost += need_new_turn ? total_movement_ : remaining_movement;
|
||||||
}
|
}
|
||||||
|
|
||||||
// we add a tiny cost based on terrain defense, so the pathfinding
|
// We will add a tiny cost based on terrain defense, so the pathfinding
|
||||||
// prefer good terrains between 2 with the same MP cost
|
// will prefer good terrains between 2 with the same MP cost
|
||||||
// we divide defense by 100 * 100, because defense it's 100-based
|
// Keep in mind that defense_modifier is inverted (= 100 - defense%)
|
||||||
// and we don't want any impact on move cost for less then 100-steps path
|
const int defense_subcost = unit_.defense_modifier(terrain);
|
||||||
// (even ~200 since mean defense is around ~50%)
|
|
||||||
const double defense_cost = unit_.defense_modifier(terrain) / 10000.0;
|
|
||||||
|
|
||||||
return move_cost + defense_cost;
|
// We divide subcosts by 100 * 100, because defense is 100-based and
|
||||||
|
// we don't want any impact on move cost for less then 100-steps path
|
||||||
|
// (even ~200 since mean defense is around ~50%)
|
||||||
|
return move_cost + (defense_subcost + other_unit_subcost) / 10000.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
emergency_path_calculator::emergency_path_calculator(const unit& u, const gamemap& map)
|
emergency_path_calculator::emergency_path_calculator(const unit& u, const gamemap& map)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user