Merge lp:~widelands-dev/widelands/ai_blocked_fields_tweaks into lp:widelands

Proposed by TiborB
Status: Merged
Merged at revision: 8633
Proposed branch: lp:~widelands-dev/widelands/ai_blocked_fields_tweaks
Merge into: lp:widelands
Diff against target: 249 lines (+121/-23)
4 files modified
src/ai/ai_help_structs.cc (+54/-2)
src/ai/ai_help_structs.h (+22/-1)
src/ai/defaultai.cc (+44/-19)
src/ai/defaultai.h (+1/-1)
To merge this branch: bzr merge lp:~widelands-dev/widelands/ai_blocked_fields_tweaks
Reviewer Review Type Date Requested Status
GunChleoc Approve
Review via email: mp+341483@code.launchpad.net

Commit message

AI tweak - better identification of unconnectable regions based on walking algorithm. Used to keep AI from wasting attempts to build there something.

Description of the change

This improves behavior related to blocked_fields (list of fields temporarily blocked for construction of new buildable fields). Now it better calculates the region that is temporarily unconnectable and consider these blocked fields more. However, visible difference is quite small.

To post a comment you must log in.
Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 3294. State: failed. Details: https://travis-ci.org/widelands/widelands/builds/354043229.
Appveyor build 3102. State: failed. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_ai_blocked_fields_tweaks-3102.

Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 3295. State: passed. Details: https://travis-ci.org/widelands/widelands/builds/354209658.
Appveyor build 3103. State: failed. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_ai_blocked_fields_tweaks-3103.

Revision history for this message
GunChleoc (gunchleoc) wrote :

Looks good to me - just some minor nits. Please feel free to merge once you have addressed those to your liking. Don't forget to set the commit message above ;)

review: Approve
Revision history for this message
TiborB (tiborb95) wrote :

@Gun
How can I use imm->descr().type() to say if an immovable is PlayerImmovable?

Revision history for this message
TiborB (tiborb95) wrote :

Do you mean this:
https://bazaar.launchpad.net/~widelands-dev/widelands/trunk/view/head:/src/logic/map_objects/map_object.h#L58
?

Is it guaranteed that type >= 40 is player immovable?

Revision history for this message
TiborB (tiborb95) wrote :

Got it!
It can go once the CI is green

Revision history for this message
GunChleoc (gunchleoc) wrote :

Please set a commit message on the top of this page.

Revision history for this message
TiborB (tiborb95) wrote :

Sorry, I forgot, done now.....

Revision history for this message
GunChleoc (gunchleoc) wrote :

Great, thanks!

