Merge lp:~s3734770/widelands/carli-ai into lp:widelands

Proposed by Carli
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
Reviewer Review Type Date Requested Status
SirVer Needs Fixing
Review via email: mp+82061@code.launchpad.net

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

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

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?

review: Needs Fixing
Revision history for this message
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?

Revision history for this message
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?

Revision history for this message
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.

Revision history for this message
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.

review: Needs Fixing
Revision history for this message
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.

Revision history for this message
Carli (s3734770) wrote :

This is also off-topic, but should i design the AI more learnable?

Revision history for this message
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.

Revision history for this message
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)

Revision history for this message
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.

Revision history for this message
SirVer (sirver) wrote :

Is this pull request still up for discussion? I.e. are you still planing to work on it carli?

Revision history for this message
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.

Revision history for this message
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 :).

Unmerged revisions

6100. By Carli

Improved AI (is now able to defeat other AI enemies)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'compile.sh'
--- compile.sh 2010-11-15 21:23:02 +0000
+++ compile.sh 2011-11-13 00:10:30 +0000
@@ -136,7 +136,7 @@
136136
137 echo " "137 echo " "
138 cmake -DWL_PORTABLE=true .. -DCMAKE_EXE_CXX_FLAGS="${CFLAGS}" -DCMAKE_BUILD_TYPE="${var_build_type}"138 cmake -DWL_PORTABLE=true .. -DCMAKE_EXE_CXX_FLAGS="${CFLAGS}" -DCMAKE_BUILD_TYPE="${var_build_type}"
139 make ${MAKEOPTS}139 make ${MAKEOPTS} -j
140 return 0140 return 0
141 }141 }
142142
@@ -182,7 +182,7 @@
182 echo " "182 echo " "
183 echo "bzr pull"183 echo "bzr pull"
184 echo "cd build"184 echo "cd build"
185 echo "make"185 echo "make -j"
186 if [ $var_build_lang -eq 1 ] ; then186 if [ $var_build_lang -eq 1 ] ; then
187 echo "make lang"187 echo "make lang"
188 fi188 fi
189189
=== modified file 'src/ai/ai_help_structs.h'
--- src/ai/ai_help_structs.h 2010-11-01 22:23:29 +0000
+++ src/ai/ai_help_structs.h 2011-11-13 00:10:30 +0000
@@ -268,6 +268,8 @@
268 uint8_t producers;268 uint8_t producers;
269 uint8_t consumers;269 uint8_t consumers;
270 uint8_t preciousness;270 uint8_t preciousness;
271 uint32_t build_prio;
272 uint32_t fight_prio;
271};273};
272274
273#endif275#endif
274276
=== modified file 'src/ai/defaultai.cc'
--- src/ai/defaultai.cc 2011-10-12 21:05:21 +0000
+++ src/ai/defaultai.cc 2011-11-13 00:10:30 +0000
@@ -232,6 +232,30 @@
232 wares.at(i).producers = 0;232 wares.at(i).producers = 0;
233 wares.at(i).consumers = 0;233 wares.at(i).consumers = 0;
234 wares.at(i).preciousness = tribe->get_ware_descr(i)->preciousness();234 wares.at(i).preciousness = tribe->get_ware_descr(i)->preciousness();
235 wares.at(i).build_prio = 0;
236 wares.at(i).fight_prio = 0;
237 }
238
239 Ware_Index const nr_workers = tribe->get_nrworkers();
240 for (Ware_Index i = Ware_Index::First(); i < nr_workers; ++i) {
241 // Find all build costs for soldiers
242 // is it a soldier?
243 if (tribe->get_worker_descr(i)->get_worker_type() == Worker_Descr::SOLDIER) {
244 Worker_Descr::Buildcost::const_iterator end = tribe->get_worker_descr(i)->buildcost().end();
245 for
246 (Worker_Descr::Buildcost::const_iterator it = tribe->get_worker_descr(i)->buildcost().begin();
247 it != end; ++it)
248 {
249 if (tribe->ware_index(it->first))
250 wares.at(tribe->ware_index(it->first)).fight_prio += it->second; // Add soldier-need priority
251 }
252 }
253 }
254
255 for (Ware_Index i = Ware_Index::First(); i < nr_wares; ++i) {
256 // We have three building sites
257 wares.at(i).consumers += wares.at(i).build_prio > 0 ?
258 (wares.at(i).build_prio > 30 ? 2 : 1) : 0;
235 }259 }
236260
237 // collect information about the different buildings our tribe can construct261 // collect information about the different buildings our tribe can construct
@@ -255,6 +279,12 @@
255 bo.current_stats = 100;279 bo.current_stats = 100;
256 bo.unoccupied = false;280 bo.unoccupied = false;
257281
282 // Find all build costs
283 Buildcost::const_iterator end = bld.buildcost().end();
284 for (Buildcost::const_iterator it = bld.buildcost().begin(); it != end; ++it) {
285 wares.at(it->first).build_prio += it->second; // Add build-need priority
286 }
287
258 bo.is_basic = false;288 bo.is_basic = false;
259289
260 bo.is_buildable = bld.is_buildable();290 bo.is_buildable = bld.is_buildable();
@@ -278,7 +308,8 @@
278 BuildingObserver::PRODUCTIONSITE;308 BuildingObserver::PRODUCTIONSITE;
279309
280 container_iterate_const(Ware_Types, prod.inputs(), j)310 container_iterate_const(Ware_Types, prod.inputs(), j)
281 bo.inputs.push_back(j.current->first.value());311 for (uint32_t i = 0; i < j.current->second; i++) // consider input count
312 bo.inputs.push_back(j.current->first.value());
282313
283 container_iterate_const314 container_iterate_const
284 (ProductionSite_Descr::Output, prod.output_ware_types(), j)315 (ProductionSite_Descr::Output, prod.output_ware_types(), j)
@@ -318,6 +349,17 @@
318 }349 }
319 }350 }
320351
352 for (Ware_Index i = Ware_Index::First(); i < nr_wares; ++i) {
353 if (wares.at(i).build_prio)
354 printf
355 ("Ware %s ist construction material with priority %d (ToDo: use this information)\n",
356 tribe->get_ware_descr(i)->name().data(), wares.at(i).build_prio);
357 if (wares.at(i).fight_prio)
358 printf
359 ("Ware %s ist fight material with priority %d (ToDo: use this information)\n",
360 tribe->get_ware_descr(i)->name().data(), wares.at(i).fight_prio);
361 }
362
321 total_constructionsites = 0;363 total_constructionsites = 0;
322 next_construction_due = 0;364 next_construction_due = 0;
323 next_road_due = 1000;365 next_road_due = 1000;
@@ -767,7 +809,7 @@
767 spots += spots_avail.at(BUILDCAPS_MEDIUM);809 spots += spots_avail.at(BUILDCAPS_MEDIUM);
768 spots += spots_avail.at(BUILDCAPS_BIG);810 spots += spots_avail.at(BUILDCAPS_BIG);
769 if (type == AGGRESSIVE)811 if (type == AGGRESSIVE)
770 spots -= militarysites.size() / 20;812 spots -= militarysites.size() / 30;
771 if (spots < 16)813 if (spots < 16)
772 expand_factor *= 2;814 expand_factor *= 2;
773 if ((type == AGGRESSIVE) && spots < 32)815 if ((type == AGGRESSIVE) && spots < 32)
@@ -791,7 +833,7 @@
791 //if (TODO) expand_factor = 0;833 //if (TODO) expand_factor = 0;
792834
793 // Defensive AIs also attack sometimes (when they want to expand)835 // Defensive AIs also attack sometimes (when they want to expand)
794 if (type == DEFENSIVE && expand_factor > 1)836 if (expand_factor > 1)
795 if (next_attack_consideration_due <= game().get_gametime())837 if (next_attack_consideration_due <= game().get_gametime())
796 consider_attack(game().get_gametime());838 consider_attack(game().get_gametime());
797839
@@ -863,8 +905,8 @@
863 continue;905 continue;
864 if (bo.need_trees) {906 if (bo.need_trees) {
865 // Priority of woodcutters depend on the number of near trees907 // Priority of woodcutters depend on the number of near trees
866 prio += bf->trees_nearby * 3;908 prio += bf->trees_nearby * 4;
867 prio /= 3 * (1 + bf->producers_nearby.at(bo.outputs.at(0)));909 prio /= 2 * (1 + bf->producers_nearby.at(bo.outputs.at(0)));
868910
869 // TODO improve this - it's still useless to place lumberjack huts randomly911 // TODO improve this - it's still useless to place lumberjack huts randomly
870 /*if (prio <= 0) // no, sometimes we need wood without having a forest912 /*if (prio <= 0) // no, sometimes we need wood without having a forest
@@ -898,6 +940,7 @@
898 // production hint (f.e. associate forester with trunks)940 // production hint (f.e. associate forester with trunks)
899941
900 // Calculate the need for this building942 // Calculate the need for this building
943
901 int16_t inout = wares.at(bo.production_hint).consumers;944 int16_t inout = wares.at(bo.production_hint).consumers;
902 if945 if
903 (tribe->safe_ware_index("trunk").value()946 (tribe->safe_ware_index("trunk").value()
@@ -907,6 +950,8 @@
907 inout -= wares.at(bo.production_hint).producers;950 inout -= wares.at(bo.production_hint).producers;
908 if (inout < 1)951 if (inout < 1)
909 inout = 1;952 inout = 1;
953 if (inout > 3)
954 inout = 2;
910 // the ware they're refreshing955 // the ware they're refreshing
911 Ware_Index wt(static_cast<size_t>(bo.production_hint));956 Ware_Index wt(static_cast<size_t>(bo.production_hint));
912 container_iterate(std::list<EconomyObserver *>, economies, l) {957 container_iterate(std::list<EconomyObserver *>, economies, l) {
@@ -948,12 +993,23 @@
948 prio = recalc_with_border_range(*bf, prio);993 prio = recalc_with_border_range(*bf, prio);
949 } else { // "normal" productionsites994 } else { // "normal" productionsites
950995
951 // ToDo: prefer soldier producing things
952 // Ware_Index const soldier_index = tribe().worker_index("soldier");996 // Ware_Index const soldier_index = tribe().worker_index("soldier");
953997
954 if (bo.is_basic && (bo.total_count() == 0))998 if (bo.is_basic && (bo.total_count() == 0))
955 prio += 100; // for very important buildings999 prio += 100; // for very important buildings
9561000
1001
1002
1003 // we can enhance this building. build more
1004 // maybe the enhancement can produce needed ware
1005 if (bo.desc->enhancements().size() > 0) {
1006 // this code builds more metalworks
1007 if (bo.total_count() == 0)
1008 prio += 10;
1009 if (bo.total_count() == 1)
1010 prio += 2;
1011 }
1012
957 // Check if the produced wares are needed1013 // Check if the produced wares are needed
958 container_iterate(std::list<EconomyObserver *>, economies, l) {1014 container_iterate(std::list<EconomyObserver *>, economies, l) {
959 // Don't check if the economy has no warehouse.1015 // Don't check if the economy has no warehouse.
@@ -968,6 +1024,11 @@
968 (*l.current)->economy.ware_target_quantity(wt).permanent)1024 (*l.current)->economy.ware_target_quantity(wt).permanent)
969 prio -= 20;1025 prio -= 20;
9701026
1027 // if we have none of them, but they are construction material, build!
1028 if (bo.total_count() == 0 && wares.at(bo.outputs.at(m)).build_prio) {
1029 prio += 100;
1030 }
1031
971 // if the economy needs this ware1032 // if the economy needs this ware
972 if ((*l.current)->economy.needs_ware(wt)) {1033 if ((*l.current)->economy.needs_ware(wt)) {
973 prio += 1 + wares.at(bo.outputs.at(m)).preciousness;1034 prio += 1 + wares.at(bo.outputs.at(m)).preciousness;
@@ -975,16 +1036,6 @@
975 // big bonus, this site might be elemental1036 // big bonus, this site might be elemental
976 prio += 3 * wares.at(bo.outputs.at(m)).preciousness;1037 prio += 3 * wares.at(bo.outputs.at(m)).preciousness;
977 }1038 }
978
979 // we can enhance this building. build more
980 // maybe the enhancement can produce needed ware
981 if (bo.desc->enhancements().size() > 0) {
982 // this code builds more metalworks
983 if (bo.total_count() == 0)
984 prio += 2;
985 if (bo.total_count() == 1)
986 prio += 8;
987 }
988 }1039 }
989 for (uint32_t m = 0; m < bo.inputs.size(); ++m) {1040 for (uint32_t m = 0; m < bo.inputs.size(); ++m) {
990 Ware_Index wt(static_cast<size_t>(bo.inputs.at(m)));1041 Ware_Index wt(static_cast<size_t>(bo.inputs.at(m)));
@@ -1018,14 +1069,14 @@
10181069
1019 // do not construct more than one building,1070 // do not construct more than one building,
1020 // if supply line is already broken.1071 // if supply line is already broken.
1021 if (!check_supply(bo) && bo.total_count() > 0)1072 if (bo.total_count() > 0 && !check_supply(bo))
1022 prio -= 12;1073 prio -= 12;
10231074
1024 }1075 }
1025 } else if (bo.type == BuildingObserver::MILITARYSITE) {1076 } else if (bo.type == BuildingObserver::MILITARYSITE) {
1026 if (!bf->unowned_land_nearby)1077 if (!bf->unowned_land_nearby)
1027 continue;1078 continue;
1028 prio = bf->unowned_land_nearby * (1 + type);1079 prio = bf->unowned_land_nearby * (2 + type);
1029 prio -= bf->military_influence * (5 - type);1080 prio -= bf->military_influence * (5 - type);
1030 // set to at least 11081 // set to at least 1
1031 prio = prio > 0 ? prio : 1;1082 prio = prio > 0 ? prio : 1;
@@ -1033,14 +1084,14 @@
1033 prio /= 2;1084 prio /= 2;
10341085
1035 if (bf->enemy_nearby)1086 if (bf->enemy_nearby)
1036 prio *= 2;1087 prio = (prio * 5) / 4;
1037 else1088 else
1038 prio -= bf->military_influence * 2;1089 prio -= bf->military_influence * 2;
10391090
1040 if (bf->avoid_military)1091 if (bf->avoid_military)
1041 prio /= 5;1092 prio /= 5;
10421093
1043 prio -= militarysites.size() - productionsites.size() / (3 - type);1094 prio -= militarysites.size() - productionsites.size() / (4 - type);
10441095
1045 } else if (bo.type == BuildingObserver::WAREHOUSE) {1096 } else if (bo.type == BuildingObserver::WAREHOUSE) {
1046 // Build one warehouse for ~every 35 productionsites and mines.1097 // Build one warehouse for ~every 35 productionsites and mines.
@@ -1209,7 +1260,7 @@
1209 // multiply with current statistics of all other buildings of this1260 // multiply with current statistics of all other buildings of this
1210 // type to avoid constructing buildings where already some are running1261 // type to avoid constructing buildings where already some are running
1211 // on low resources.1262 // on low resources.
1212 prio *= 5 + bo.current_stats;1263 prio *= 40 + bo.current_stats;
1213 prio /= 100;1264 prio /= 100;
12141265
1215 if (onlymissing) // mines aren't *that* important1266 if (onlymissing) // mines aren't *that* important
@@ -1613,7 +1664,7 @@
1613 // destruct the building and it's flag (via flag destruction)1664 // destruct the building and it's flag (via flag destruction)
1614 // the destruction of the flag avoids that defaultAI will have too many1665 // the destruction of the flag avoids that defaultAI will have too many
1615 // unused roads - if needed the road will be rebuild directly.1666 // unused roads - if needed the road will be rebuild directly.
1616 game().send_player_bulldoze(site.site->base_flag());1667 game().send_player_dismantle(*(site.site));
1617 return true;1668 return true;
1618 }1669 }
1619 }1670 }
@@ -1632,7 +1683,7 @@
1632 // destruct the building and it's flag (via flag destruction)1683 // destruct the building and it's flag (via flag destruction)
1633 // the destruction of the flag avoids that defaultAI will have too many1684 // the destruction of the flag avoids that defaultAI will have too many
1634 // unused roads - if needed the road will be rebuild directly.1685 // unused roads - if needed the road will be rebuild directly.
1635 game().send_player_bulldoze(site.site->base_flag());1686 game().send_player_dismantle(*(site.site));
1636 return true;1687 return true;
1637 }1688 }
16381689
@@ -1662,7 +1713,7 @@
1662 //1713 //
1663 // Add a bonus if one building of this type is still unoccupied1714 // Add a bonus if one building of this type is still unoccupied
1664 if (((game().get_gametime() % 4) + site.bo->unoccupied) > 2) {1715 if (((game().get_gametime() % 4) + site.bo->unoccupied) > 2) {
1665 game().send_player_bulldoze(site.site->base_flag());1716 game().send_player_dismantle(*(site.site));
1666 return true;1717 return true;
1667 }1718 }
1668 else1719 else
@@ -1675,7 +1726,7 @@
16751726
1676 // Do not have too many constructionsites1727 // Do not have too many constructionsites
1677 uint32_t producers = mines.size() + productionsites.size();1728 uint32_t producers = mines.size() + productionsites.size();
1678 if (total_constructionsites >= (5 + (producers / 10)))1729 if (total_constructionsites >= (5 + (producers / 5)))
1679 return false;1730 return false;
16801731
1681 // Check whether building is enhanceable and if wares of the enhanced1732 // Check whether building is enhanceable and if wares of the enhanced
@@ -1709,7 +1760,7 @@
1709 Ware_Index wt(static_cast<size_t>(current_outputs.at(j)));1760 Ware_Index wt(static_cast<size_t>(current_outputs.at(j)));
1710 if (site.site->economy().needs_ware(wt))1761 if (site.site->economy().needs_ware(wt))
1711 prio -=1762 prio -=
1712 (2 + wares.at(current_outputs.at(j)).preciousness) / 2;1763 (2 + wares.at(current_outputs.at(j)).preciousness) / 4;
1713 continue;1764 continue;
1714 }1765 }
1715 new_outputs.push_back(static_cast<int16_t>(i));1766 new_outputs.push_back(static_cast<int16_t>(i));
@@ -1718,28 +1769,30 @@
1718 // Check if the new wares are needed in economy of the building1769 // Check if the new wares are needed in economy of the building
1719 for (uint32_t i = 0; i < new_outputs.size(); ++i) {1770 for (uint32_t i = 0; i < new_outputs.size(); ++i) {
1720 Ware_Index wt(static_cast<size_t>(new_outputs.at(i)));1771 Ware_Index wt(static_cast<size_t>(new_outputs.at(i)));
1721 if (site.site->economy().needs_ware(wt))1772 if (site.site->economy().needs_ware(wt) || wares.at(wt).fight_prio)
1722 prio += 2 + wares.at(new_outputs.at(i)).preciousness;1773 prio += 2 + wares.at(new_outputs.at(i)).preciousness;
1723 }1774 }
17241775
1725 // Compare the number of buildings of current type with the number1776 // Compare the number of buildings of current type with the number
1726 // of buildings of enhanced type1777 // of buildings of enhanced type
1727 prio += (site.bo->total_count() - en_bo.total_count()) * 2;1778 prio += (2 * site.bo->total_count() - en_bo.total_count());
17281779
1729 // If the new wares are needed1780 // If the new wares are needed
1730 if (prio > 0) {1781 if (prio > 0) {
1731 prio = calculate_need_for_ps(en_bo, prio);1782 prio = calculate_need_for_ps(en_bo, prio);
1732 if (prio > maxprio) {1783 if (prio > maxprio) {
1784 // we always enhance if it is the first building of this type
1785 if (en_bo.total_count() == 0) prio += 500;
1733 maxprio = prio;1786 maxprio = prio;
1734 enbld = (*x.current);1787 enbld = (*x.current);
1735 }1788 }
1736 }1789 };
1737 }1790 }
1738 }1791 }
17391792
1740 // Enhance if enhanced building is useful1793 // Enhance if enhanced building is useful
1741 // additional: we dont want to lose the old building1794 // additional: we dont want to lose the old building
1742 if (maxprio > 0 && site.bo->total_count() > 1) {1795 if (maxprio > 0 && (maxprio > 500 || site.bo->total_count() > 1)) {
1743 game().send_player_enhance_building(*site.site, enbld);1796 game().send_player_enhance_building(*site.site, enbld);
1744 changed = true;1797 changed = true;
1745 }1798 }
@@ -1778,7 +1831,7 @@
1778 // destruct the building and it's flag (via flag destruction)1831 // destruct the building and it's flag (via flag destruction)
1779 // the destruction of the flag avoids that defaultAI will have too many1832 // the destruction of the flag avoids that defaultAI will have too many
1780 // unused roads - if needed the road will be rebuild directly.1833 // unused roads - if needed the road will be rebuild directly.
1781 game().send_player_bulldoze(site.site->base_flag());1834 game().send_player_dismantle(*(site.site));
1782 return true;1835 return true;
1783 }1836 }
17841837
@@ -1880,7 +1933,7 @@
1880 (static_cast<int32_t>(ms->maxSoldierCapacity() * 4)1933 (static_cast<int32_t>(ms->maxSoldierCapacity() * 4)
1881 <1934 <
1882 bf.military_influence)1935 bf.military_influence)
1883 game().send_player_bulldoze(ms->base_flag());1936 game().send_player_dismantle(*ms);
18841937
1885 // Else consider enhancing the building (if possible)1938 // Else consider enhancing the building (if possible)
1886 else {1939 else {
@@ -1995,7 +2048,7 @@
1995 WareObserver & wo = wares.at(bo.outputs.at(k));2048 WareObserver & wo = wares.at(bo.outputs.at(k));
1996 if (wo.consumers > 0) {2049 if (wo.consumers > 0) {
1997 output_prio += wo.preciousness;2050 output_prio += wo.preciousness;
1998 output_prio += wo.consumers * 2;2051 output_prio += wo.consumers * 3;
1999 output_prio -= wo.producers * 2;2052 output_prio -= wo.producers * 2;
2000 if (bo.total_count() == 0)2053 if (bo.total_count() == 0)
2001 output_prio += 10; // add a big bonus2054 output_prio += 10; // add a big bonus
@@ -2006,12 +2059,18 @@
2006 (ceil(output_prio / sqrt(static_cast<double>(bo.outputs.size()))));2059 (ceil(output_prio / sqrt(static_cast<double>(bo.outputs.size()))));
2007 prio += 2 * output_prio;2060 prio += 2 * output_prio;
20082061
2062 if (!bo.inputs.empty() && !bo.outputs.empty() && bo.current_stats >= 80) {
2063 // extra bonus for high productivity
2064 // this should compensate various output count of a production step
2065 prio += 10;
2066 }
2067
2009 // If building consumes some wares, multiply with current statistics of all2068 // If building consumes some wares, multiply with current statistics of all
2010 // other buildings of this type to avoid constructing buildings where already2069 // other buildings of this type to avoid constructing buildings where already
2011 // some are running on low resources.2070 // some are running on low resources.
2012 // Else at least add a part of the stats t the calculation.2071 // Else at least add a part of the stats t the calculation.
2013 if (!bo.inputs.empty()) {2072 if (!bo.inputs.empty()) {
2014 prio *= bo.current_stats;2073 prio = (prio + 50) * bo.current_stats;
2015 prio /= 100;2074 prio /= 100;
2016 } else2075 } else
2017 prio = ((prio * bo.current_stats) / 100) + (prio / 2);2076 prio = ((prio * bo.current_stats) / 100) + (prio / 2);
@@ -2142,8 +2201,14 @@
2142 militarysites.back().site = &ref_cast<MilitarySite, Building>(b);2201 militarysites.back().site = &ref_cast<MilitarySite, Building>(b);
2143 militarysites.back().bo = &bo;2202 militarysites.back().bo = &bo;
2144 militarysites.back().checks = bo.desc->get_size();2203 militarysites.back().checks = bo.desc->get_size();
2145 } else if (bo.type == BuildingObserver::WAREHOUSE)2204 } else if (bo.type == BuildingObserver::WAREHOUSE) {
2146 ++numof_warehouses;2205 ++numof_warehouses;
2206 Ware_Index const nr_wares = tribe->get_nrwares();
2207 for (Ware_Index i = Ware_Index::First(); i < nr_wares; ++i) {
2208 // Warehouses are consumers of weapons
2209 wares.at(i).consumers += 2 * wares.at(i).fight_prio;
2210 }
2211 }
2147 }2212 }
2148}2213}
21492214
@@ -2207,6 +2272,11 @@
2207 } else if (bo.type == BuildingObserver::WAREHOUSE) {2272 } else if (bo.type == BuildingObserver::WAREHOUSE) {
2208 assert(numof_warehouses > 0);2273 assert(numof_warehouses > 0);
2209 --numof_warehouses;2274 --numof_warehouses;
2275 Ware_Index const nr_wares = tribe->get_nrwares();
2276 for (Ware_Index i = Ware_Index::First(); i < nr_wares; ++i) {
2277 // Warehouses are consumers of weapons
2278 wares.at(i).consumers -= 2 * wares.at(i).fight_prio;
2279 }
2210 }2280 }
2211 }2281 }
2212 m_buildable_changed = true;2282 m_buildable_changed = true;
@@ -2220,23 +2290,23 @@
2220// TODO: It needs profiling and optimization.2290// TODO: It needs profiling and optimization.
2221bool DefaultAI::check_supply(BuildingObserver const & bo)2291bool DefaultAI::check_supply(BuildingObserver const & bo)
2222{2292{
2223 size_t supplied = 0;
2224 container_iterate_const(std::vector<int16_t>, bo.inputs, i)2293 container_iterate_const(std::vector<int16_t>, bo.inputs, i)
2225 container_iterate_const(std::vector<BuildingObserver>, buildings, j)2294 container_iterate_const(std::vector<BuildingObserver>, buildings, j)
2226 if2295 if
2227 (j.current->cnt_built &&2296 (j.current->cnt_built &&
2228 std::find2297 std::find
2229 (j.current->outputs.begin(), j.current->outputs.end(),2298 (j.current->outputs.begin(), j.current->outputs.end(),
2230 *i.current)2299 *i.current)
2231 !=2300 !=
2232 j.current->outputs.end()2301 j.current->outputs.end()
2233 &&2302 &&
2234 check_supply(*j.current))2303 check_supply(*j.current))
2235 {2304 {
2236 ++supplied;
2237 break;2305 break;
2306 } else {
2307 return false;
2238 }2308 }
2239 return supplied == bo.inputs.size();2309 return true;
2240}2310}
22412311
22422312
@@ -2277,12 +2347,12 @@
2277 continue;2347 continue;
2278 if (bld->canAttack()) {2348 if (bld->canAttack()) {
2279 int32_t ta = player->findAttackSoldiers(bld->base_flag());2349 int32_t ta = player->findAttackSoldiers(bld->base_flag());
2280 if (type == NORMAL)2350 if (type != AGGRESSIVE)
2281 ta = ta * 2 / 3;2351 ta = (ta * 2) / 3;
2282 if (ta < 1)2352 if (ta < 1)
2283 continue;2353 continue;
22842354
2285 int32_t const tc = ta - bld->presentSoldiers().size();2355 int32_t const tc = ta * 2 - bld->presentSoldiers().size() * 3;
2286 if (tc > chance) {2356 if (tc > chance) {
2287 target = bld;2357 target = bld;
2288 chance = tc;2358 chance = tc;
@@ -2313,7 +2383,7 @@
23132383
2314 // Return if chance to win is too low2384 // Return if chance to win is too low
2315 if (chance < 3) {2385 if (chance < 3) {
2316 next_attack_consideration_due = gametime % 7 * 1000 + gametime;2386 next_attack_consideration_due = (2 + gametime % 7) * 1000 + gametime;
2317 return false;2387 return false;
2318 }2388 }
23192389
@@ -2326,6 +2396,6 @@
2326 (target->base_flag(), pn, attackers, retreat);2396 (target->base_flag(), pn, attackers, retreat);
23272397
2328 // Do not attack again too soon - returning soldiers must get healed first.2398 // Do not attack again too soon - returning soldiers must get healed first.
2329 next_attack_consideration_due = (gametime % 51 + 10) * 1000 + gametime;2399 next_attack_consideration_due = (gametime % 51 + 20) * 1000 + gametime;
2330 return true;2400 return true;
2331}2401}
23322402
=== modified file 'src/ui_basic/table.cc'
--- src/ui_basic/table.cc 2011-11-06 14:23:36 +0000
+++ src/ui_basic/table.cc 2011-11-13 00:10:30 +0000
@@ -429,6 +429,7 @@
429 return result;429 return result;
430}430}
431431
432
432/**433/**
433 * Scroll to the given position, in pixels.434 * Scroll to the given position, in pixels.
434*/435*/

Subscribers

People subscribed via source and target branches

to status/vote changes: