package games.strategy.triplea.delegate;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Collection;
import java.util.Map.Entry;
import org.junit.Before;
import org.junit.Test;
import games.strategy.engine.data.Change;
import games.strategy.engine.data.GameData;
import games.strategy.engine.data.ITestDelegateBridge;
import games.strategy.engine.data.PlayerID;
import games.strategy.engine.data.Territory;
import games.strategy.engine.data.UnitType;
import games.strategy.engine.data.changefactory.ChangeFactory;
import games.strategy.engine.random.ScriptedRandomSource;
import games.strategy.test.TestUtil;
import games.strategy.triplea.delegate.IBattle.BattleType;
import games.strategy.triplea.player.ITripleAPlayer;
import games.strategy.triplea.xml.TestMapGameData;
public class AirThatCantLandUtilTest {
private GameData gameData;
private PlayerID americansPlayer;
private UnitType fighterType;
@Before
public void setUp() throws Exception {
gameData = TestMapGameData.REVISED.getGameData();
americansPlayer = GameDataTestUtil.americans(gameData);
fighterType = GameDataTestUtil.fighter(gameData);
}
private ITestDelegateBridge getDelegateBridge(final PlayerID player) {
return GameDataTestUtil.getDelegateBridge(player, gameData);
}
public static String fight(final BattleDelegate battle, final Territory territory, final boolean bombing) {
for (final Entry<BattleType, Collection<Territory>> entry : battle.getBattles().getBattles().entrySet()) {
if (entry.getKey().isBombingRun() == bombing) {
if (entry.getValue().contains(territory)) {
return battle.fightBattle(territory, bombing, entry.getKey());
}
}
}
throw new IllegalStateException(
"Could not find " + (bombing ? "bombing" : "normal") + " battle in: " + territory.getName());
}
@Test
public void testSimple() {
final PlayerID player = americansPlayer;
// everything can land
final ITestDelegateBridge bridge = getDelegateBridge(player);
final AirThatCantLandUtil util = new AirThatCantLandUtil(bridge);
assertTrue(util.getTerritoriesWhereAirCantLand(player).isEmpty());
}
@Test
public void testCantLandEnemyTerritory() {
final PlayerID player = americansPlayer;
final ITestDelegateBridge bridge = getDelegateBridge(player);
final Territory balkans = gameData.getMap().getTerritory("Balkans");
final Change addAir = ChangeFactory.addUnits(balkans, fighterType.create(2, player));
gameData.performChange(addAir);
final AirThatCantLandUtil airThatCantLandUtil = new AirThatCantLandUtil(bridge);
final Collection<Territory> cantLand = airThatCantLandUtil.getTerritoriesWhereAirCantLand(player);
assertEquals(1, cantLand.size());
assertEquals(balkans, cantLand.iterator().next());
airThatCantLandUtil.removeAirThatCantLand(player, false);
// jsut the original german fighter
assertEquals(1, balkans.getUnits().getMatches(Matches.UnitIsAir).size());
}
@Test
public void testCantLandWater() {
final PlayerID player = americansPlayer;
final ITestDelegateBridge bridge = getDelegateBridge(player);
final Territory sz_55 = gameData.getMap().getTerritory("55 Sea Zone");
final Change addAir = ChangeFactory.addUnits(sz_55, fighterType.create(2, player));
gameData.performChange(addAir);
final AirThatCantLandUtil airThatCantLandUtil = new AirThatCantLandUtil(bridge);
final Collection<Territory> cantLand = airThatCantLandUtil.getTerritoriesWhereAirCantLand(player);
assertEquals(1, cantLand.size());
assertEquals(sz_55, cantLand.iterator().next());
airThatCantLandUtil.removeAirThatCantLand(player, false);
assertEquals(0, sz_55.getUnits().getMatches(Matches.UnitIsAir).size());
}
@Test
public void testSpareNextToFactory() {
final PlayerID player = americansPlayer;
final ITestDelegateBridge bridge = getDelegateBridge(player);
final Territory sz_55 = gameData.getMap().getTerritory("55 Sea Zone");
final Change addAir = ChangeFactory.addUnits(sz_55, fighterType.create(2, player));
gameData.performChange(addAir);
final AirThatCantLandUtil airThatCantLandUtil = new AirThatCantLandUtil(bridge);
airThatCantLandUtil.removeAirThatCantLand(player, true);
assertEquals(2, sz_55.getUnits().getMatches(Matches.UnitIsAir).size());
}
@Test
public void testCantLandCarrier() {
// 1 carrier in the region, but three fighters, make sure we cant land
final PlayerID player = americansPlayer;
final ITestDelegateBridge bridge = getDelegateBridge(player);
final Territory sz_52 = gameData.getMap().getTerritory("52 Sea Zone");
final Change addAir = ChangeFactory.addUnits(sz_52, fighterType.create(2, player));
gameData.performChange(addAir);
final AirThatCantLandUtil airThatCantLandUtil = new AirThatCantLandUtil(bridge);
final Collection<Territory> cantLand = airThatCantLandUtil.getTerritoriesWhereAirCantLand(player);
assertEquals(1, cantLand.size());
assertEquals(sz_52, cantLand.iterator().next());
airThatCantLandUtil.removeAirThatCantLand(player, false);
// just the original american fighter, plus one that can land on the carrier
assertEquals(2, sz_52.getUnits().getMatches(Matches.UnitIsAir).size());
}
@Test
public void testCanLandNeighborCarrier() {
final PlayerID japanese = GameDataTestUtil.japanese(gameData);
final PlayerID americans = GameDataTestUtil.americans(gameData);
final ITestDelegateBridge bridge = getDelegateBridge(japanese);
// we need to initialize the original owner
final InitializationDelegate initDel =
(InitializationDelegate) gameData.getDelegateList().getDelegate("initDelegate");
initDel.setDelegateBridgeAndPlayer(bridge);
initDel.start();
initDel.end();
// Get necessary sea zones and unit types for this test
final Territory sz_44 = gameData.getMap().getTerritory("44 Sea Zone");
final Territory sz_45 = gameData.getMap().getTerritory("45 Sea Zone");
final Territory sz_52 = gameData.getMap().getTerritory("52 Sea Zone");
final UnitType subType = GameDataTestUtil.submarine(gameData);
final UnitType carrierType = GameDataTestUtil.carrier(gameData);
final UnitType fighterType = GameDataTestUtil.fighter(gameData);
// Add units for the test
gameData.performChange(ChangeFactory.addUnits(sz_45, subType.create(1, japanese)));
gameData.performChange(ChangeFactory.addUnits(sz_44, carrierType.create(1, americans)));
gameData.performChange(ChangeFactory.addUnits(sz_44, fighterType.create(1, americans)));
// Get total number of defending units before the battle
final int preCountSz_52 = sz_52.getUnits().size();
final int preCountAirSz_44 = sz_44.getUnits().getMatches(Matches.UnitIsAir).size();
// now move to attack
final MoveDelegate moveDelegate = (MoveDelegate) gameData.getDelegateList().getDelegate("move");
bridge.setStepName("CombatMove");
moveDelegate.setDelegateBridgeAndPlayer(bridge);
moveDelegate.start();
moveDelegate.move(sz_45.getUnits().getUnits(), gameData.getMap().getRoute(sz_45, sz_44));
moveDelegate.end();
// fight the battle
final BattleDelegate battle = (BattleDelegate) gameData.getDelegateList().getDelegate("battle");
battle.setDelegateBridgeAndPlayer(bridge);
bridge.setRandomSource(new ScriptedRandomSource(new int[] {0, 0, 0}));
bridge.setRemote(getDummyPlayer());
battle.start();
battle.end();
// Get the total number of units that should be left after the planes retreat
final int expectedCountSz_52 = sz_52.getUnits().size();
final int postCountInt = preCountSz_52 + preCountAirSz_44;
// Compare the expected count with the actual number of units in landing zone
assertEquals(expectedCountSz_52, postCountInt);
}
@Test
public void testCanLandMultiNeighborCarriers() {
final PlayerID japanese = GameDataTestUtil.japanese(gameData);
final PlayerID americans = GameDataTestUtil.americans(gameData);
final ITestDelegateBridge bridge = getDelegateBridge(japanese);
// we need to initialize the original owner
final InitializationDelegate initDel =
(InitializationDelegate) gameData.getDelegateList().getDelegate("initDelegate");
initDel.setDelegateBridgeAndPlayer(bridge);
initDel.start();
initDel.end();
// Get necessary sea zones and unit types for this test
final Territory sz_43 = gameData.getMap().getTerritory("43 Sea Zone");
final Territory sz_44 = gameData.getMap().getTerritory("44 Sea Zone");
final Territory sz_45 = gameData.getMap().getTerritory("45 Sea Zone");
final Territory sz_52 = gameData.getMap().getTerritory("52 Sea Zone");
final UnitType subType = GameDataTestUtil.submarine(gameData);
final UnitType carrierType = GameDataTestUtil.carrier(gameData);
final UnitType fighterType = GameDataTestUtil.fighter(gameData);
// Add units for the test
gameData.performChange(ChangeFactory.addUnits(sz_45, subType.create(1, japanese)));
gameData.performChange(ChangeFactory.addUnits(sz_44, carrierType.create(1, americans)));
gameData.performChange(ChangeFactory.addUnits(sz_44, fighterType.create(3, americans)));
gameData.performChange(ChangeFactory.addUnits(sz_43, carrierType.create(1, americans)));
// Get total number of defending units before the battle
final int preCountSz_52 = sz_52.getUnits().size();
final int preCountSz_43 = sz_43.getUnits().size();
// now move to attack
final MoveDelegate moveDelegate = (MoveDelegate) gameData.getDelegateList().getDelegate("move");
bridge.setStepName("CombatMove");
moveDelegate.setDelegateBridgeAndPlayer(bridge);
moveDelegate.start();
moveDelegate.move(sz_45.getUnits().getUnits(), gameData.getMap().getRoute(sz_45, sz_44));
moveDelegate.end();
// fight the battle
final BattleDelegate battle = (BattleDelegate) gameData.getDelegateList().getDelegate("battle");
battle.setDelegateBridgeAndPlayer(bridge);
bridge.setRandomSource(new ScriptedRandomSource(new int[] {0, 0, 0}));
bridge.setRemote(getDummyPlayer());
battle.start();
battle.end();
// Get the total number of units that should be left after the planes retreat
final int expectedCountSz_52 = sz_52.getUnits().size();
final int expectedCountSz_43 = sz_43.getUnits().size();
final int postCountSz_52 = preCountSz_52 + 1;
final int postCountSz_43 = preCountSz_43 + 2;
// Compare the expected count with the actual number of units in landing zone
assertEquals(expectedCountSz_52, postCountSz_52);
assertEquals(expectedCountSz_43, postCountSz_43);
}
@Test
public void testCanLandNeighborLandV2() {
final PlayerID japanese = GameDataTestUtil.japanese(gameData);
final PlayerID americans = GameDataTestUtil.americans(gameData);
final ITestDelegateBridge bridge = getDelegateBridge(japanese);
// we need to initialize the original owner
final InitializationDelegate initDel =
(InitializationDelegate) gameData.getDelegateList().getDelegate("initDelegate");
initDel.setDelegateBridgeAndPlayer(bridge);
initDel.start();
initDel.end();
// Get necessary sea zones and unit types for this test
final Territory sz_9 = gameData.getMap().getTerritory("9 Sea Zone");
final Territory eastCanada = gameData.getMap().getTerritory("Eastern Canada");
final Territory sz_11 = gameData.getMap().getTerritory("11 Sea Zone");
final UnitType subType = GameDataTestUtil.submarine(gameData);
final UnitType carrierType = GameDataTestUtil.carrier(gameData);
final UnitType fighterType = GameDataTestUtil.fighter(gameData);
// Add units for the test
gameData.performChange(ChangeFactory.addUnits(sz_11, subType.create(1, japanese)));
gameData.performChange(ChangeFactory.addUnits(sz_9, carrierType.create(1, americans)));
gameData.performChange(ChangeFactory.addUnits(sz_9, fighterType.create(1, americans)));
// Get total number of defending units before the battle
final int preCountCanada = eastCanada.getUnits().size();
final int preCountAirSz_9 = sz_9.getUnits().getMatches(Matches.UnitIsAir).size();
// now move to attack
final MoveDelegate moveDelegate = (MoveDelegate) gameData.getDelegateList().getDelegate("move");
bridge.setStepName("CombatMove");
moveDelegate.setDelegateBridgeAndPlayer(bridge);
moveDelegate.start();
moveDelegate.move(sz_11.getUnits().getUnits(), gameData.getMap().getRoute(sz_11, sz_9));
moveDelegate.end();
// fight the battle
final BattleDelegate battle = (BattleDelegate) gameData.getDelegateList().getDelegate("battle");
battle.setDelegateBridgeAndPlayer(bridge);
bridge.setRandomSource(new ScriptedRandomSource(new int[] {0,}));
bridge.setRemote(getDummyPlayer());
battle.start();
battle.end();
// Get the total number of units that should be left after the planes retreat
final int expectedCountCanada = eastCanada.getUnits().size();
final int postCountInt = preCountCanada + preCountAirSz_9;
// Compare the expected count with the actual number of units in landing zone
assertEquals(expectedCountCanada, postCountInt);
}
@Test
public void testCanLandNeighborLandWithRetreatedBattleV2() {
final PlayerID japanese = GameDataTestUtil.japanese(gameData);
final PlayerID americans = GameDataTestUtil.americans(gameData);
final ITestDelegateBridge bridge = getDelegateBridge(japanese);
// Get necessary sea zones and unit types for this test
final Territory sz_9 = gameData.getMap().getTerritory("9 Sea Zone");
final Territory eastCanada = gameData.getMap().getTerritory("Eastern Canada");
final Territory sz_11 = gameData.getMap().getTerritory("11 Sea Zone");
final UnitType subType = GameDataTestUtil.submarine(gameData);
final UnitType carrierType = GameDataTestUtil.carrier(gameData);
final UnitType fighterType = GameDataTestUtil.fighter(gameData);
final UnitType transportType = GameDataTestUtil.transport(gameData);
final UnitType infantryType = GameDataTestUtil.infantry(gameData);
// Add units for the test
gameData.performChange(ChangeFactory.addUnits(sz_11, subType.create(1, japanese)));
gameData.performChange(ChangeFactory.addUnits(sz_11, transportType.create(1, japanese)));
gameData.performChange(ChangeFactory.addUnits(sz_11, infantryType.create(1, japanese)));
gameData.performChange(ChangeFactory.addUnits(sz_9, carrierType.create(1, americans)));
gameData.performChange(ChangeFactory.addUnits(sz_9, fighterType.create(2, americans)));
// we need to initialize the original owner
final InitializationDelegate initDel =
(InitializationDelegate) gameData.getDelegateList().getDelegate("initDelegate");
initDel.setDelegateBridgeAndPlayer(bridge);
initDel.start();
initDel.end();
// Get total number of defending units before the battle
final int preCountCanada = eastCanada.getUnits().size();
final int preCountAirSz_9 = sz_9.getUnits().getMatches(Matches.UnitIsAir).size();
// now move to attack
final MoveDelegate moveDelegate = (MoveDelegate) gameData.getDelegateList().getDelegate("move");
bridge.setStepName("CombatMove");
moveDelegate.setDelegateBridgeAndPlayer(bridge);
moveDelegate.start();
moveDelegate.move(sz_11.getUnits().getUnits(), gameData.getMap().getRoute(sz_11, sz_9));
moveDelegate.move(sz_9.getUnits().getUnits(infantryType, 1), gameData.getMap().getRoute(sz_9, eastCanada));
moveDelegate.end();
// fight the battle
final BattleDelegate battle = (BattleDelegate) gameData.getDelegateList().getDelegate("battle");
battle.setDelegateBridgeAndPlayer(bridge);
battle.start();
bridge.setRandomSource(new ScriptedRandomSource(new int[] {0, 0, 0}));
bridge.setRemote(getDummyPlayer());
fight(battle, sz_9, false);
battle.end();
// Get the total number of units that should be left after the planes retreat
final int expectedCountCanada = eastCanada.getUnits().size();
final int postCountInt = preCountCanada + preCountAirSz_9;
// Compare the expected count with the actual number of units in landing zone
assertEquals(expectedCountCanada, postCountInt);
}
/**
* @deprecated Use a mock object instead.
*/
@Deprecated
private static ITripleAPlayer getDummyPlayer() {
final InvocationHandler handler = new InvocationHandler() {
@Override
public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
return null;
}
};
return (ITripleAPlayer) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
TestUtil.getClassArrayFrom(ITripleAPlayer.class), handler);
}
}