@bunnybot merge

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/ai/ai_help_structs.cc'
--- src/ai/ai_help_structs.cc 2018-02-16 20:42:21 +0000
+++ src/ai/ai_help_structs.cc 2018-03-25 16:41:13 +0000
@@ -42,7 +42,7 @@
4242
43bool CheckStepRoadAI::allowed(43bool CheckStepRoadAI::allowed(
44 const Map& map, FCoords start, FCoords end, int32_t, CheckStep::StepId const id) const {44 const Map& map, FCoords start, FCoords end, int32_t, CheckStep::StepId const id) const {
45 uint8_t endcaps = player->get_buildcaps(end);45 const uint8_t endcaps = player->get_buildcaps(end);
4646
47 // we should not cross fields with road or flags (or any other immovable)47 // we should not cross fields with road or flags (or any other immovable)
48 if ((map.get_immovable(start)) && !(id == CheckStep::stepFirst)) {48 if ((map.get_immovable(start)) && !(id == CheckStep::stepFirst)) {
@@ -83,6 +83,57 @@
83 return true;83 return true;
84}84}
8585
86
87// CheckStepOwnTerritory
88CheckStepOwnTerritory::CheckStepOwnTerritory(Player* const pl, uint8_t const mc, bool const oe)
89 : player(pl), movecaps(mc), open_end(oe) {
90}
91
92// Defines when movement is allowed:
93// 1. startfield is walkable (or it is the first step)
94// And endfield either:
95// 2a. is walkable
96// 2b. has our PlayerImmovable (building or flag)
97bool CheckStepOwnTerritory::allowed(
98 const Map& map, FCoords start, FCoords end, int32_t, CheckStep::StepId const id) const {
99 const uint8_t endcaps = player->get_buildcaps(end);
100 const uint8_t startcaps = player->get_buildcaps(start);
101
102 // We should not cross fields with road or flags (or any other immovable)
103 // Or rather we can step on it, but not go on from such field
104 if ((map.get_immovable(start)) && !(id == CheckStep::stepFirst)) {
105 return false;
106 }
107
108 // Start field must be walkable
109 if (!(startcaps & movecaps)) {
110 return false;
111 }
112
113 // Endfield can not be water
114 if (endcaps & MOVECAPS_SWIM) {
115 return false;
116 }
117
118 return true;
119}
120
121// We accept either walkable territory or field with own immovable
122bool CheckStepOwnTerritory::reachable_dest(const Map& map, const FCoords& dest) const {
123 const uint8_t endcaps = player->get_buildcaps(dest);
124 if (BaseImmovable const* const imm = map.get_immovable(dest)) {
125 if (imm->descr().type() >= MapObjectType::FLAG) {
126 return true;
127 } else {
128 return false;
129 }
130 }
131 if (endcaps & MOVECAPS_WALK) {
132 return true;
133 }
134 return false;
135}
136
86// We are looking for fields we can walk on137// We are looking for fields we can walk on
87// and owned by hostile player.138// and owned by hostile player.
88FindNodeEnemy::FindNodeEnemy(Player* p, Game& g) : player(p), game(g) {139FindNodeEnemy::FindNodeEnemy(Player* p, Game& g) : player(p), game(g) {
@@ -296,7 +347,8 @@
296}347}
297348
298EconomyObserver::EconomyObserver(Widelands::Economy& e) : economy(e) {349EconomyObserver::EconomyObserver(Widelands::Economy& e) : economy(e) {
299 dismantle_grace_time = std::numeric_limits<int32_t>::max();350 dismantle_grace_time = std::numeric_limits<uint32_t>::max();
351 fields_block_last_time = 0;
300}352}
301353
302int32_t BuildingObserver::total_count() const {354int32_t BuildingObserver::total_count() const {
303355
=== modified file 'src/ai/ai_help_structs.h'
--- src/ai/ai_help_structs.h 2018-03-03 20:46:01 +0000
+++ src/ai/ai_help_structs.h 2018-03-25 16:41:13 +0000
@@ -133,6 +133,21 @@
133 Player* player;133 Player* player;
134 uint8_t movecaps;134 uint8_t movecaps;
135 bool open_end;135 bool open_end;
136
137};
138
139// Used to walk ower own territory, on fields that are walkable (or as given by mc)
140// plus one step more to a field with own immovable. So that also flags and buildings are
141// included in resulting list
142struct CheckStepOwnTerritory {
143 CheckStepOwnTerritory(Player* const pl, uint8_t const mc, bool const oe);
144
145 bool allowed(const Map&, FCoords start, FCoords end, int32_t dir, CheckStep::StepId) const;
146 bool reachable_dest(const Map&, const FCoords& dest) const;
147
148 Player* player;
149 uint8_t movecaps;
150 bool open_end;
136};151};
137152
138// We are looking for fields we can walk on153// We are looking for fields we can walk on
@@ -249,6 +264,11 @@
249 bool accept(const Map&, FCoords) const;264 bool accept(const Map&, FCoords) const;
250};265};
251266
267// Accepts any field
268struct FindNodeAcceptAll {
269 bool accept(const Map&, FCoords) const {return true;};
270};
271
252struct NearFlag {272struct NearFlag {
253 // ordering nearflags by biggest reduction273 // ordering nearflags by biggest reduction
254 struct CompareShortening {274 struct CompareShortening {
@@ -387,7 +407,8 @@
387407
388 Widelands::Economy& economy;408 Widelands::Economy& economy;
389 std::deque<Widelands::Flag const*> flags;409 std::deque<Widelands::Flag const*> flags;
390 int32_t dismantle_grace_time;410 uint32_t dismantle_grace_time;
411 uint32_t fields_block_last_time;
391};412};
392413
393struct BuildingObserver {414struct BuildingObserver {
394415
=== modified file 'src/ai/defaultai.cc'
--- src/ai/defaultai.cc 2018-03-03 20:46:01 +0000
+++ src/ai/defaultai.cc 2018-03-25 16:41:13 +0000
@@ -2069,9 +2069,15 @@
2069 for (int32_t i = 0; i < 4; ++i)2069 for (int32_t i = 0; i < 4; ++i)
2070 spots_avail.at(i) = 0;2070 spots_avail.at(i) = 0;
20712071
2072 // We calculate owned buildable spots, of course ignoring ones that are blocked
2073 // for now
2072 for (std::deque<BuildableField*>::iterator i = buildable_fields.begin();2074 for (std::deque<BuildableField*>::iterator i = buildable_fields.begin();
2073 i != buildable_fields.end(); ++i)2075 i != buildable_fields.end(); ++i) {
2076 if (blocked_fields.is_blocked((*i)->coords)) {
2077 continue;
2078 }
2074 ++spots_avail.at((*i)->coords.field->nodecaps() & BUILDCAPS_SIZEMASK);2079 ++spots_avail.at((*i)->coords.field->nodecaps() & BUILDCAPS_SIZEMASK);
2080 }
20752081
2076 spots_ = spots_avail.at(BUILDCAPS_SMALL);2082 spots_ = spots_avail.at(BUILDCAPS_SMALL);
2077 spots_ += spots_avail.at(BUILDCAPS_MEDIUM);2083 spots_ += spots_avail.at(BUILDCAPS_MEDIUM);
@@ -3549,7 +3555,7 @@
3549bool DefaultAI::create_shortcut_road(const Flag& flag,3555bool DefaultAI::create_shortcut_road(const Flag& flag,
3550 uint16_t checkradius,3556 uint16_t checkradius,
3551 int16_t min_reduction,3557 int16_t min_reduction,
3552 int32_t gametime) {3558 uint32_t gametime) {
35533559
3554 // Increasing the failed_connection_tries counter3560 // Increasing the failed_connection_tries counter
3555 // At the same time it indicates a time an economy is without a warehouse3561 // At the same time it indicates a time an economy is without a warehouse
@@ -3561,8 +3567,8 @@
3561 // this should not happen, but if the economy has a warehouse and a dismantle3567 // this should not happen, but if the economy has a warehouse and a dismantle
3562 // grace time set, we must 'zero' the dismantle grace time3568 // grace time set, we must 'zero' the dismantle grace time
3563 if (!flag.get_economy()->warehouses().empty() &&3569 if (!flag.get_economy()->warehouses().empty() &&
3564 eco->dismantle_grace_time != std::numeric_limits<int32_t>::max()) {3570 eco->dismantle_grace_time != std::numeric_limits<uint32_t>::max()) {
3565 eco->dismantle_grace_time = std::numeric_limits<int32_t>::max();3571 eco->dismantle_grace_time = std::numeric_limits<uint32_t>::max();
3566 }3572 }
35673573
3568 // first we deal with situations when this is economy with no warehouses3574 // first we deal with situations when this is economy with no warehouses
@@ -3583,12 +3589,12 @@
35833589
3584 // if we are within grace time, it is OK, just go on3590 // if we are within grace time, it is OK, just go on
3585 if (eco->dismantle_grace_time > gametime &&3591 if (eco->dismantle_grace_time > gametime &&
3586 eco->dismantle_grace_time != std::numeric_limits<int32_t>::max()) {3592 eco->dismantle_grace_time != std::numeric_limits<uint32_t>::max()) {
3587 ;3593 ;
35883594
3589 // if grace time is not set, this is probably first time without a warehouse and we must3595 // if grace time is not set, this is probably first time without a warehouse and we must
3590 // set it3596 // set it
3591 } else if (eco->dismantle_grace_time == std::numeric_limits<int32_t>::max()) {3597 } else if (eco->dismantle_grace_time == std::numeric_limits<uint32_t>::max()) {
35923598
3593 // constructionsites3599 // constructionsites
3594 if (upcast(ConstructionSite const, constructionsite, flag.get_building())) {3600 if (upcast(ConstructionSite const, constructionsite, flag.get_building())) {
@@ -3827,19 +3833,38 @@
3827 game().send_player_build_road(player_number(), path);3833 game().send_player_build_road(player_number(), path);
3828 return true;3834 return true;
3829 }3835 }
3830 // if all possible roads skipped3836 // We can't build a road so let's block the vicinity as an indication this area is not connectible
3831 if (last_attempt_) {3837 // Usually we block for 2 minutes, but if it is a last attempt we block for 10 minutes
3832 Building* bld = flag.get_building();3838 // Note: we block the vicinity only if this economy (usually a sole flag with a building) is not
3833 // first we block the field and vicinity for 15 minutes, probably it is not a good place to3839 // connected to a warehouse
3834 // build on3840 if (flag.get_economy()->warehouses().empty()) {
3835 MapRegion<Area<FCoords>> mr(map, Area<FCoords>(map.get_fcoords(bld->get_position()), 2));3841
3836 do {3842 // blocking only if latest block was less then 60 seconds ago or it is last attempt
3837 blocked_fields.add(mr.location(), game().get_gametime() + 15 * 60 * 1000);3843 if (eco->fields_block_last_time + 60000 < gametime || last_attempt_) {
3838 } while (mr.advance(map));3844 eco->fields_block_last_time = gametime;
3839 remove_from_dqueue<Widelands::Flag>(eco->flags, &flag);3845
3840 game().send_player_bulldoze(*const_cast<Flag*>(&flag));3846 const uint32_t block_time = last_attempt_ ? 10 * 60 * 1000 : 2 * 60 * 1000;
3841 dead_ends_check_ = true;3847
3842 return true;3848 FindNodeAcceptAll buildable_functor;
3849 CheckStepOwnTerritory check_own(player_, MOVECAPS_WALK, true);
3850
3851 // get all flags within radius
3852 std::vector<Coords> reachable_to_block;
3853 map.find_reachable_fields(Area<FCoords>(map.get_fcoords(flag.get_position()), checkradius),
3854 &reachable_to_block, check_own, buildable_functor);
3855
3856 for (auto coords : reachable_to_block) {
3857 blocked_fields.add(coords, game().get_gametime() + block_time);
3858 }
3859 }
3860
3861 // If it last attempt we also destroy the flag (with a building if any attached)
3862 if (last_attempt_) {
3863 remove_from_dqueue<Widelands::Flag>(eco->flags, &flag);
3864 game().send_player_bulldoze(*const_cast<Flag*>(&flag));
3865 dead_ends_check_ = true;
3866 return true;
3867 }
3843 }3868 }
3844 return false;3869 return false;
3845}3870}
38463871
=== modified file 'src/ai/defaultai.h'
--- src/ai/defaultai.h 2018-02-20 21:11:27 +0000
+++ src/ai/defaultai.h 2018-03-25 16:41:13 +0000
@@ -199,7 +199,7 @@
199 bool create_shortcut_road(const Widelands::Flag&,199 bool create_shortcut_road(const Widelands::Flag&,
200 uint16_t maxcheckradius,200 uint16_t maxcheckradius,
201 int16_t minReduction,201 int16_t minReduction,
202 const int32_t gametime);202 const uint32_t gametime);
203 // trying to identify roads that might be removed203 // trying to identify roads that might be removed
204 bool dispensable_road_test(const Widelands::Road&);204 bool dispensable_road_test(const Widelands::Road&);
205 bool dismantle_dead_ends();205 bool dismantle_dead_ends();

Subscribers

People subscribed via source and target branches

to status/vote changes: