/** * Copyright (C) 2002-2012 The FreeCol Team * * This file is part of FreeCol. * * FreeCol is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * FreeCol is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with FreeCol. If not, see <http://www.gnu.org/licenses/>. */ package net.sf.freecol.server.model; import java.util.ArrayList; import java.util.List; import net.sf.freecol.common.model.BuildingType; import net.sf.freecol.common.model.Colony; import net.sf.freecol.common.model.ColonyTile; import net.sf.freecol.common.model.EquipmentType; import net.sf.freecol.common.model.Game; import net.sf.freecol.common.model.GoodsType; import net.sf.freecol.common.model.Map; import net.sf.freecol.common.model.Map.Direction; import net.sf.freecol.common.model.Player; import net.sf.freecol.common.model.Tile; import net.sf.freecol.common.model.TileImprovement; import net.sf.freecol.common.model.TileImprovementType; import net.sf.freecol.common.model.TileType; import net.sf.freecol.common.model.Unit; import net.sf.freecol.common.model.UnitType; import net.sf.freecol.common.model.UnitTypeChange.ChangeType; import net.sf.freecol.common.model.WorkLocation; import net.sf.freecol.server.ServerTestHelper; import net.sf.freecol.server.control.InGameController; import net.sf.freecol.util.test.FreeColTestCase; import net.sf.freecol.util.test.MockPseudoRandom; public class ServerUnitTest extends FreeColTestCase { private static final BuildingType townHallType = spec().getBuildingType("model.building.townHall"); private static final EquipmentType horsesType = spec().getEquipmentType("model.equipment.horses"); private static final EquipmentType toolsType = spec().getEquipmentType("model.equipment.tools"); private static final GoodsType foodType = spec().getPrimaryFoodType(); private static final GoodsType grainType = spec().getGoodsType("model.goods.grain"); private static final TileImprovementType road = spec().getTileImprovementType("model.improvement.road"); private static final TileImprovementType plow = spec().getTileImprovementType("model.improvement.plow"); private static final TileImprovementType clear = spec().getTileImprovementType("model.improvement.clearForest"); private static final TileType plains = spec().getTileType("model.tile.plains"); private static final TileType savannah = spec().getTileType("model.tile.savannah"); private static final TileType savannahForest = spec().getTileType("model.tile.tropicalForest"); private static final UnitType colonistType = spec().getUnitType("model.unit.freeColonist"); private static final UnitType expertFarmerType = spec().getUnitType("model.unit.expertFarmer"); private static final UnitType pioneerType = spec().getUnitType("model.unit.hardyPioneer"); private static final UnitType soldierType = spec().getUnitType("model.unit.veteranSoldier"); public void testToggleHorses() { Map map = getTestMap(plains); Game game = ServerTestHelper.startServerGame(map); Player dutch = game.getPlayer("model.nation.dutch"); Tile tile1 = map.getTile(5, 8); tile1.setExploredBy(dutch, true); ServerUnit scout = new ServerUnit(game, tile1, dutch, colonistType); // make sure unit has all moves left ServerTestHelper.newTurn(); assertEquals(scout.getInitialMovesLeft(), scout.getMovesLeft()); int colonistMoves = scout.getMovesLeft(); scout.changeEquipment(horsesType, 1); ServerTestHelper.newTurn(); assertTrue("Scout should have more moves than a colonist", scout.getMovesLeft() > colonistMoves); scout.changeEquipment(horsesType, -1); ServerTestHelper.newTurn(); assertEquals(scout.getMovesLeft(), colonistMoves); } /** * Test Plowing with a hardy pioneer */ public void testDoAssignedWorkHardyPioneerPlowPlain() { Map map = getTestMap(plains); Game game = ServerTestHelper.startServerGame(map); InGameController igc = ServerTestHelper.getInGameController(); ServerPlayer dutch = (ServerPlayer)game.getPlayer("model.nation.dutch"); Tile plain = map.getTile(5, 8); plain.setExploredBy(dutch, true); plain.setOwner(dutch); ServerUnit hardyPioneer = new ServerUnit(game, plain, dutch, pioneerType); // Before assertFalse(plain.hasImprovement(plow)); assertEquals(3, hardyPioneer.getMovesLeft()); assertEquals(Unit.UnitState.ACTIVE, hardyPioneer.getState()); assertEquals(-1, hardyPioneer.getWorkLeft()); assertEquals(100, hardyPioneer.getEquipmentCount(toolsType) * 20); //TileImprovement plowImprovement // = new TileImprovement(game, plain, plow); //plain.add(plowImprovement); igc.changeWorkImprovementType(dutch, hardyPioneer, plow); assertFalse(plain.hasImprovement(plow)); assertEquals(0, hardyPioneer.getMovesLeft()); assertEquals(Unit.UnitState.IMPROVING, hardyPioneer.getState()); assertEquals(5, hardyPioneer.getWorkLeft()); assertEquals(100, hardyPioneer.getEquipmentCount(toolsType) * 20); // Advance to finish while (hardyPioneer.getWorkLeft() > 0) { ServerTestHelper.newTurn(); } // Pioneer finished work assertTrue(plain.hasImprovement(plow)); assertEquals(0, hardyPioneer.getMovesLeft()); assertEquals(Unit.UnitState.ACTIVE, hardyPioneer.getState()); assertEquals(-1, hardyPioneer.getWorkLeft()); assertEquals(80, hardyPioneer.getEquipmentCount(toolsType) * 20); } public void testColonyProfitFromEnhancement() { Map map = getTestMap(plains); Game game = ServerTestHelper.startServerGame(map); InGameController igc = ServerTestHelper.getInGameController(); ServerPlayer dutch = (ServerPlayer)game.getPlayer("model.nation.dutch"); map.getTile(5, 8).setExploredBy(dutch, true); map.getTile(6, 8).setExploredBy(dutch, true); Tile plain58 = map.getTile(5, 8); //assertEquals(2, dutch.getDifficulty().getIndex()); //assertEquals("model.difficulty.medium", dutch.getDifficulty().getId()); assertEquals(6, spec().getInteger("model.option.badGovernmentLimit")); assertEquals(10, spec().getInteger("model.option.veryBadGovernmentLimit")); // Found colony on 6,8 ServerUnit soldier = new ServerUnit(game, map.getTile(6, 8), dutch, soldierType); ServerColony colony = new ServerColony(game, dutch, "New Amsterdam", soldier.getTile()); dutch.addSettlement(colony); soldier.setWorkType(foodType); nonServerBuildColony(soldier, colony); soldier.setLocation(colony.getColonyTile(plain58)); ServerUnit hardyPioneer = new ServerUnit(game, plain58, dutch, pioneerType); // Before assertEquals(0, colony.getGoodsCount(foodType)); assertEquals(2, colony.getFoodConsumption()); assertEquals(5 + 5, colony.getFoodProduction()); assertFalse(plain58.hasImprovement(plow)); assertEquals(0, colony.getProductionBonus()); assertEquals("" + soldier.getLocation(), colony.getColonyTile(map.getTile(5, 8)), soldier.getLocation()); // One turn to check production ServerTestHelper.newTurn(); assertFalse(plain58.hasImprovement(plow)); assertEquals(8, colony.getGoodsCount(foodType)); assertEquals(2, colony.getFoodConsumption()); assertEquals(0, colony.getProductionBonus()); assertEquals(5 + 5, colony.getFoodProduction()); // Start Plowing //TileImprovement plowImprovement // = new TileImprovement(game, plain58, plow); //plain58.add(plowImprovement); igc.changeWorkImprovementType(dutch, hardyPioneer, plow); int n = 0; while (hardyPioneer.getWorkLeft() > 0) { ServerTestHelper.newTurn(); n++; } colony.invalidateCache(); assertTrue(plain58.hasImprovement(plow)); // Production for next turn is updated assertEquals(5 + 6, colony.getFoodProduction()); assertEquals(2, colony.getFoodConsumption()); // But in only 10 - 2 == 8 are added from last turn assertEquals(8 + n * 8, colony.getGoodsCount(foodType)); // In game, this should happen via a Tile update colony.invalidateCache(); // Advance last turn ServerTestHelper.newTurn(); assertTrue(plain58.hasImprovement(plow)); assertEquals(5 + 6, colony.getFoodProduction()); assertEquals(2, colony.getFoodConsumption()); assertEquals(8 + n * 8 + 9, colony.getGoodsCount(foodType)); } /** * Test Building a road with a hardy pioneer. * * The road is available directly, but the pioneer can only move on the next * turn. * */ public void testDoAssignedWorkHardyPioneerBuildRoad() { Map map = getTestMap(savannahForest); Game game = ServerTestHelper.startServerGame(map); InGameController igc = ServerTestHelper.getInGameController(); ServerPlayer dutch = (ServerPlayer)game.getPlayer("model.nation.dutch"); Tile tile = map.getTile(5, 8); map.getTile(5, 8).setExploredBy(dutch, true); ServerUnit hardyPioneer1 = new ServerUnit(game, tile, dutch, pioneerType); ServerUnit hardyPioneer2 = new ServerUnit(game, tile, dutch, pioneerType); ServerUnit hardyPioneer3 = new ServerUnit(game, tile, dutch, pioneerType); // Before assertEquals(false, tile.hasRoad()); assertEquals(3, hardyPioneer1.getMovesLeft()); assertEquals(-1, hardyPioneer1.getWorkLeft()); assertEquals(100, hardyPioneer1.getEquipmentCount(toolsType) * 20); assertEquals(Unit.UnitState.ACTIVE, hardyPioneer1.getState()); assertEquals(3, hardyPioneer2.getMovesLeft()); assertEquals(-1, hardyPioneer2.getWorkLeft()); assertEquals(100, hardyPioneer2.getEquipmentCount(toolsType) * 20); assertEquals(Unit.UnitState.ACTIVE, hardyPioneer2.getState()); // Now do it tile.setOwner(dutch); igc.changeWorkImprovementType(dutch, hardyPioneer1, road); igc.changeWorkImprovementType(dutch, hardyPioneer2, road); igc.changeWorkImprovementType(dutch, hardyPioneer3, clear); assertEquals(6, hardyPioneer1.getWorkLeft()); assertEquals(6, hardyPioneer2.getWorkLeft()); assertEquals(8, hardyPioneer3.getWorkLeft()); TileImprovement roadImprovement = tile.getRoad(); while (roadImprovement.getTurnsToComplete() > 0) { ServerTestHelper.newTurn(); } // After: both pioneers building road have used up their tools assertTrue(tile.hasRoad()); assertTrue(roadImprovement.isComplete()); assertEquals(savannahForest, tile.getType()); //assertEquals(0, hardyPioneer1.getMovesLeft()); assertEquals(-1, hardyPioneer1.getWorkLeft()); assertEquals(Unit.UnitState.ACTIVE, hardyPioneer1.getState()); //assertEquals(0, hardyPioneer2.getMovesLeft()); assertEquals(-1, hardyPioneer2.getWorkLeft()); assertEquals(Unit.UnitState.ACTIVE, hardyPioneer2.getState()); assertEquals(180, 20 * (hardyPioneer1.getEquipmentCount(toolsType) + hardyPioneer2.getEquipmentCount(toolsType))); // Pioneer clearing forest is not affected assertEquals(3, hardyPioneer3.getMovesLeft()); assertEquals(4, hardyPioneer3.getWorkLeft()); assertEquals(Unit.UnitState.IMPROVING, hardyPioneer3.getState()); assertEquals(100, hardyPioneer3.getEquipmentCount(toolsType) * 20); // Finish while (hardyPioneer3.getWorkLeft() > 0) { ServerTestHelper.newTurn(); } assertEquals(savannah, tile.getType()); assertEquals(0, hardyPioneer3.getMovesLeft()); assertEquals(-1, hardyPioneer3.getWorkLeft()); assertEquals(Unit.UnitState.ACTIVE, hardyPioneer3.getState()); assertEquals(80, hardyPioneer3.getEquipmentCount(toolsType) * 20); } public void testUnitGetsExperienceThroughWork() { Map map = getTestMap(); Game game = ServerTestHelper.startServerGame(map); Colony colony = getStandardColony(); Unit colonist = colony.getUnitList().get(0); assertEquals("Colonist should not have any experience", 0, colonist.getExperience()); // colonist either in building or colony work tile WorkLocation loc = colonist.getWorkLocation(); if (loc == null) loc = colonist.getWorkTile(); // produces goods ServerTestHelper.newTurn(); assertTrue("Colonist should have gained some experience", colonist.getExperience() > 0); } public void testUnitPromotionWorkingInWorkTile() { Map map = getTestMap(plains); Game game = ServerTestHelper.startServerGame(map); Colony colony = getStandardColony(); assertTrue("Colony should only have 1 colonist for test setup", colony.getUnitCount() == 1); Unit colonist = colony.getUnitList().get(0); String errMsg = "Error setting test, colonist should not be an expert"; assertTrue(errMsg, colonist.getType() == colonistType); // set colonist as farmer Tile tile = colony.getTile().getNeighbourOrNull(Direction.N); assertTrue(colony.getOwner().canOwnTile(tile)); ColonyTile colonyTile = colony.getColonyTile(tile); if (!colonyTile.isEmpty()) { colonyTile.getUnitList().get(0).setLocation(colony.getBuilding(townHallType)); } assertTrue(colonyTile.canBeWorked()); colonist.setLocation(colonyTile); colonist.setWorkType(grainType); assertEquals("Wrong work allocation", grainType, colonist.getWorkType()); assertEquals(colonyTile.getUnitList().get(0), colonist); // Will colonist gain experience? assertTrue(colonyTile.getTotalProductionOf(colonist.getWorkType()) > 0); // Can colonist be upgraded UnitType learn = spec().getExpertForProducing(colonist.getWorkType()); assertNotNull(learn); assertTrue(learn != colonist.getType()); assertTrue(colonist.getType().canBeUpgraded(learn, ChangeType.EXPERIENCE)); // set some experience int expectXP = 10; colonist.modifyExperience(expectXP); assertEquals("Wrong colonist experience", expectXP, colonist.getExperience()); // We need a deterministic random List<Integer> setValues = new ArrayList<Integer>(); setValues.add(1); MockPseudoRandom mockRandom = new MockPseudoRandom(setValues, true); ServerTestHelper.setRandom(mockRandom); // Verify initial state boolean isExpert = colonist.getType() == expertFarmerType; assertFalse("Unit should not be an expert", isExpert); // Make upgrade ServerTestHelper.newTurn(); assertTrue(colonist.getExperience() > expectXP); // verify upgrade isExpert = colonist.getType() == expertFarmerType; assertTrue("Unit should now be an expert", isExpert); } public void testExposeResource() { Map map = getTestMap(savannahForest); Game game = ServerTestHelper.startServerGame(map); InGameController igc = ServerTestHelper.getInGameController(); ServerPlayer dutch = (ServerPlayer)game.getPlayer("model.nation.dutch"); Tile tile = map.getTile(5, 8); tile.setOwner(dutch); tile.setExploredBy(dutch, true); // Almost clear the tile ServerUnit hardyPioneer = new ServerUnit(game, tile, dutch, pioneerType, toolsType); //TileImprovement clearImprovement // = new TileImprovement(game, tile, clear); //tile.add(clearImprovement); igc.changeWorkImprovementType(dutch, hardyPioneer, clear); // Verify initial state assertEquals(8, hardyPioneer.getWorkLeft()); assertEquals(savannahForest, tile.getType()); assertFalse(tile.hasResource()); // Almost finish clearing ServerTestHelper.newTurn(); ServerTestHelper.newTurn(); ServerTestHelper.newTurn(); // We need a deterministic random List<Integer> setValues = new ArrayList<Integer>(); setValues.add(1); MockPseudoRandom mockRandom = new MockPseudoRandom(setValues, true); ServerTestHelper.setRandom(mockRandom); // Finish clearing ServerTestHelper.newTurn(); // Verify clearing succeeded and has revealed a resource assertEquals(savannah, tile.getType()); assertTrue(tile.hasResource()); } }