On 22.09.2012 10:01, Michael Vehrs wrote:
On 20.09.2012 12:36, Michael T. Pope wrote:
On Thu, 20 Sep 2012 08:28:17 AM Michael Vehrs wrote:

This looks like a rather hairy problem, since we are basically doing
everything right already. Except that in the case of starvation, we need
to look into the future.

The higher level fix (starve.diff) is still an option if you think the
production code is doing the Right Thing, however ISTM that the problem is
that the decision to build is too simplistic.  Rather than just `>= 200 food',
it should be `>= 200 + one-unit-consumption if net food production is -ve'.
Not elegant I admit.


Also, I don't understand why
ServerTestHelper.newTurn() doesn't update my test game properly.

No idea.  Last time I looked (the teaching tests, ugh) it worked for me.

Cheers,
Mike Pope

Finally, I have found the root cause of the starvation bug: the
ProductionTree code does not allow for negative values. At the moment, I
am not sure whether this problem can be fixed without any serious fallout.


Regards

Michael

The appended patch seems to fix the starvation problem and passes all unit tests, but I am by no means sure it is correct. Please ponder.


Regards

Michael

Index: test/src/net/sf/freecol/server/model/ServerColonyTest.java
===================================================================
--- test/src/net/sf/freecol/server/model/ServerColonyTest.java	(revision 10153)
+++ test/src/net/sf/freecol/server/model/ServerColonyTest.java	(working copy)
@@ -22,6 +22,7 @@
 import java.util.List;
 
 import net.sf.freecol.common.model.AbstractGoods;
+import net.sf.freecol.common.model.Building;
 import net.sf.freecol.common.model.BuildingType;
 import net.sf.freecol.common.model.Colony;
 import net.sf.freecol.common.model.Game;
@@ -189,6 +190,52 @@
         assertTrue(errMsg,foodStored == 0);
     }
 
+
+    public void testAvoidStarvation() {
+        Game game = ServerTestHelper.startServerGame(getTestMap());
+        Map map = getTestMap(spec().getTileType("model.tile.marsh"));
+        game.setMap(map);
+
+        ServerPlayer dutch = (ServerPlayer) game.getPlayer("model.nation.dutch");
+
+        ServerColony colony = new ServerColony(game, dutch, "New Amsterdam", map.getTile(5, 8));
+        dutch.addSettlement(colony);
+
+        UnitType pioneerType = spec().getUnitType("model.unit.hardyPioneer");
+        GoodsType bellsType = spec().getGoodsType("model.goods.bells");
+        Building townHall = colony.getBuildingForProducing(bellsType);
+
+        Unit unit1 = new ServerUnit(game, townHall, dutch, pioneerType);
+        Unit unit2 = new ServerUnit(game, townHall, dutch, pioneerType);
+        Unit unit3 = new ServerUnit(game, townHall, dutch, pioneerType);
+
+        int consumption = colony.getFoodConsumption();
+        int production = colony.getTile().getType().getPrimaryGoods().getAmount();
+        assertEquals(6, consumption);
+        assertEquals(3, production);
+        assertEquals(-3, colony.getNetProductionOf(foodType));
+        assertEquals(0, colony.getGoodsCount(foodType));
+        assertEquals(0, colony.getTile().getUnitCount());
+
+        colony.addGoods(foodType, 202);
+        ServerTestHelper.newTurn();
+        assertEquals(199, colony.getGoodsCount(foodType));
+        assertEquals(0, colony.getTile().getUnitCount());
+        assertEquals(3, colony.getUnitCount());
+        assertEquals(unit1.getId(), colony.getUnitList().get(0).getId());
+        assertEquals(unit2.getId(), colony.getUnitList().get(1).getId());
+        assertEquals(unit3.getId(), colony.getUnitList().get(2).getId());
+
+        colony.addGoods(foodType, 15);
+        ServerTestHelper.newTurn();
+        assertEquals(11, colony.getGoodsCount(foodType));
+        assertEquals(1, colony.getTile().getUnitCount());
+        assertEquals(unit1.getId(), colony.getUnitList().get(0).getId());
+        assertEquals(unit2.getId(), colony.getUnitList().get(1).getId());
+        assertEquals(unit3.getId(), colony.getUnitList().get(2).getId());
+
+    }
+
     /**
      * Tests completion of buildable
      */
Index: src/net/sf/freecol/common/model/ProductionMap.java
===================================================================
--- src/net/sf/freecol/common/model/ProductionMap.java	(revision 10153)
+++ src/net/sf/freecol/common/model/ProductionMap.java	(working copy)
@@ -111,24 +111,14 @@
         public int remove(AbstractGoods goods) {
             int consumed = goods.getAmount();
             if (goods.getType() == root.getType()) {
-                if (consumed > root.getAmount()) {
-                    consumed = root.getAmount();
-                    root.setAmount(0);
-                } else {
-                    root.setAmount(root.getAmount() - consumed);
-                }
+                root.setAmount(root.getAmount() - consumed);
                 for (AbstractGoods leaf : leafs) {
                     leaf.setAmount(Math.min(leaf.getAmount(), root.getAmount()));
                 }
             } else {
                 for (AbstractGoods leaf : leafs) {
                     if (leaf.getType() == goods.getType()) {
-                        if (consumed > leaf.getAmount()) {
-                            consumed = leaf.getAmount();
-                            leaf.setAmount(0);
-                        } else {
-                            leaf.setAmount(leaf.getAmount() - consumed);
-                        }
+                        leaf.setAmount(leaf.getAmount() - consumed);
                         root.setAmount(root.getAmount() - consumed);
                         break;
                     }
------------------------------------------------------------------------------
How fast is your code?
3 out of 4 devs don\\\'t know how their code performs in production.
Find out how slow your code is with AppDynamics Lite.
http://ad.doubleclick.net/clk;262219672;13503038;z?
http://info.appdynamics.com/FreeJavaPerformanceDownload.html
_______________________________________________
Freecol-developers mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freecol-developers

Reply via email to