Status: | Rejected |
---|---|
Rejected by: | SirVer |
Proposed branch: | lp:~s3734770/widelands/carli-ai |
Merge into: | lp:widelands |
Diff against target: |
487 lines (+125/-52) 4 files modified
compile.sh (+2/-2) src/ai/ai_help_structs.h (+2/-0) src/ai/defaultai.cc (+120/-50) src/ui_basic/table.cc (+1/-0) |
To merge this branch: | bzr merge lp:~s3734770/widelands/carli-ai |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
SirVer | Needs Fixing | ||
Review via email: mp+82061@code.launchpad.net |
Commit message
Description of the change
Hi,
I improved the AI a bit and fixed some bugs.
The AI now takes in account that it needs material for building and for creating soldiers.
The barbarians axefactory upgrade works now.
What I further will do:
- Treat upgradable buildings like normal buildings and create construction time plans
- find an automatic balance for the consumer-producer problem
Carli (s3734770) wrote : | # |
Shouldnt the road optimizer detect the flag problems? I did not notice any problems with that.
About the compile.sh.... the make parameters should not be versioned.
So what should I fix? The make parameter....
But not the dismantle. It works for me. Which version of widelands do you have?
SirVer (sirver) wrote : | # |
> Shouldnt the road optimizer detect the flag problems? I did not notice any
> problems with that.
It should, but notice the comment in 256. I guess it is there for a reason.
> About the compile.sh.... the make parameters should not be versioned.
Yep, it shouldn't. You have to be more careful what you commit. You can unmerge your changes or rely on me reverting it when this will be merged.
> But not the dismantle. It works for me. Which version of widelands do you
> have?
Current trunk obviously :). I am really reluctant to merge this for it is not clear what you did. Your branch contains a lot of lines where only whitespace changes happened (something which you should avoid. Use bzr diff or qdiff or similar to check that you do not do that). Some stuff is juggled around and in some places you changed one magic constant into another. What makes you believe that your AI is indeed an improvement?
Carli (s3734770) wrote : | # |
I checked the source files with bzr diff, but i did not want to revert it because i _want_ to build with -j. (ok but i could have only committed the ai related files)
How should I comment the constant changes? In the commit message? I think a person who reads the source is not interested in the history of the constants.
SirVer (sirver) wrote : | # |
At the very least you should comment in the source code. And you should fix up whitespace issues and repropose for merging.
I am sorry if I appear to be strict. I am sure your work makes widelands better. Nevertheless, we need to keep some standards int the quality of the code.
Nicolai Hähnle (nha) wrote : | # |
Slightly off-topic for the discussion of this particular merge request, but this just highlights our need for some framework to properly judge the competitiveness of the AI, e.g. by letting different versions of it automatically play against each other.
Carli (s3734770) wrote : | # |
This is also off-topic, but should i design the AI more learnable?
SirVer (sirver) wrote : | # |
learnable is quite vague. Afaik most AI in games no longer use neural networks or similar because heuristics just perform so much better. Nevertheless, there is a bookshelve of literature on "good" game AI, some of them employ something like bayesian parameter tuning for "learning". That could be interesting of course.
Carli (s3734770) wrote : | # |
With "learnable" i ment parameter tuning. My question was related to the fact that I changed some constants in the AI code. They shouldnt be constants. (Or be defined in a extra header)
Nicolai Hähnle (nha) wrote : | # |
Yes, putting those parameters into a separate header or even a loadable file seems like a good idea. Even more so if it goes along with at least basic documentation of what the numbers actually mean.
SirVer (sirver) wrote : | # |
Is this pull request still up for discussion? I.e. are you still planing to work on it carli?
Carli (s3734770) wrote : | # |
> Is this pull request still up for discussion? I.e. are you still planing to
> work on it carli?
Currently not.
If someone would fix the C++ things with const vs & and such, it could be merged but otherwise I don't care.
SirVer (sirver) wrote : | # |
Thanks for the feedback. Okay, I am setting this to rejected than to get it out of the review queue. It is unlikely that someone wants to clean up other peoples code :).
Preview Diff
1 | === modified file 'compile.sh' |
2 | --- compile.sh 2010-11-15 21:23:02 +0000 |
3 | +++ compile.sh 2011-11-13 00:10:30 +0000 |
4 | @@ -136,7 +136,7 @@ |
5 | |
6 | echo " " |
7 | cmake -DWL_PORTABLE=true .. -DCMAKE_EXE_CXX_FLAGS="${CFLAGS}" -DCMAKE_BUILD_TYPE="${var_build_type}" |
8 | - make ${MAKEOPTS} |
9 | + make ${MAKEOPTS} -j |
10 | return 0 |
11 | } |
12 | |
13 | @@ -182,7 +182,7 @@ |
14 | echo " " |
15 | echo "bzr pull" |
16 | echo "cd build" |
17 | - echo "make" |
18 | + echo "make -j" |
19 | if [ $var_build_lang -eq 1 ] ; then |
20 | echo "make lang" |
21 | fi |
22 | |
23 | === modified file 'src/ai/ai_help_structs.h' |
24 | --- src/ai/ai_help_structs.h 2010-11-01 22:23:29 +0000 |
25 | +++ src/ai/ai_help_structs.h 2011-11-13 00:10:30 +0000 |
26 | @@ -268,6 +268,8 @@ |
27 | uint8_t producers; |
28 | uint8_t consumers; |
29 | uint8_t preciousness; |
30 | + uint32_t build_prio; |
31 | + uint32_t fight_prio; |
32 | }; |
33 | |
34 | #endif |
35 | |
36 | === modified file 'src/ai/defaultai.cc' |
37 | --- src/ai/defaultai.cc 2011-10-12 21:05:21 +0000 |
38 | +++ src/ai/defaultai.cc 2011-11-13 00:10:30 +0000 |
39 | @@ -232,6 +232,30 @@ |
40 | wares.at(i).producers = 0; |
41 | wares.at(i).consumers = 0; |
42 | wares.at(i).preciousness = tribe->get_ware_descr(i)->preciousness(); |
43 | + wares.at(i).build_prio = 0; |
44 | + wares.at(i).fight_prio = 0; |
45 | + } |
46 | + |
47 | + Ware_Index const nr_workers = tribe->get_nrworkers(); |
48 | + for (Ware_Index i = Ware_Index::First(); i < nr_workers; ++i) { |
49 | + // Find all build costs for soldiers |
50 | + // is it a soldier? |
51 | + if (tribe->get_worker_descr(i)->get_worker_type() == Worker_Descr::SOLDIER) { |
52 | + Worker_Descr::Buildcost::const_iterator end = tribe->get_worker_descr(i)->buildcost().end(); |
53 | + for |
54 | + (Worker_Descr::Buildcost::const_iterator it = tribe->get_worker_descr(i)->buildcost().begin(); |
55 | + it != end; ++it) |
56 | + { |
57 | + if (tribe->ware_index(it->first)) |
58 | + wares.at(tribe->ware_index(it->first)).fight_prio += it->second; // Add soldier-need priority |
59 | + } |
60 | + } |
61 | + } |
62 | + |
63 | + for (Ware_Index i = Ware_Index::First(); i < nr_wares; ++i) { |
64 | + // We have three building sites |
65 | + wares.at(i).consumers += wares.at(i).build_prio > 0 ? |
66 | + (wares.at(i).build_prio > 30 ? 2 : 1) : 0; |
67 | } |
68 | |
69 | // collect information about the different buildings our tribe can construct |
70 | @@ -255,6 +279,12 @@ |
71 | bo.current_stats = 100; |
72 | bo.unoccupied = false; |
73 | |
74 | + // Find all build costs |
75 | + Buildcost::const_iterator end = bld.buildcost().end(); |
76 | + for (Buildcost::const_iterator it = bld.buildcost().begin(); it != end; ++it) { |
77 | + wares.at(it->first).build_prio += it->second; // Add build-need priority |
78 | + } |
79 | + |
80 | bo.is_basic = false; |
81 | |
82 | bo.is_buildable = bld.is_buildable(); |
83 | @@ -278,7 +308,8 @@ |
84 | BuildingObserver::PRODUCTIONSITE; |
85 | |
86 | container_iterate_const(Ware_Types, prod.inputs(), j) |
87 | - bo.inputs.push_back(j.current->first.value()); |
88 | + for (uint32_t i = 0; i < j.current->second; i++) // consider input count |
89 | + bo.inputs.push_back(j.current->first.value()); |
90 | |
91 | container_iterate_const |
92 | (ProductionSite_Descr::Output, prod.output_ware_types(), j) |
93 | @@ -318,6 +349,17 @@ |
94 | } |
95 | } |
96 | |
97 | + for (Ware_Index i = Ware_Index::First(); i < nr_wares; ++i) { |
98 | + if (wares.at(i).build_prio) |
99 | + printf |
100 | + ("Ware %s ist construction material with priority %d (ToDo: use this information)\n", |
101 | + tribe->get_ware_descr(i)->name().data(), wares.at(i).build_prio); |
102 | + if (wares.at(i).fight_prio) |
103 | + printf |
104 | + ("Ware %s ist fight material with priority %d (ToDo: use this information)\n", |
105 | + tribe->get_ware_descr(i)->name().data(), wares.at(i).fight_prio); |
106 | + } |
107 | + |
108 | total_constructionsites = 0; |
109 | next_construction_due = 0; |
110 | next_road_due = 1000; |
111 | @@ -767,7 +809,7 @@ |
112 | spots += spots_avail.at(BUILDCAPS_MEDIUM); |
113 | spots += spots_avail.at(BUILDCAPS_BIG); |
114 | if (type == AGGRESSIVE) |
115 | - spots -= militarysites.size() / 20; |
116 | + spots -= militarysites.size() / 30; |
117 | if (spots < 16) |
118 | expand_factor *= 2; |
119 | if ((type == AGGRESSIVE) && spots < 32) |
120 | @@ -791,7 +833,7 @@ |
121 | //if (TODO) expand_factor = 0; |
122 | |
123 | // Defensive AIs also attack sometimes (when they want to expand) |
124 | - if (type == DEFENSIVE && expand_factor > 1) |
125 | + if (expand_factor > 1) |
126 | if (next_attack_consideration_due <= game().get_gametime()) |
127 | consider_attack(game().get_gametime()); |
128 | |
129 | @@ -863,8 +905,8 @@ |
130 | continue; |
131 | if (bo.need_trees) { |
132 | // Priority of woodcutters depend on the number of near trees |
133 | - prio += bf->trees_nearby * 3; |
134 | - prio /= 3 * (1 + bf->producers_nearby.at(bo.outputs.at(0))); |
135 | + prio += bf->trees_nearby * 4; |
136 | + prio /= 2 * (1 + bf->producers_nearby.at(bo.outputs.at(0))); |
137 | |
138 | // TODO improve this - it's still useless to place lumberjack huts randomly |
139 | /*if (prio <= 0) // no, sometimes we need wood without having a forest |
140 | @@ -898,6 +940,7 @@ |
141 | // production hint (f.e. associate forester with trunks) |
142 | |
143 | // Calculate the need for this building |
144 | + |
145 | int16_t inout = wares.at(bo.production_hint).consumers; |
146 | if |
147 | (tribe->safe_ware_index("trunk").value() |
148 | @@ -907,6 +950,8 @@ |
149 | inout -= wares.at(bo.production_hint).producers; |
150 | if (inout < 1) |
151 | inout = 1; |
152 | + if (inout > 3) |
153 | + inout = 2; |
154 | // the ware they're refreshing |
155 | Ware_Index wt(static_cast<size_t>(bo.production_hint)); |
156 | container_iterate(std::list<EconomyObserver *>, economies, l) { |
157 | @@ -948,12 +993,23 @@ |
158 | prio = recalc_with_border_range(*bf, prio); |
159 | } else { // "normal" productionsites |
160 | |
161 | - // ToDo: prefer soldier producing things |
162 | // Ware_Index const soldier_index = tribe().worker_index("soldier"); |
163 | |
164 | if (bo.is_basic && (bo.total_count() == 0)) |
165 | prio += 100; // for very important buildings |
166 | |
167 | + |
168 | + |
169 | + // we can enhance this building. build more |
170 | + // maybe the enhancement can produce needed ware |
171 | + if (bo.desc->enhancements().size() > 0) { |
172 | + // this code builds more metalworks |
173 | + if (bo.total_count() == 0) |
174 | + prio += 10; |
175 | + if (bo.total_count() == 1) |
176 | + prio += 2; |
177 | + } |
178 | + |
179 | // Check if the produced wares are needed |
180 | container_iterate(std::list<EconomyObserver *>, economies, l) { |
181 | // Don't check if the economy has no warehouse. |
182 | @@ -968,6 +1024,11 @@ |
183 | (*l.current)->economy.ware_target_quantity(wt).permanent) |
184 | prio -= 20; |
185 | |
186 | + // if we have none of them, but they are construction material, build! |
187 | + if (bo.total_count() == 0 && wares.at(bo.outputs.at(m)).build_prio) { |
188 | + prio += 100; |
189 | + } |
190 | + |
191 | // if the economy needs this ware |
192 | if ((*l.current)->economy.needs_ware(wt)) { |
193 | prio += 1 + wares.at(bo.outputs.at(m)).preciousness; |
194 | @@ -975,16 +1036,6 @@ |
195 | // big bonus, this site might be elemental |
196 | prio += 3 * wares.at(bo.outputs.at(m)).preciousness; |
197 | } |
198 | - |
199 | - // we can enhance this building. build more |
200 | - // maybe the enhancement can produce needed ware |
201 | - if (bo.desc->enhancements().size() > 0) { |
202 | - // this code builds more metalworks |
203 | - if (bo.total_count() == 0) |
204 | - prio += 2; |
205 | - if (bo.total_count() == 1) |
206 | - prio += 8; |
207 | - } |
208 | } |
209 | for (uint32_t m = 0; m < bo.inputs.size(); ++m) { |
210 | Ware_Index wt(static_cast<size_t>(bo.inputs.at(m))); |
211 | @@ -1018,14 +1069,14 @@ |
212 | |
213 | // do not construct more than one building, |
214 | // if supply line is already broken. |
215 | - if (!check_supply(bo) && bo.total_count() > 0) |
216 | + if (bo.total_count() > 0 && !check_supply(bo)) |
217 | prio -= 12; |
218 | |
219 | } |
220 | } else if (bo.type == BuildingObserver::MILITARYSITE) { |
221 | if (!bf->unowned_land_nearby) |
222 | continue; |
223 | - prio = bf->unowned_land_nearby * (1 + type); |
224 | + prio = bf->unowned_land_nearby * (2 + type); |
225 | prio -= bf->military_influence * (5 - type); |
226 | // set to at least 1 |
227 | prio = prio > 0 ? prio : 1; |
228 | @@ -1033,14 +1084,14 @@ |
229 | prio /= 2; |
230 | |
231 | if (bf->enemy_nearby) |
232 | - prio *= 2; |
233 | + prio = (prio * 5) / 4; |
234 | else |
235 | prio -= bf->military_influence * 2; |
236 | |
237 | if (bf->avoid_military) |
238 | prio /= 5; |
239 | |
240 | - prio -= militarysites.size() - productionsites.size() / (3 - type); |
241 | + prio -= militarysites.size() - productionsites.size() / (4 - type); |
242 | |
243 | } else if (bo.type == BuildingObserver::WAREHOUSE) { |
244 | // Build one warehouse for ~every 35 productionsites and mines. |
245 | @@ -1209,7 +1260,7 @@ |
246 | // multiply with current statistics of all other buildings of this |
247 | // type to avoid constructing buildings where already some are running |
248 | // on low resources. |
249 | - prio *= 5 + bo.current_stats; |
250 | + prio *= 40 + bo.current_stats; |
251 | prio /= 100; |
252 | |
253 | if (onlymissing) // mines aren't *that* important |
254 | @@ -1613,7 +1664,7 @@ |
255 | // destruct the building and it's flag (via flag destruction) |
256 | // the destruction of the flag avoids that defaultAI will have too many |
257 | // unused roads - if needed the road will be rebuild directly. |
258 | - game().send_player_bulldoze(site.site->base_flag()); |
259 | + game().send_player_dismantle(*(site.site)); |
260 | return true; |
261 | } |
262 | } |
263 | @@ -1632,7 +1683,7 @@ |
264 | // destruct the building and it's flag (via flag destruction) |
265 | // the destruction of the flag avoids that defaultAI will have too many |
266 | // unused roads - if needed the road will be rebuild directly. |
267 | - game().send_player_bulldoze(site.site->base_flag()); |
268 | + game().send_player_dismantle(*(site.site)); |
269 | return true; |
270 | } |
271 | |
272 | @@ -1662,7 +1713,7 @@ |
273 | // |
274 | // Add a bonus if one building of this type is still unoccupied |
275 | if (((game().get_gametime() % 4) + site.bo->unoccupied) > 2) { |
276 | - game().send_player_bulldoze(site.site->base_flag()); |
277 | + game().send_player_dismantle(*(site.site)); |
278 | return true; |
279 | } |
280 | else |
281 | @@ -1675,7 +1726,7 @@ |
282 | |
283 | // Do not have too many constructionsites |
284 | uint32_t producers = mines.size() + productionsites.size(); |
285 | - if (total_constructionsites >= (5 + (producers / 10))) |
286 | + if (total_constructionsites >= (5 + (producers / 5))) |
287 | return false; |
288 | |
289 | // Check whether building is enhanceable and if wares of the enhanced |
290 | @@ -1709,7 +1760,7 @@ |
291 | Ware_Index wt(static_cast<size_t>(current_outputs.at(j))); |
292 | if (site.site->economy().needs_ware(wt)) |
293 | prio -= |
294 | - (2 + wares.at(current_outputs.at(j)).preciousness) / 2; |
295 | + (2 + wares.at(current_outputs.at(j)).preciousness) / 4; |
296 | continue; |
297 | } |
298 | new_outputs.push_back(static_cast<int16_t>(i)); |
299 | @@ -1718,28 +1769,30 @@ |
300 | // Check if the new wares are needed in economy of the building |
301 | for (uint32_t i = 0; i < new_outputs.size(); ++i) { |
302 | Ware_Index wt(static_cast<size_t>(new_outputs.at(i))); |
303 | - if (site.site->economy().needs_ware(wt)) |
304 | + if (site.site->economy().needs_ware(wt) || wares.at(wt).fight_prio) |
305 | prio += 2 + wares.at(new_outputs.at(i)).preciousness; |
306 | } |
307 | |
308 | // Compare the number of buildings of current type with the number |
309 | // of buildings of enhanced type |
310 | - prio += (site.bo->total_count() - en_bo.total_count()) * 2; |
311 | + prio += (2 * site.bo->total_count() - en_bo.total_count()); |
312 | |
313 | // If the new wares are needed |
314 | if (prio > 0) { |
315 | prio = calculate_need_for_ps(en_bo, prio); |
316 | if (prio > maxprio) { |
317 | + // we always enhance if it is the first building of this type |
318 | + if (en_bo.total_count() == 0) prio += 500; |
319 | maxprio = prio; |
320 | enbld = (*x.current); |
321 | } |
322 | - } |
323 | + }; |
324 | } |
325 | } |
326 | |
327 | // Enhance if enhanced building is useful |
328 | // additional: we dont want to lose the old building |
329 | - if (maxprio > 0 && site.bo->total_count() > 1) { |
330 | + if (maxprio > 0 && (maxprio > 500 || site.bo->total_count() > 1)) { |
331 | game().send_player_enhance_building(*site.site, enbld); |
332 | changed = true; |
333 | } |
334 | @@ -1778,7 +1831,7 @@ |
335 | // destruct the building and it's flag (via flag destruction) |
336 | // the destruction of the flag avoids that defaultAI will have too many |
337 | // unused roads - if needed the road will be rebuild directly. |
338 | - game().send_player_bulldoze(site.site->base_flag()); |
339 | + game().send_player_dismantle(*(site.site)); |
340 | return true; |
341 | } |
342 | |
343 | @@ -1880,7 +1933,7 @@ |
344 | (static_cast<int32_t>(ms->maxSoldierCapacity() * 4) |
345 | < |
346 | bf.military_influence) |
347 | - game().send_player_bulldoze(ms->base_flag()); |
348 | + game().send_player_dismantle(*ms); |
349 | |
350 | // Else consider enhancing the building (if possible) |
351 | else { |
352 | @@ -1995,7 +2048,7 @@ |
353 | WareObserver & wo = wares.at(bo.outputs.at(k)); |
354 | if (wo.consumers > 0) { |
355 | output_prio += wo.preciousness; |
356 | - output_prio += wo.consumers * 2; |
357 | + output_prio += wo.consumers * 3; |
358 | output_prio -= wo.producers * 2; |
359 | if (bo.total_count() == 0) |
360 | output_prio += 10; // add a big bonus |
361 | @@ -2006,12 +2059,18 @@ |
362 | (ceil(output_prio / sqrt(static_cast<double>(bo.outputs.size())))); |
363 | prio += 2 * output_prio; |
364 | |
365 | + if (!bo.inputs.empty() && !bo.outputs.empty() && bo.current_stats >= 80) { |
366 | + // extra bonus for high productivity |
367 | + // this should compensate various output count of a production step |
368 | + prio += 10; |
369 | + } |
370 | + |
371 | // If building consumes some wares, multiply with current statistics of all |
372 | // other buildings of this type to avoid constructing buildings where already |
373 | // some are running on low resources. |
374 | // Else at least add a part of the stats t the calculation. |
375 | if (!bo.inputs.empty()) { |
376 | - prio *= bo.current_stats; |
377 | + prio = (prio + 50) * bo.current_stats; |
378 | prio /= 100; |
379 | } else |
380 | prio = ((prio * bo.current_stats) / 100) + (prio / 2); |
381 | @@ -2142,8 +2201,14 @@ |
382 | militarysites.back().site = &ref_cast<MilitarySite, Building>(b); |
383 | militarysites.back().bo = &bo; |
384 | militarysites.back().checks = bo.desc->get_size(); |
385 | - } else if (bo.type == BuildingObserver::WAREHOUSE) |
386 | + } else if (bo.type == BuildingObserver::WAREHOUSE) { |
387 | ++numof_warehouses; |
388 | + Ware_Index const nr_wares = tribe->get_nrwares(); |
389 | + for (Ware_Index i = Ware_Index::First(); i < nr_wares; ++i) { |
390 | + // Warehouses are consumers of weapons |
391 | + wares.at(i).consumers += 2 * wares.at(i).fight_prio; |
392 | + } |
393 | + } |
394 | } |
395 | } |
396 | |
397 | @@ -2207,6 +2272,11 @@ |
398 | } else if (bo.type == BuildingObserver::WAREHOUSE) { |
399 | assert(numof_warehouses > 0); |
400 | --numof_warehouses; |
401 | + Ware_Index const nr_wares = tribe->get_nrwares(); |
402 | + for (Ware_Index i = Ware_Index::First(); i < nr_wares; ++i) { |
403 | + // Warehouses are consumers of weapons |
404 | + wares.at(i).consumers -= 2 * wares.at(i).fight_prio; |
405 | + } |
406 | } |
407 | } |
408 | m_buildable_changed = true; |
409 | @@ -2220,23 +2290,23 @@ |
410 | // TODO: It needs profiling and optimization. |
411 | bool DefaultAI::check_supply(BuildingObserver const & bo) |
412 | { |
413 | - size_t supplied = 0; |
414 | container_iterate_const(std::vector<int16_t>, bo.inputs, i) |
415 | container_iterate_const(std::vector<BuildingObserver>, buildings, j) |
416 | if |
417 | (j.current->cnt_built && |
418 | - std::find |
419 | - (j.current->outputs.begin(), j.current->outputs.end(), |
420 | - *i.current) |
421 | - != |
422 | - j.current->outputs.end() |
423 | - && |
424 | - check_supply(*j.current)) |
425 | + std::find |
426 | + (j.current->outputs.begin(), j.current->outputs.end(), |
427 | + *i.current) |
428 | + != |
429 | + j.current->outputs.end() |
430 | + && |
431 | + check_supply(*j.current)) |
432 | { |
433 | - ++supplied; |
434 | break; |
435 | + } else { |
436 | + return false; |
437 | } |
438 | - return supplied == bo.inputs.size(); |
439 | + return true; |
440 | } |
441 | |
442 | |
443 | @@ -2277,12 +2347,12 @@ |
444 | continue; |
445 | if (bld->canAttack()) { |
446 | int32_t ta = player->findAttackSoldiers(bld->base_flag()); |
447 | - if (type == NORMAL) |
448 | - ta = ta * 2 / 3; |
449 | + if (type != AGGRESSIVE) |
450 | + ta = (ta * 2) / 3; |
451 | if (ta < 1) |
452 | continue; |
453 | |
454 | - int32_t const tc = ta - bld->presentSoldiers().size(); |
455 | + int32_t const tc = ta * 2 - bld->presentSoldiers().size() * 3; |
456 | if (tc > chance) { |
457 | target = bld; |
458 | chance = tc; |
459 | @@ -2313,7 +2383,7 @@ |
460 | |
461 | // Return if chance to win is too low |
462 | if (chance < 3) { |
463 | - next_attack_consideration_due = gametime % 7 * 1000 + gametime; |
464 | + next_attack_consideration_due = (2 + gametime % 7) * 1000 + gametime; |
465 | return false; |
466 | } |
467 | |
468 | @@ -2326,6 +2396,6 @@ |
469 | (target->base_flag(), pn, attackers, retreat); |
470 | |
471 | // Do not attack again too soon - returning soldiers must get healed first. |
472 | - next_attack_consideration_due = (gametime % 51 + 10) * 1000 + gametime; |
473 | + next_attack_consideration_due = (gametime % 51 + 20) * 1000 + gametime; |
474 | return true; |
475 | } |
476 | |
477 | === modified file 'src/ui_basic/table.cc' |
478 | --- src/ui_basic/table.cc 2011-11-06 14:23:36 +0000 |
479 | +++ src/ui_basic/table.cc 2011-11-13 00:10:30 +0000 |
480 | @@ -429,6 +429,7 @@ |
481 | return result; |
482 | } |
483 | |
484 | + |
485 | /** |
486 | * Scroll to the given position, in pixels. |
487 | */ |
Cool that you work on that. However your changes also contain changes to compile.sh; and also I saw that you replaced bulldoze via dismantle. This let's the flag standing and let to problems in the past. Have you seen this as well?