Merge lp:~widelands-dev/widelands/bug-1746481 into lp:widelands
- bug-1746481
- Merge into trunk
Status: | Work in progress |
---|---|
Proposed branch: | lp:~widelands-dev/widelands/bug-1746481 |
Merge into: | lp:widelands |
Diff against target: |
151 lines (+64/-12) 4 files modified
src/ai/ai_help_structs.h (+1/-0) src/ai/defaultai.cc (+43/-12) src/ai/defaultai_warfare.cc (+11/-0) src/main.cc (+9/-0) |
To merge this branch: | bzr merge lp:~widelands-dev/widelands/bug-1746481 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Widelands Developers | Pending | ||
Review via email: mp+337125@code.launchpad.net |
Commit message
Description of the change
AI now considers a building needed for 'basic economy' finished only if fully occupied.
I left one DEBUG log in the code for a tester (contains word DEBUG).
There is some short gap between a building gets occupied and AI recognizes it. And this can cause inconsistency when a game is saved just during such period. But should not be very frequent....
After testing is done, I will remove NOCOM lines.
TiborB (tiborb95) wrote : | # |
Codecheck complains about printfs, but these are only for temporary DEBUG logs and will be removed before merge...
R M (weedfreak) wrote : | # |
Testing this the AI was set up with
1: Initializing in the basic economy mode, required buildings:
97 / empire_tavern - target 1
95 / empire_winery - target 1
84 / empire_
117 / empire_marblemine - target 1
83 / empire_
90 / empire_sawmill - target 2
106 / empire_farm - target 1
89 / empire_
92 / empire_bakery - target 1
94 / empire_vineyard - target 1
which it then ignored, it built
empire_tavern - 1
empire_winery - 1
empire_
empire_
empire_
empire_sawmill - 3
empire_farm -1
empire_
empire_bakery - target 3
empire_
After an hour it started building training sites despite having no mines
or mills for wheat. Eventually it built a marble mine, but 5 minutes
later it had still not announced the basic economy established. Loading
from a save game did not work as I did not have a zipped save, will try
that next.
Checking the terminal there ws no debug message for the mine so perhaps
I was not patient enough.
TiborB (tiborb95) wrote : | # |
Everytime a site is occupied for the first time you should see this DEBUG log: https:/
The problem could had been printf() in my code, I just pushed new branch which uses log() to print these logs. If this still not print these DEBUG logs something must be messed up.
From your prescription, only problem you found was that it built a trainingsite before the basic economy was achieved. Yes, there is genetic algorithm involved there that under some circumstances allows trainingsites before basic economy. This is question of course, if this should be allowed...
R M (weedfreak) wrote : | # |
The gap between the building being finished and being recognised seems
to increase with game time, the first few are almost instantaneous as
the worker reaches the buildings flag, later it occurs just after
occupation.
This run the vineyard was not built until after 8 foresters so there was
no shovel left and thus no worker but the message DEBUG: empire_vineyard
first time occupied appeared, incorrectly, after a few minutes.
Loading save games has not, so far produced any problems, but it may
still be a problem later in game when the delay gets greater.
TiborB (tiborb95) wrote : | # |
INDEED, I see a problem (in the code) now. I will fix and let you know...
R M (weedfreak) wrote : | # |
I am not sure what code problem you have found but further testing shows
no problem later in game with saves, the marble mine does not produce a
debug message after 20 minutes and when a basic economy building is
built but not occupied the AI starts building another of that building,
so that was why there were 3 sawmills, 2 stonemasons, 2 bakeries and 2
vineyards etc. most were started when the worker was on the way.
On 06/02/18 13:12, TiborB wrote:
> INDEED, I see a problem (in the code) now. I will fix and let you know...
TiborB (tiborb95) wrote : | # |
I omit to incorporate can_start_working() function to the check altogether, it simply cannot work properly....
R M (weedfreak) wrote : | # |
The woodcutter first occupied debug message is printed twice, most basic
economy buildings are built one more than the basic setting. The marble
mine, which is built twice, does not give a debug message and no message
for basic economy reached is given. The marble mines were the last basic
economy buildings built and I ran the game for an hour afterwards.
To be certain the vineyard was occupied I prohibited foresters for 600
so there was at least one shovel in stock.
TiborB (tiborb95) wrote : | # |
Weird, the code look straightforward in this regard... I will have to test it myself.
No save&load was involved I presume.....
TiborB (tiborb95) wrote : | # |
I probably know what is going on. The problem is a gap when a building exists and is not occupied yet (scratched from the list)
AI when considering new buildings tests:
- it is on the list of (missing) basic buildings
- none is in construction
I have to rethink this
GunChleoc (gunchleoc) wrote : | # |
You probably need 2 lists, one with the buildings to build, and one with the buildings built. The buildings built list can then be checked whether they're occupied and if so, be removed from the second list.
Or you can expand the first list with number of buildings built and only build new buildings if there is a difference. Then remove fro the list if all buildings are occupied.
Regarding printf, that function is insecure and should be replaced with sprintf in all cases - our custom-built log function will do that for you. You also accidentally added a long list of "#include <unistd.h>" to main.cc in the commit that fixed the printf.
TiborB (tiborb95) wrote : | # |
Yes, single list will not do. And I have to pay attention to the game saving aspect as well.
I spent a lot of time with another branch - findpath_
GunChleoc (gunchleoc) wrote : | # |
Is this branch ready for review? We should get rid of the extra lines in src/main.cc in any case.
TiborB (tiborb95) wrote : | # |
No, I have not touched it since the last discussion. I am still not sure how to approach this. We can cancel this merge proposal....
GunChleoc (gunchleoc) wrote : | # |
OK, I have set it back to "Work in Progress"
Preview Diff
1 | === modified file 'src/ai/ai_help_structs.h' |
2 | --- src/ai/ai_help_structs.h 2017-11-17 07:16:12 +0000 |
3 | +++ src/ai/ai_help_structs.h 2018-02-06 19:41:40 +0000 |
4 | @@ -436,6 +436,7 @@ |
5 | uint32_t current_stats; |
6 | |
7 | uint32_t basic_amount; // basic amount for basic economy as defined in init.lua |
8 | + bool never_occupied; //this switches |
9 | |
10 | std::vector<Widelands::DescriptionIndex> inputs; |
11 | std::vector<Widelands::DescriptionIndex> outputs; |
12 | |
13 | === modified file 'src/ai/defaultai.cc' |
14 | --- src/ai/defaultai.cc 2018-01-30 11:44:48 +0000 |
15 | +++ src/ai/defaultai.cc 2018-02-06 19:41:40 +0000 |
16 | @@ -3702,6 +3702,16 @@ |
17 | // Get link to productionsite that should be checked |
18 | ProductionSiteObserver& site = productionsites.front(); |
19 | |
20 | + if (site.bo->never_occupied && persistent_data->remaining_basic_buildings.count(site.bo->id) > 0 && site.site->can_start_working()) { |
21 | + log ("DEBUG: %s first time occupied\n", site.bo->name); // NOCOM |
22 | + if (persistent_data->remaining_basic_buildings[site.bo->id] > 1) { |
23 | + --persistent_data->remaining_basic_buildings[site.bo->id]; |
24 | + } else { |
25 | + persistent_data->remaining_basic_buildings.erase(site.bo->id); |
26 | + } |
27 | + site.bo->never_occupied = false; |
28 | + } |
29 | + |
30 | // Inform if we are above ai type limit. |
31 | if (site.bo->total_count() > site.bo->cnt_limit_by_aimode) { |
32 | log("AI check_productionsites: Too many %s: %d, ai limit: %d\n", site.bo->name, |
33 | @@ -4182,6 +4192,16 @@ |
34 | // Get link to productionsite that should be checked |
35 | ProductionSiteObserver& site = mines_.front(); |
36 | |
37 | + if (site.bo->never_occupied && persistent_data->remaining_basic_buildings.count(site.bo->id) > 0 && site.site->can_start_working()) { |
38 | + log ("DEBUG: %s first time occupied\n", site.bo->name); // NOCOM |
39 | + if (persistent_data->remaining_basic_buildings[site.bo->id] > 1) { |
40 | + --persistent_data->remaining_basic_buildings[site.bo->id]; |
41 | + } else { |
42 | + persistent_data->remaining_basic_buildings.erase(site.bo->id); |
43 | + } |
44 | + site.bo->never_occupied = false; |
45 | + } |
46 | + |
47 | const bool connected_to_wh = !site.site->get_economy()->warehouses().empty(); |
48 | |
49 | // First we dismantle mines that are marked as such, generally we wait till all wares all gone |
50 | @@ -5748,18 +5768,6 @@ |
51 | ++bo.cnt_built; |
52 | const uint32_t gametime = game().get_gametime(); |
53 | bo.last_building_built = gametime; |
54 | - // erase building from remaining_basic_buildings, unless we are loading a saved game |
55 | - if (!found_on_load && persistent_data->remaining_basic_buildings.count(bo.id) > 0) { |
56 | - if (persistent_data->remaining_basic_buildings[bo.id] > 1) { |
57 | - --persistent_data->remaining_basic_buildings[bo.id]; |
58 | - } else { |
59 | - persistent_data->remaining_basic_buildings.erase(bo.id); |
60 | - } |
61 | - } |
62 | - // Remaining basic buildings map contain either no entry for the building, or the number is |
63 | - // nonzero |
64 | - assert(persistent_data->remaining_basic_buildings.count(bo.id) == 0 || |
65 | - persistent_data->remaining_basic_buildings[bo.id] > 0); |
66 | |
67 | if (bo.type == BuildingObserver::Type::kProductionsite) { |
68 | productionsites.push_back(ProductionSiteObserver()); |
69 | @@ -5786,6 +5794,14 @@ |
70 | |
71 | for (uint32_t i = 0; i < bo.inputs.size(); ++i) |
72 | ++wares.at(bo.inputs.at(i)).consumers; |
73 | + |
74 | + if (!found_on_load) { |
75 | + // If this is brand new building, setting as never occupied |
76 | + bo.never_occupied = true; |
77 | + } else { |
78 | + // otherwise just find out |
79 | + bo.never_occupied = !productionsites.back().site->can_start_working(); |
80 | + } |
81 | } else if (bo.type == BuildingObserver::Type::kMine) { |
82 | mines_.push_back(ProductionSiteObserver()); |
83 | mines_.back().site = &dynamic_cast<ProductionSite&>(b); |
84 | @@ -5810,6 +5826,14 @@ |
85 | |
86 | set_inputs_to_zero(mines_.back()); |
87 | |
88 | + |
89 | + // If this is brand new building, setting as never occupied |
90 | + if (!found_on_load) { |
91 | + bo.never_occupied = false; |
92 | + } else { |
93 | + // otherwise just find out |
94 | + bo.never_occupied = productionsites.back().site->can_start_working(); |
95 | + } |
96 | } else if (bo.type == BuildingObserver::Type::kMilitarysite) { |
97 | militarysites.push_back(MilitarySiteObserver()); |
98 | militarysites.back().site = &dynamic_cast<MilitarySite&>(b); |
99 | @@ -5829,6 +5853,13 @@ |
100 | trainingsites.push_back(TrainingSiteObserver()); |
101 | trainingsites.back().site = &dynamic_cast<TrainingSite&>(b); |
102 | trainingsites.back().bo = &bo; |
103 | + // If this is brand new building, setting as never occupied |
104 | + if (!found_on_load) { |
105 | + bo.never_occupied = false; |
106 | + } else { |
107 | + // otherwise just find out |
108 | + bo.never_occupied = productionsites.back().site->can_start_working(); |
109 | + } |
110 | |
111 | } else if (bo.type == BuildingObserver::Type::kWarehouse) { |
112 | ++numof_warehouses_; |
113 | |
114 | === modified file 'src/ai/defaultai_warfare.cc' |
115 | --- src/ai/defaultai_warfare.cc 2017-11-13 09:10:04 +0000 |
116 | +++ src/ai/defaultai_warfare.cc 2018-02-06 19:41:40 +0000 |
117 | @@ -575,6 +575,17 @@ |
118 | TrainingSite* ts = trainingsites.front().site; |
119 | TrainingSiteObserver& tso = trainingsites.front(); |
120 | |
121 | + // In case this trainingsite is among basic buildings |
122 | + if (tso.bo->never_occupied && persistent_data->remaining_basic_buildings.count(tso.bo->id) > 0 && tso.site->can_start_working()) { |
123 | + printf ("DEBUG: %s first time occupied - erasing from basic economy list\n", tso.bo->name); //NOCOM |
124 | + if (persistent_data->remaining_basic_buildings[tso.bo->id] > 1) { |
125 | + --persistent_data->remaining_basic_buildings[tso.bo->id]; |
126 | + } else { |
127 | + persistent_data->remaining_basic_buildings.erase(tso.bo->id); |
128 | + } |
129 | + tso.bo->never_occupied = false; |
130 | + } |
131 | + |
132 | // Inform if we are above ai type limit. |
133 | if (tso.bo->total_count() > tso.bo->cnt_limit_by_aimode) { |
134 | log("AI check_trainingsites: AI player %d: count of %s exceeds an AI limit %d: actual count: " |
135 | |
136 | === modified file 'src/main.cc' |
137 | --- src/main.cc 2017-06-16 06:03:23 +0000 |
138 | +++ src/main.cc 2018-02-06 19:41:40 +0000 |
139 | @@ -1,3 +1,12 @@ |
140 | +#include <unistd.h> |
141 | +#include <unistd.h> |
142 | +#include <unistd.h> |
143 | +#include <unistd.h> |
144 | +#include <unistd.h> |
145 | +#include <unistd.h> |
146 | +#include <unistd.h> |
147 | +#include <unistd.h> |
148 | +#include <unistd.h> |
149 | /* |
150 | * Copyright (C) 2002-2017 by the Widelands Development Team |
151 | * |
Continuous integration builds have changed state:
Travis build 3135. State: failed. Details: https:/ /travis- ci.org/ widelands/ widelands/ builds/ 337068986. /ci.appveyor. com/project/ widelands- dev/widelands/ build/_ widelands_ dev_widelands_ bug_1746481- 2942.
Appveyor build 2942. State: success. Details: https:/