package games.strategy.triplea.delegate;
import static games.strategy.triplea.delegate.BattleStepStrings.ATTACKER_WITHDRAW;
import static games.strategy.triplea.delegate.BattleStepStrings.FIRE;
import static games.strategy.triplea.delegate.BattleStepStrings.REMOVE_CASUALTIES;
import static games.strategy.triplea.delegate.BattleStepStrings.REMOVE_SNEAK_ATTACK_CASUALTIES;
import static games.strategy.triplea.delegate.BattleStepStrings.SELECT_CASUALTIES;
import static games.strategy.triplea.delegate.BattleStepStrings.SELECT_SUB_CASUALTIES;
import static games.strategy.triplea.delegate.BattleStepStrings.SUBS_FIRE;
import static games.strategy.triplea.delegate.BattleStepStrings.SUBS_SUBMERGE;
import static games.strategy.triplea.delegate.GameDataTestUtil.aaGun;
import static games.strategy.triplea.delegate.GameDataTestUtil.addTo;
import static games.strategy.triplea.delegate.GameDataTestUtil.americans;
import static games.strategy.triplea.delegate.GameDataTestUtil.armour;
import static games.strategy.triplea.delegate.GameDataTestUtil.battleDelegate;
import static games.strategy.triplea.delegate.GameDataTestUtil.bidPlaceDelegate;
import static games.strategy.triplea.delegate.GameDataTestUtil.bomber;
import static games.strategy.triplea.delegate.GameDataTestUtil.british;
import static games.strategy.triplea.delegate.GameDataTestUtil.carrier;
import static games.strategy.triplea.delegate.GameDataTestUtil.chinese;
import static games.strategy.triplea.delegate.GameDataTestUtil.destroyer;
import static games.strategy.triplea.delegate.GameDataTestUtil.factory;
import static games.strategy.triplea.delegate.GameDataTestUtil.fighter;
import static games.strategy.triplea.delegate.GameDataTestUtil.germans;
import static games.strategy.triplea.delegate.GameDataTestUtil.givePlayerRadar;
import static games.strategy.triplea.delegate.GameDataTestUtil.infantry;
import static games.strategy.triplea.delegate.GameDataTestUtil.italians;
import static games.strategy.triplea.delegate.GameDataTestUtil.load;
import static games.strategy.triplea.delegate.GameDataTestUtil.makeGameLowLuck;
import static games.strategy.triplea.delegate.GameDataTestUtil.move;
import static games.strategy.triplea.delegate.GameDataTestUtil.moveDelegate;
import static games.strategy.triplea.delegate.GameDataTestUtil.placeDelegate;
import static games.strategy.triplea.delegate.GameDataTestUtil.purchaseDelegate;
import static games.strategy.triplea.delegate.GameDataTestUtil.removeFrom;
import static games.strategy.triplea.delegate.GameDataTestUtil.russians;
import static games.strategy.triplea.delegate.GameDataTestUtil.submarine;
import static games.strategy.triplea.delegate.GameDataTestUtil.techDelegate;
import static games.strategy.triplea.delegate.GameDataTestUtil.territory;
import static games.strategy.triplea.delegate.GameDataTestUtil.transport;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.contains;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import org.junit.Before;
import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import games.strategy.debug.ClientLogger;
import games.strategy.engine.data.Change;
import games.strategy.engine.data.GameData;
import games.strategy.engine.data.GameParseException;
import games.strategy.engine.data.ITestDelegateBridge;
import games.strategy.engine.data.PlayerID;
import games.strategy.engine.data.RepairRule;
import games.strategy.engine.data.Route;
import games.strategy.engine.data.TechnologyFrontier;
import games.strategy.engine.data.Territory;
import games.strategy.engine.data.TerritoryEffect;
import games.strategy.engine.data.Unit;
import games.strategy.engine.data.UnitType;
import games.strategy.engine.data.changefactory.ChangeFactory;
import games.strategy.engine.random.ScriptedRandomSource;
import games.strategy.triplea.Constants;
import games.strategy.triplea.TripleAUnit;
import games.strategy.triplea.attachments.TechAttachment;
import games.strategy.triplea.attachments.TerritoryAttachment;
import games.strategy.triplea.attachments.UnitAttachment;
import games.strategy.triplea.delegate.IBattle.BattleType;
import games.strategy.triplea.delegate.dataObjects.CasualtyDetails;
import games.strategy.triplea.delegate.dataObjects.CasualtyList;
import games.strategy.triplea.delegate.dataObjects.MoveValidationResult;
import games.strategy.triplea.delegate.dataObjects.PlaceableUnits;
import games.strategy.triplea.delegate.dataObjects.TechResults;
import games.strategy.triplea.delegate.remote.IAbstractPlaceDelegate;
import games.strategy.triplea.player.ITripleAPlayer;
import games.strategy.triplea.ui.display.ITripleADisplay;
import games.strategy.triplea.xml.TestMapGameData;
import games.strategy.util.IntegerMap;
import games.strategy.util.Match;
public class WW2V3_41_Test {
private GameData gameData;
private final ITripleAPlayer dummyPlayer = mock(ITripleAPlayer.class);
@Before
public void setUp() throws Exception {
when(dummyPlayer.selectCasualties(any(), any(), anyInt(), any(), any(), any(), any(), any(), any(),
anyBoolean(), any(), any(), any(), any(), anyBoolean())).thenAnswer(new Answer<CasualtyDetails>() {
@Override
public CasualtyDetails answer(final InvocationOnMock invocation) throws Throwable {
final CasualtyList defaultCasualties = invocation.getArgument(11);
if (defaultCasualties != null) {
return new CasualtyDetails(defaultCasualties.getKilled(), defaultCasualties.getDamaged(), true);
}
return null;
}
});
gameData = TestMapGameData.WW2V3_1941.getGameData();
}
private ITestDelegateBridge getDelegateBridge(final PlayerID player) {
return GameDataTestUtil.getDelegateBridge(player, gameData);
}
public static String fight(final BattleDelegate battle, final Territory territory) {
for (final Entry<BattleType, Collection<Territory>> entry : battle.getBattles().getBattles().entrySet()) {
if (!entry.getKey().isBombingRun() && entry.getValue().contains(territory)) {
return battle.fightBattle(territory, false, entry.getKey());
}
}
throw new IllegalStateException("Could not find battle in: " + territory.getName());
}
@Test
public void testAACasualtiesLowLuckMixedRadar() {
// moved from BattleCalculatorTest because "revised" does not have "radar"
final PlayerID british = GameDataTestUtil.british(gameData);
final ITestDelegateBridge m_bridge = getDelegateBridge(british);
makeGameLowLuck(gameData);
// setSelectAACasualties(data, false);
givePlayerRadar(germans(gameData));
// 3 bombers and 3 fighters
final Collection<Unit> planes = bomber(gameData).create(3, british(gameData));
planes.addAll(fighter(gameData).create(3, british(gameData)));
final Collection<Unit> defendingAA =
territory("Germany", gameData).getUnits().getMatches(Matches.UnitIsAAforAnything);
// don't allow rolling, 6 of each is deterministic
m_bridge.setRandomSource(new ScriptedRandomSource(new int[] {ScriptedRandomSource.ERROR}));
final DiceRoll roll =
DiceRoll
.rollAA(
Match.getMatches(planes,
Matches.unitIsOfTypes(
UnitAttachment.get(defendingAA.iterator().next().getType()).getTargetsAA(gameData))),
defendingAA, m_bridge, territory("Germany", gameData), true);
final Collection<Unit> casualties = BattleCalculator.getAACasualties(false, planes, planes, defendingAA,
defendingAA, roll, m_bridge, null, null, null, territory("Germany", gameData), null, false, null).getKilled();
assertEquals(casualties.size(), 2);
// should be 1 fighter and 1 bomber
assertEquals(Match.countMatches(casualties, Matches.UnitIsStrategicBomber), 1);
assertEquals(Match.countMatches(casualties, Matches.UnitIsStrategicBomber.invert()), 1);
}
@Test
public void testAACasualtiesLowLuckMixedWithRollingRadar() {
// moved from BattleCalculatorTest because "revised" does not have "radar"
final PlayerID british = GameDataTestUtil.british(gameData);
final ITestDelegateBridge m_bridge = getDelegateBridge(british);
makeGameLowLuck(gameData);
// setSelectAACasualties(data, false);
givePlayerRadar(germans(gameData));
// 4 bombers and 4 fighters
final Collection<Unit> planes = bomber(gameData).create(4, british(gameData));
planes.addAll(fighter(gameData).create(4, british(gameData)));
final Collection<Unit> defendingAA =
territory("Germany", gameData).getUnits().getMatches(Matches.UnitIsAAforAnything);
// 1 roll, a hit
// then a dice to select the casualty
final ScriptedRandomSource randomSource = new ScriptedRandomSource(new int[] {0, 1});
m_bridge.setRandomSource(randomSource);
final DiceRoll roll =
DiceRoll
.rollAA(
Match.getMatches(planes,
Matches.unitIsOfTypes(
UnitAttachment.get(defendingAA.iterator().next().getType()).getTargetsAA(gameData))),
defendingAA, m_bridge, territory("Germany", gameData), true);
// make sure we rolled once
assertEquals(1, randomSource.getTotalRolled());
final Collection<Unit> casualties = BattleCalculator.getAACasualties(false, planes, planes, defendingAA,
defendingAA, roll, m_bridge, null, null, null, territory("Germany", gameData), null, false, null).getKilled();
assertEquals(casualties.size(), 3);
// should be 1 fighter and 2 bombers
assertEquals(Match.countMatches(casualties, Matches.UnitIsStrategicBomber), 2);
assertEquals(Match.countMatches(casualties, Matches.UnitIsStrategicBomber.invert()), 1);
}
@Test
public void testAACasualtiesLowLuckMixedWithRollingMissRadar() {
// moved from BattleCalculatorTest because "revised" does not have "radar"
final PlayerID british = GameDataTestUtil.british(gameData);
final ITestDelegateBridge m_bridge = getDelegateBridge(british);
makeGameLowLuck(gameData);
// setSelectAACasualties(data, false);
givePlayerRadar(germans(gameData));
// 4 bombers and 4 fighters
final Collection<Unit> planes = bomber(gameData).create(4, british(gameData));
planes.addAll(fighter(gameData).create(4, british(gameData)));
final Collection<Unit> defendingAA =
territory("Germany", gameData).getUnits().getMatches(Matches.UnitIsAAforAnything);
// 1 roll, a miss
// then a dice to select the casualty
final ScriptedRandomSource randomSource =
new ScriptedRandomSource(new int[] {5, 0, 0, 0, ScriptedRandomSource.ERROR});
m_bridge.setRandomSource(randomSource);
final DiceRoll roll =
DiceRoll
.rollAA(
Match.getMatches(planes,
Matches.unitIsOfTypes(
UnitAttachment.get(defendingAA.iterator().next().getType()).getTargetsAA(gameData))),
defendingAA, m_bridge, territory("Germany", gameData), true);
assertEquals(roll.getHits(), 2);
// make sure we rolled once
assertEquals(1, randomSource.getTotalRolled());
final Collection<Unit> casualties = BattleCalculator.getAACasualties(false, planes, planes, defendingAA,
defendingAA, roll, m_bridge, null, null, null, territory("Germany", gameData), null, false, null).getKilled();
assertEquals(casualties.size(), 2);
assertEquals(4, randomSource.getTotalRolled());
// should be 1 fighter and 2 bombers
assertEquals(Match.countMatches(casualties, Matches.UnitIsStrategicBomber), 1);
assertEquals(Match.countMatches(casualties, Matches.UnitIsStrategicBomber.invert()), 1);
}
@Test
public void testDefendingTrasnportsAutoKilled() {
final Territory sz13 = gameData.getMap().getTerritory("13 Sea Zone");
final Territory sz12 = gameData.getMap().getTerritory("12 Sea Zone");
final PlayerID british = GameDataTestUtil.british(gameData);
final MoveDelegate moveDelegate = moveDelegate(gameData);
final ITestDelegateBridge bridge = getDelegateBridge(british);
bridge.setStepName("CombatMove");
moveDelegate.setDelegateBridgeAndPlayer(bridge);
moveDelegate.start();
final Route sz12To13 = new Route();
sz12To13.setStart(sz12);
sz12To13.add(sz13);
final String error = moveDelegate.move(sz12.getUnits().getUnits(), sz12To13);
assertEquals(error, null);
assertEquals(sz13.getUnits().size(), 3);
moveDelegate.end();
// the transport was not removed automatically
assertEquals(sz13.getUnits().size(), 3);
final BattleDelegate bd = battleDelegate(gameData);
assertFalse(bd.getBattleTracker().getPendingBattleSites(false).isEmpty());
}
@Test
public void testUnplacedDie() {
final PlaceDelegate del = placeDelegate(gameData);
del.setDelegateBridgeAndPlayer(getDelegateBridge(british(gameData)));
del.start();
addTo(british(gameData), transport(gameData).create(1, british(gameData)), gameData);
del.end();
// unplaced units die
assertEquals(1, british(gameData).getUnits().size());
}
@Test
public void testPlaceEmpty() {
final PlaceDelegate del = placeDelegate(gameData);
del.setDelegateBridgeAndPlayer(getDelegateBridge(british(gameData)));
del.start();
addTo(british(gameData), transport(gameData).create(1, british(gameData)), gameData);
final String error = del.placeUnits(Collections.<Unit>emptyList(), territory("United Kingdom", gameData),
IAbstractPlaceDelegate.BidMode.NOT_BID);
assertNull(error);
}
@Test
public void testTechTokens() {
// Set up the test
final PlayerID germans = GameDataTestUtil.germans(gameData);
final ITestDelegateBridge delegateBridge = getDelegateBridge(germans);
delegateBridge.setStepName("germanTech");
final TechnologyDelegate techDelegate = techDelegate(gameData);
techDelegate.setDelegateBridgeAndPlayer(delegateBridge);
techDelegate.start();
final TechnologyFrontier mech = new TechnologyFrontier("", gameData);
mech.addAdvance(TechAdvance.findAdvance(TechAdvance.TECH_PROPERTY_MECHANIZED_INFANTRY, gameData, null));
// Add tech token
gameData.performChange(
ChangeFactory.changeResourcesChange(germans, gameData.getResourceList().getResource(Constants.TECH_TOKENS), 1));
// Check to make sure it was successful
final int initTokens = germans.getResources().getQuantity("techTokens");
assertEquals(1, initTokens);
// Fail the roll
delegateBridge.setRandomSource(new ScriptedRandomSource(new int[] {3}));
final TechResults roll = techDelegate.rollTech(1, mech, 0, null);
// Check to make sure it failed
assertEquals(0, roll.getHits());
final int midTokens = germans.getResources().getQuantity("techTokens");
assertEquals(1, midTokens);
// Make a Successful roll
delegateBridge.setRandomSource(new ScriptedRandomSource(new int[] {5}));
final TechResults roll2 = techDelegate.rollTech(1, mech, 0, null);
// Check to make sure it succeeded and all tokens were removed
assertEquals(1, roll2.getHits());
final int finalTokens = germans.getResources().getQuantity("techTokens");
assertEquals(0, finalTokens);
}
@Test
public void testInfantryLoadOnlyTransports() {
final Territory gibraltar = territory("Gibraltar", gameData);
// add a tank to gibralter
final PlayerID british = british(gameData);
addTo(gibraltar, infantry(gameData).create(1, british));
final MoveDelegate moveDelegate = moveDelegate(gameData);
final ITestDelegateBridge bridge = getDelegateBridge(british);
bridge.setStepName("britishCombatMove");
moveDelegate.setDelegateBridgeAndPlayer(bridge);
moveDelegate.start();
bridge.setRemote(dummyPlayer);
final Territory sz9 = territory("9 Sea Zone", gameData);
final Territory sz13 = territory("13 Sea Zone", gameData);
final Route sz9ToSz13 = new Route(sz9, territory("12 Sea Zone", gameData), sz13);
// move the transport to attack, this is suicide but valid
move(sz9.getUnits().getMatches(Matches.UnitIsTransport), sz9ToSz13);
// load the transport
load(gibraltar.getUnits().getUnits(), new Route(gibraltar, sz13));
moveDelegate.end();
bridge.setStepName("britishBattle");
final BattleDelegate battleDelegate = battleDelegate(gameData);
battleDelegate.setDelegateBridgeAndPlayer(bridge);
battleDelegate.start();
assertTrue(battleDelegate.getBattles().isEmpty());
}
@Test
public void testLoadedTransportAttackKillsLoadedUnits() {
final PlayerID british = british(gameData);
final MoveDelegate moveDelegate = moveDelegate(gameData);
final ITestDelegateBridge bridge = getDelegateBridge(british);
bridge.setStepName("britishCombatMove");
when(dummyPlayer.selectAttackSubs(any())).thenReturn(true);
bridge.setRemote(dummyPlayer);
moveDelegate.setDelegateBridgeAndPlayer(bridge);
moveDelegate.start();
final Territory sz9 = territory("9 Sea Zone", gameData);
final Territory sz7 = territory("7 Sea Zone", gameData);
final Territory uk = territory("United Kingdom", gameData);
final Route sz9ToSz7 = new Route(sz9, territory("8 Sea Zone", gameData), sz7);
// move the transport to attack, this is suicide but valid
final List<Unit> transports = sz9.getUnits().getMatches(Matches.UnitIsTransport);
move(transports, sz9ToSz7);
// load the transport
load(uk.getUnits().getMatches(Matches.UnitIsInfantry), new Route(uk, sz7));
moveDelegate(gameData).end();
final ScriptedRandomSource randomSource = new ScriptedRandomSource(new int[] {0, 1});
bridge.setRandomSource(randomSource);
bridge.setStepName("britishBattle");
final BattleDelegate battleDelegate = battleDelegate(gameData);
battleDelegate.setDelegateBridgeAndPlayer(bridge);
assertEquals(2, TransportTracker.transporting(transports.get(0)).size());
battleDelegate.start();
// battle already fought
// make sure the infantry die with the transport
assertTrue(sz7.getUnits().toString(), sz7.getUnits().getMatches(Matches.unitOwnedBy(british)).isEmpty());
}
@Test
public void testCanRetreatIntoEmptyEnemyTerritory() {
final Territory eastPoland = territory("East Poland", gameData);
final Territory ukraine = territory("Ukraine", gameData);
final Territory poland = territory("Poland", gameData);
// remove all units from east poland
removeFrom(eastPoland, eastPoland.getUnits().getUnits());
final MoveDelegate moveDelegate = moveDelegate(gameData);
final ITestDelegateBridge delegateBridge = getDelegateBridge(germans(gameData));
delegateBridge.setStepName("CombatMove");
moveDelegate.setDelegateBridgeAndPlayer(delegateBridge);
moveDelegate.start();
final Territory bulgaria = territory("Bulgaria Romania", gameData);
// attack from bulgraia
move(bulgaria.getUnits().getUnits(), new Route(bulgaria, ukraine));
// add an air attack from east poland
move(poland.getUnits().getMatches(Matches.UnitIsAir), new Route(poland, eastPoland, ukraine));
// we should not be able to retreat to east poland!
// that territory is still owned by the enemy
final MustFightBattle battle =
(MustFightBattle) AbstractMoveDelegate.getBattleTracker(gameData).getPendingBattle(ukraine, false, null);
assertFalse(battle.getAttackerRetreatTerritories().contains(eastPoland));
}
@Test
public void testCanRetreatIntoBlitzedTerritory() {
final Territory eastPoland = territory("East Poland", gameData);
final Territory ukraine = territory("Ukraine", gameData);
final Territory poland = territory("Poland", gameData);
// remove all units from east poland
removeFrom(eastPoland, eastPoland.getUnits().getUnits());
final MoveDelegate moveDelegate = moveDelegate(gameData);
final ITestDelegateBridge delegateBridge = getDelegateBridge(germans(gameData));
delegateBridge.setStepName("CombatMove");
moveDelegate.setDelegateBridgeAndPlayer(delegateBridge);
moveDelegate.start();
final Territory bulgaria = territory("Bulgaria Romania", gameData);
// attack from bulgraia
move(bulgaria.getUnits().getUnits(), new Route(bulgaria, ukraine));
// add a blitz attack
move(poland.getUnits().getMatches(Matches.UnitCanBlitz), new Route(poland, eastPoland, ukraine));
// we should not be able to retreat to east poland!
// that territory was just conquered
final MustFightBattle battle =
(MustFightBattle) AbstractMoveDelegate.getBattleTracker(gameData).getPendingBattle(ukraine, false, null);
assertTrue(battle.getAttackerRetreatTerritories().contains(eastPoland));
}
@Test
public void testCantBlitzFactoryOrAA() {
// Set up territories
final Territory poland = territory("Poland", gameData);
final Territory eastPoland = territory("East Poland", gameData);
final Territory ukraine = territory("Ukraine", gameData);
// remove all units from east poland
removeFrom(eastPoland, eastPoland.getUnits().getUnits());
// Add a russian factory
addTo(eastPoland, factory(gameData).create(1, russians(gameData)));
MoveDelegate moveDelegate = moveDelegate(gameData);
ITestDelegateBridge delegateBridge = getDelegateBridge(germans(gameData));
delegateBridge.setStepName("CombatMove");
moveDelegate.setDelegateBridgeAndPlayer(delegateBridge);
moveDelegate.start();
// add a blitz attack
String errorResults =
moveDelegate.move(poland.getUnits().getMatches(Matches.UnitCanBlitz), new Route(poland, eastPoland, ukraine));
assertError(errorResults);
/*
* Now try with an AA
*/
// remove all units from east poland
removeFrom(eastPoland, eastPoland.getUnits().getUnits());
// Add a russian factory
addTo(eastPoland, aaGun(gameData).create(1, russians(gameData)));
moveDelegate = moveDelegate(gameData);
delegateBridge = getDelegateBridge(germans(gameData));
delegateBridge.setStepName("CombatMove");
moveDelegate.setDelegateBridgeAndPlayer(delegateBridge);
moveDelegate.start();
// add a blitz attack
errorResults =
moveDelegate.move(poland.getUnits().getMatches(Matches.UnitCanBlitz), new Route(poland, eastPoland, ukraine));
assertError(errorResults);
}
@Test
public void testMultipleAAInTerritory() {
// Set up territories
final Territory poland = territory("Poland", gameData);
// Add a russian factory
final Territory germany = territory("Germany", gameData);
addTo(poland, aaGun(gameData).create(1, germans(gameData)));
MoveDelegate moveDelegate = moveDelegate(gameData);
ITestDelegateBridge delegateBridge = getDelegateBridge(germans(gameData));
delegateBridge.setStepName("NonCombatMove");
moveDelegate.setDelegateBridgeAndPlayer(delegateBridge);
moveDelegate.start();
final int preCount = germany.getUnits().getUnitCount();
/*
* Move one
*/
String errorResults =
moveDelegate.move(poland.getUnits().getMatches(Matches.UnitIsAAforAnything), new Route(poland, germany));
assertValid(errorResults);
assertEquals(germany.getUnits().getUnitCount(), preCount + 1);
/*
* Test unloading TRN
*/
final Territory finland = territory("Finland", gameData);
final Territory sz5 = territory("5 Sea Zone", gameData);
addTo(finland, aaGun(gameData).create(1, germans(gameData)));
moveDelegate = moveDelegate(gameData);
delegateBridge = getDelegateBridge(germans(gameData));
delegateBridge.setStepName("NonCombatMove");
moveDelegate.setDelegateBridgeAndPlayer(delegateBridge);
moveDelegate.start();
// load the trn
errorResults = moveDelegate.move(finland.getUnits().getMatches(Matches.UnitIsAAforAnything),
new Route(finland, sz5), sz5.getUnits().getMatches(Matches.UnitIsTransport));
assertValid(errorResults);
// unload the trn
errorResults = moveDelegate.move(sz5.getUnits().getMatches(Matches.UnitIsAAforAnything), new Route(sz5, germany));
assertValid(errorResults);
assertEquals(germany.getUnits().getUnitCount(), preCount + 2);
/*
* Test Building one
*/
final UnitType aaGun = GameDataTestUtil.aaGun(gameData);
final IntegerMap<UnitType> map = new IntegerMap<>();
map.add(aaGun, 1);
// Set up the test
final PlayerID germans = GameDataTestUtil.germans(gameData);
final PlaceDelegate placeDelegate = placeDelegate(gameData);
delegateBridge.setStepName("Place");
delegateBridge.setPlayerID(germans);
placeDelegate.setDelegateBridgeAndPlayer(getDelegateBridge(germans(gameData)));
placeDelegate.start();
addTo(germans(gameData), aaGun(gameData).create(1, germans(gameData)), gameData);
errorResults = placeDelegate.placeUnits(getUnits(map, germans), germany, IAbstractPlaceDelegate.BidMode.NOT_BID);
assertValid(errorResults);
assertEquals(germany.getUnits().getUnitCount(), preCount + 3);
}
@Test
public void testMechanizedInfantry() {
// Set up tech
final PlayerID germans = GameDataTestUtil.germans(gameData);
final ITestDelegateBridge delegateBridge = getDelegateBridge(germans(gameData));
TechTracker.addAdvance(germans, delegateBridge,
TechAdvance.findAdvance(TechAdvance.TECH_PROPERTY_MECHANIZED_INFANTRY, gameData, germans));
// Set up the move delegate
final MoveDelegate moveDelegate = moveDelegate(gameData);
delegateBridge.setStepName("CombatMove");
moveDelegate.setDelegateBridgeAndPlayer(delegateBridge);
moveDelegate.start();
// Set up the territories
final Territory poland = territory("Poland", gameData);
final Territory eastPoland = territory("East Poland", gameData);
final Territory belorussia = territory("Belorussia", gameData);
// Set up the unit types
final UnitType infantryType = GameDataTestUtil.infantry(gameData);
// Remove all units from east poland
removeFrom(eastPoland, eastPoland.getUnits().getUnits());
// Get total number of units in territories to start
final int preCountIntPoland = poland.getUnits().size();
final int preCountIntBelorussia = belorussia.getUnits().size();
// Get units
final Collection<Unit> moveUnits = poland.getUnits().getUnits(infantryType, 3);
moveUnits.addAll(poland.getUnits().getMatches(Matches.UnitCanBlitz));
// add a INVALID blitz attack
final String errorResults = moveDelegate.move(moveUnits, new Route(poland, eastPoland, belorussia));
assertError(errorResults);
// Fix the number of units
moveUnits.clear();
moveUnits.addAll(poland.getUnits().getUnits(infantryType, 2));
moveUnits.addAll(poland.getUnits().getMatches(Matches.UnitCanBlitz));
// add a VALID blitz attack
final String validResults = moveDelegate.move(moveUnits, new Route(poland, eastPoland, belorussia));
assertValid(validResults);
// Get number of units in territories after move (adjusted for movement)
final int postCountIntPoland = poland.getUnits().size() + 4;
final int postCountIntBelorussia = belorussia.getUnits().size() - 4;
// Compare the number of units before and after
assertEquals(preCountIntPoland, postCountIntPoland);
assertEquals(preCountIntBelorussia, postCountIntBelorussia);
}
@Test
public void testJetPower() {
// Set up tech
final PlayerID germans = GameDataTestUtil.germans(gameData);
final ITestDelegateBridge delegateBridge = getDelegateBridge(germans(gameData));
TechTracker.addAdvance(germans, delegateBridge,
TechAdvance.findAdvance(TechAdvance.TECH_PROPERTY_JET_POWER, gameData, germans));
// Set up the territories
final Territory poland = territory("Poland", gameData);
final Territory eastPoland = territory("East Poland", gameData);
// Set up the unit types
final UnitType fighterType = GameDataTestUtil.fighter(gameData);
delegateBridge.setStepName("germanBattle");
while (!gameData.getSequence().getStep().getName().equals("germanBattle")) {
gameData.getSequence().next();
}
final Collection<TerritoryEffect> territoryEffects = TerritoryEffectHelper.getEffects(eastPoland);
// With JET_POWER attacking fighter hits on 4 (0 base)
final List<Unit> germanFighter = (List<Unit>) poland.getUnits().getUnits(fighterType, 1);
delegateBridge.setRandomSource(new ScriptedRandomSource(new int[] {3}));
final DiceRoll roll1 = DiceRoll.rollDice(germanFighter, false, germans, delegateBridge, new MockBattle(eastPoland),
"", territoryEffects, null);
assertEquals(1, roll1.getHits());
// With JET_POWER defending fighter misses on 5 (0 base)
delegateBridge.setRandomSource(new ScriptedRandomSource(new int[] {4}));
final DiceRoll roll2 = DiceRoll.rollDice(germanFighter, true, germans, delegateBridge, new MockBattle(eastPoland),
"", territoryEffects, null);
assertEquals(0, roll2.getHits());
}
@Test
public void testBidPlace() {
final ITestDelegateBridge bridge = getDelegateBridge(british(gameData));
bridge.setStepName("BidPlace");
bidPlaceDelegate(gameData).setDelegateBridgeAndPlayer(bridge);
bidPlaceDelegate(gameData).start();
// create 20 british infantry
addTo(british(gameData), infantry(gameData).create(20, british(gameData)), gameData);
final Territory uk = territory("United Kingdom", gameData);
final Collection<Unit> units = british(gameData).getUnits().getUnits();
final PlaceableUnits placeable = bidPlaceDelegate(gameData).getPlaceableUnits(units, uk);
assertEquals(20, placeable.getMaxUnits());
assertNull(placeable.getErrorMessage());
final String error = bidPlaceDelegate(gameData).placeUnits(units, uk);
assertNull(error);
}
@Test
public void testFactoryPlace() {
// Set up game
final PlayerID british = GameDataTestUtil.british(gameData);
final ITestDelegateBridge delegateBridge = getDelegateBridge(british(gameData));
// Set up the territories
final Territory egypt = territory("Union of South Africa", gameData);
// Set up the unit types
final UnitType factoryType = GameDataTestUtil.factory(gameData);
// Set up the move delegate
final PlaceDelegate placeDelegate = placeDelegate(gameData);
delegateBridge.setStepName("Place");
delegateBridge.setPlayerID(british);
placeDelegate.setDelegateBridgeAndPlayer(delegateBridge);
placeDelegate.start();
// Add the factory
final IntegerMap<UnitType> map = new IntegerMap<>();
map.add(factoryType, 1);
addTo(british(gameData), factory(gameData).create(1, british(gameData)), gameData);
// Place the factory
final String response = placeDelegate.placeUnits(getUnits(map, british), egypt);
assertValid(response);
// placeUnits performPlace
// get production and unit production values
final TerritoryAttachment ta = TerritoryAttachment.get(egypt);
assertEquals(ta.getUnitProduction(), ta.getProduction());
}
@Test
public void testChinesePlacement() {
/*
* This tests that Chinese can place units in any territory, that they can
* place in just conquered territories, and that they can place in territories
* with up to 3 Chinese units in them.
*/
// Set up game
final PlayerID chinese = GameDataTestUtil.chinese(gameData);
final ITestDelegateBridge delegateBridge = getDelegateBridge(chinese(gameData));
delegateBridge.setPlayerID(chinese);
delegateBridge.setStepName("CombatMove");
final MoveDelegate moveDelegate = moveDelegate(gameData);
moveDelegate.setDelegateBridgeAndPlayer(delegateBridge);
moveDelegate.start();
// Set up the territories
final Territory yunnan = territory("Yunnan", gameData);
final Territory kiangsu = territory("Kiangsu", gameData);
final Territory hupeh = territory("Hupeh", gameData);
// Set up the unit types
final UnitType infantryType = GameDataTestUtil.infantry(gameData);
// Remove all units
removeFrom(kiangsu, kiangsu.getUnits().getUnits());
// add a VALID attack
final Collection<Unit> moveUnits = hupeh.getUnits().getUnits();
final String validResults = moveDelegate.move(moveUnits, new Route(hupeh, kiangsu));
assertValid(validResults);
/*
* Place units in just captured territory
*/
final PlaceDelegate placeDelegate = placeDelegate(gameData);
delegateBridge.setStepName("Place");
placeDelegate.setDelegateBridgeAndPlayer(delegateBridge);
placeDelegate.start();
// Add the infantry
IntegerMap<UnitType> map = new IntegerMap<>();
map.add(infantryType, 3);
addTo(chinese(gameData), infantry(gameData).create(1, chinese(gameData)), gameData);
// Get the number of units before placing
int preCount = kiangsu.getUnits().getUnitCount();
// Place the infantry
String response = placeDelegate.placeUnits(getUnits(map, chinese), kiangsu, IAbstractPlaceDelegate.BidMode.NOT_BID);
assertValid(response);
assertEquals(preCount + 1, kiangsu.getUnits().getUnitCount());
/*
* Place units in a territory with up to 3 Chinese units
*/
// Add the infantry
map = new IntegerMap<>();
map.add(infantryType, 3);
addTo(chinese(gameData), infantry(gameData).create(3, chinese(gameData)), gameData);
// Get the number of units before placing
preCount = yunnan.getUnits().getUnitCount();
// Place the infantry
response = placeDelegate.placeUnits(getUnits(map, chinese), yunnan, IAbstractPlaceDelegate.BidMode.NOT_BID);
assertValid(response);
final int midCount = yunnan.getUnits().getUnitCount();
// Make sure they were all placed
assertEquals(preCount, midCount - 3);
/*
* Place units in a territory with 3 or more Chinese units
*/
map = new IntegerMap<>();
map.add(infantryType, 1);
addTo(chinese(gameData), infantry(gameData).create(1, chinese(gameData)), gameData);
response = placeDelegate.placeUnits(getUnits(map, chinese), yunnan, IAbstractPlaceDelegate.BidMode.NOT_BID);
assertError(response);
// Make sure none were placed
final int postCount = yunnan.getUnits().getUnitCount();
assertEquals(midCount, postCount);
}
@Test
public void testPlaceInOccupiedSZ() {
// Set up game
final PlayerID germans = GameDataTestUtil.germans(gameData);
final ITestDelegateBridge delegateBridge = getDelegateBridge(british(gameData));
// Clear all units from the SZ and add an enemy unit
final Territory sz5 = territory("5 Sea Zone", gameData);
removeFrom(sz5, sz5.getUnits().getUnits());
addTo(sz5, destroyer(gameData).create(1, british(gameData)));
// Set up the unit types
final UnitType transportType = GameDataTestUtil.transport(gameData);
// Set up the move delegate
final PlaceDelegate placeDelegate = placeDelegate(gameData);
delegateBridge.setStepName("Place");
delegateBridge.setPlayerID(germans);
placeDelegate.setDelegateBridgeAndPlayer(delegateBridge);
placeDelegate.start();
// Add the transport
final IntegerMap<UnitType> map = new IntegerMap<>();
map.add(transportType, 1);
addTo(germans(gameData), transport(gameData).create(1, germans(gameData)), gameData);
// Place it
final String response = placeDelegate.placeUnits(getUnits(map, germans), sz5);
assertValid(response);
}
@Test
public void testMoveUnitsThroughSubs() {
final ITestDelegateBridge bridge = getDelegateBridge(british(gameData));
bridge.setStepName("britishNonCombatMove");
moveDelegate(gameData).setDelegateBridgeAndPlayer(bridge);
moveDelegate(gameData).start();
final Territory sz6 = territory("6 Sea Zone", gameData);
final Route route = new Route(sz6, territory("7 Sea Zone", gameData), territory("8 Sea Zone", gameData));
final String error = moveDelegate(gameData).move(sz6.getUnits().getUnits(), route);
assertNull(error, error);
}
@Test
public void testMoveUnitsThroughTransports() {
final ITestDelegateBridge bridge = getDelegateBridge(british(gameData));
bridge.setStepName("britishCombatMove");
moveDelegate(gameData).setDelegateBridgeAndPlayer(bridge);
moveDelegate(gameData).start();
final Territory sz12 = territory("12 Sea Zone", gameData);
final Route route = new Route(sz12, territory("13 Sea Zone", gameData), territory("14 Sea Zone", gameData));
final String error = moveDelegate(gameData).move(sz12.getUnits().getUnits(), route);
assertNull(error, error);
}
@Test
public void testMoveUnitsThroughTransports2() {
final ITestDelegateBridge bridge = getDelegateBridge(british(gameData));
bridge.setStepName("britishNonCombatMove");
moveDelegate(gameData).setDelegateBridgeAndPlayer(bridge);
moveDelegate(gameData).start();
final Territory sz12 = territory("12 Sea Zone", gameData);
final Territory sz14 = territory("14 Sea Zone", gameData);
removeFrom(sz14, sz14.getUnits().getUnits());
final Route route = new Route(sz12, territory("13 Sea Zone", gameData), sz14);
final String error = moveDelegate(gameData).move(sz12.getUnits().getUnits(), route);
assertNull(error, error);
}
@Test
public void testLoadThroughSubs() {
final ITestDelegateBridge bridge = getDelegateBridge(british(gameData));
bridge.setStepName("britishNonCombatMove");
final MoveDelegate moveDelegate = moveDelegate(gameData);
moveDelegate.setDelegateBridgeAndPlayer(bridge);
moveDelegate.start();
final Territory sz8 = territory("8 Sea Zone", gameData);
final Territory sz7 = territory("7 Sea Zone", gameData);
final Territory sz6 = territory("6 Sea Zone", gameData);
final Territory uk = territory("United Kingdom", gameData);
// add a transport
addTo(sz8, transport(gameData).create(1, british(gameData)));
// move the transport where to the sub is
assertValid(moveDelegate.move(sz8.getUnits().getUnits(), new Route(sz8, sz7)));
// load the transport
load(uk.getUnits().getMatches(Matches.UnitIsInfantry), new Route(uk, sz7));
// move the transport out
assertValid(
moveDelegate.move(sz7.getUnits().getMatches(Matches.unitOwnedBy(british(gameData))), new Route(sz7, sz6)));
}
@Test
public void testAttackUndoAndAttackAgain() {
final MoveDelegate move = moveDelegate(gameData);
final ITestDelegateBridge bridge = getDelegateBridge(italians(gameData));
bridge.setStepName("CombatMove");
move.setDelegateBridgeAndPlayer(bridge);
move.start();
final Territory sz14 = territory("14 Sea Zone", gameData);
final Territory sz13 = territory("13 Sea Zone", gameData);
final Territory sz12 = territory("12 Sea Zone", gameData);
final Route r = new Route(sz14, sz13, sz12);
// move the battleship
move(sz14.getUnits().getMatches(Matches.UnitHasMoreThanOneHitPointTotal), r);
// move everything
move(sz14.getUnits().getMatches(Matches.UnitIsNotTransport), r);
// undo it
move.undoMove(1);
// move again
move(sz14.getUnits().getMatches(Matches.UnitIsNotTransport), r);
final MustFightBattle mfb =
(MustFightBattle) AbstractMoveDelegate.getBattleTracker(gameData).getPendingBattle(sz12, false, null);
// only 3 attacking units
// the battleship and the two cruisers
assertEquals(3, mfb.getAttackingUnits().size());
}
@Test
public void testAttackSubsOnSubs() {
final String defender = "Germans";
final String attacker = "British";
final Territory attacked = territory("31 Sea Zone", gameData);
final Territory from = territory("32 Sea Zone", gameData);
// 1 sub attacks 1 sub
addTo(from, submarine(gameData).create(1, british(gameData)));
addTo(attacked, submarine(gameData).create(1, germans(gameData)));
final ITestDelegateBridge bridge = getDelegateBridge(british(gameData));
bridge.setStepName("CombatMove");
moveDelegate(gameData).setDelegateBridgeAndPlayer(bridge);
moveDelegate(gameData).start();
move(from.getUnits().getUnits(), new Route(from, attacked));
moveDelegate(gameData).end();
final MustFightBattle battle =
(MustFightBattle) AbstractMoveDelegate.getBattleTracker(gameData).getPendingBattle(attacked, false, null);
final List<String> steps = battle.determineStepStrings(true, bridge);
assertEquals(
Arrays.asList(attacker + SUBS_SUBMERGE, defender + SUBS_SUBMERGE, attacker + SUBS_FIRE,
defender + SELECT_SUB_CASUALTIES, defender + SUBS_FIRE, attacker + SELECT_SUB_CASUALTIES,
REMOVE_SNEAK_ATTACK_CASUALTIES, REMOVE_CASUALTIES, attacker + ATTACKER_WITHDRAW).toString(),
steps.toString());
bridge.setRemote(dummyPlayer);
// fight, each sub should fire
// and hit
final ScriptedRandomSource randomSource = new ScriptedRandomSource(0, 0, ScriptedRandomSource.ERROR);
bridge.setRandomSource(randomSource);
battle.fight(bridge);
assertEquals(2, randomSource.getTotalRolled());
assertTrue(attacked.getUnits().isEmpty());
}
@Test
public void testAttackSubsOnDestroyer() {
final String defender = "Germans";
final String attacker = "British";
final Territory attacked = territory("31 Sea Zone", gameData);
final Territory from = territory("32 Sea Zone", gameData);
// 1 sub attacks 1 sub and 1 destroyer
// defender sneak attacks, not attacker
addTo(from, submarine(gameData).create(1, british(gameData)));
addTo(attacked, submarine(gameData).create(1, germans(gameData)));
addTo(attacked, destroyer(gameData).create(1, germans(gameData)));
final ITestDelegateBridge bridge = getDelegateBridge(british(gameData));
bridge.setStepName("CombatMove");
moveDelegate(gameData).setDelegateBridgeAndPlayer(bridge);
moveDelegate(gameData).start();
move(from.getUnits().getUnits(), new Route(from, attacked));
moveDelegate(gameData).end();
final MustFightBattle battle =
(MustFightBattle) AbstractMoveDelegate.getBattleTracker(gameData).getPendingBattle(attacked, false, null);
final List<String> steps = battle.determineStepStrings(true, bridge);
assertEquals(
Arrays.asList(defender + SUBS_SUBMERGE, defender + SUBS_FIRE, attacker + SELECT_SUB_CASUALTIES,
REMOVE_SNEAK_ATTACK_CASUALTIES, attacker + SUBS_FIRE, defender + SELECT_SUB_CASUALTIES, defender + FIRE,
attacker + SELECT_CASUALTIES, REMOVE_CASUALTIES, attacker + ATTACKER_WITHDRAW).toString(),
steps.toString());
bridge.setRemote(dummyPlayer);
// defending subs sneak attack and hit
// no chance to return fire
final ScriptedRandomSource randomSource = new ScriptedRandomSource(0, ScriptedRandomSource.ERROR);
bridge.setRandomSource(randomSource);
battle.fight(bridge);
assertEquals(1, randomSource.getTotalRolled());
assertTrue(attacked.getUnits().getMatches(Matches.unitIsOwnedBy(british(gameData))).isEmpty());
assertEquals(2, attacked.getUnits().size());
}
@Test
public void testAttackDestroyerAndSubsAgainstSub() {
final String defender = "Germans";
final String attacker = "British";
final Territory attacked = territory("31 Sea Zone", gameData);
final Territory from = territory("32 Sea Zone", gameData);
// 1 sub and 1 destroyer attack 1 sub
// defender sneak attacks, not attacker
addTo(from, submarine(gameData).create(1, british(gameData)));
addTo(from, destroyer(gameData).create(1, british(gameData)));
addTo(attacked, submarine(gameData).create(1, germans(gameData)));
final ITestDelegateBridge bridge = getDelegateBridge(british(gameData));
bridge.setStepName("CombatMove");
moveDelegate(gameData).setDelegateBridgeAndPlayer(bridge);
moveDelegate(gameData).start();
move(from.getUnits().getUnits(), new Route(from, attacked));
moveDelegate(gameData).end();
final MustFightBattle battle =
(MustFightBattle) AbstractMoveDelegate.getBattleTracker(gameData).getPendingBattle(attacked, false, null);
final List<String> steps = battle.determineStepStrings(true, bridge);
assertEquals(
Arrays.asList(attacker + SUBS_SUBMERGE, attacker + SUBS_FIRE, defender + SELECT_SUB_CASUALTIES,
REMOVE_SNEAK_ATTACK_CASUALTIES, attacker + FIRE, defender + SELECT_CASUALTIES, defender + SUBS_FIRE,
attacker + SELECT_SUB_CASUALTIES, REMOVE_CASUALTIES, attacker + ATTACKER_WITHDRAW).toString(),
steps.toString());
bridge.setRemote(dummyPlayer);
// attacking subs sneak attack and hit
// no chance to return fire
final ScriptedRandomSource randomSource = new ScriptedRandomSource(0, ScriptedRandomSource.ERROR);
bridge.setRandomSource(randomSource);
battle.fight(bridge);
assertEquals(1, randomSource.getTotalRolled());
assertTrue(attacked.getUnits().getMatches(Matches.unitIsOwnedBy(germans(gameData))).isEmpty());
assertEquals(2, attacked.getUnits().size());
}
@Test
public void testAttackDestroyerAndSubsAgainstSubAndDestroyer() {
final String defender = "Germans";
final String attacker = "British";
final Territory attacked = territory("31 Sea Zone", gameData);
final Territory from = territory("32 Sea Zone", gameData);
// 1 sub and 1 destroyer attack 1 sub and 1 destroyer
// no sneak attacks
addTo(from, submarine(gameData).create(1, british(gameData)));
addTo(from, destroyer(gameData).create(1, british(gameData)));
addTo(attacked, submarine(gameData).create(1, germans(gameData)));
addTo(attacked, destroyer(gameData).create(1, germans(gameData)));
final ITestDelegateBridge bridge = getDelegateBridge(british(gameData));
bridge.setStepName("CombatMove");
moveDelegate(gameData).setDelegateBridgeAndPlayer(bridge);
moveDelegate(gameData).start();
move(from.getUnits().getUnits(), new Route(from, attacked));
moveDelegate(gameData).end();
final MustFightBattle battle =
(MustFightBattle) AbstractMoveDelegate.getBattleTracker(gameData).getPendingBattle(attacked, false, null);
final List<String> steps = battle.determineStepStrings(true, bridge);
assertEquals(
Arrays.asList(attacker + SUBS_FIRE, defender + SELECT_SUB_CASUALTIES, attacker + FIRE,
defender + SELECT_CASUALTIES, defender + SUBS_FIRE, attacker + SELECT_SUB_CASUALTIES, defender + FIRE,
attacker + SELECT_CASUALTIES, REMOVE_CASUALTIES, attacker + ATTACKER_WITHDRAW).toString(),
steps.toString());
when(dummyPlayer.selectCasualties(any(), any(), anyInt(), any(), any(), any(), any(), any(), any(), anyBoolean(),
any(),
any(), any(), any(), anyBoolean())).thenAnswer(new Answer<CasualtyDetails>() {
@Override
public CasualtyDetails answer(final InvocationOnMock invocation) {
final Collection<Unit> selectFrom = invocation.getArgument(0);
return new CasualtyDetails(Arrays.asList(selectFrom.iterator().next()), new ArrayList<>(), false);
}
});
bridge.setRemote(dummyPlayer);
// attacking subs sneak attack and hit
// no chance to return fire
final ScriptedRandomSource randomSource = new ScriptedRandomSource(0, 0, 0, 0, ScriptedRandomSource.ERROR);
bridge.setRandomSource(randomSource);
battle.fight(bridge);
assertEquals(4, randomSource.getTotalRolled());
assertEquals(0, attacked.getUnits().size());
}
@Test
public void testLimitBombardtoNumberOfUnloaded() {
final MoveDelegate move = moveDelegate(gameData);
final ITestDelegateBridge bridge = getDelegateBridge(italians(gameData));
when(dummyPlayer.selectShoreBombard(any())).thenReturn(true);
bridge.setRemote(dummyPlayer);
bridge.setStepName("CombatMove");
move.setDelegateBridgeAndPlayer(bridge);
move.start();
final Territory sz14 = territory("14 Sea Zone", gameData);
final Territory sz15 = territory("15 Sea Zone", gameData);
final Territory eg = territory("Egypt", gameData);
final Territory li = territory("Libya", gameData);
final Territory balkans = territory("Balkans", gameData);
// Clear all units from the attacked terr
removeFrom(eg, eg.getUnits().getUnits());
// Add 2 inf
final PlayerID british = GameDataTestUtil.british(gameData);
addTo(eg, infantry(gameData).create(2, british));
// load the transports
load(balkans.getUnits().getMatches(Matches.UnitIsInfantry), new Route(balkans, sz14));
// move the fleet
move(sz14.getUnits().getUnits(), new Route(sz14, sz15));
// move troops from Libya
move(li.getUnits().getMatches(Matches.unitOwnedBy(italians(gameData))), new Route(li, eg));
// unload the transports
move(sz15.getUnits().getMatches(Matches.UnitIsLand), new Route(sz15, eg));
move.end();
// start the battle phase, this will ask the user to bombard
battleDelegate(gameData).setDelegateBridgeAndPlayer(bridge);
BattleDelegate.doInitialize(battleDelegate(gameData).getBattleTracker(), bridge);
battleDelegate(gameData).addBombardmentSources();
final MustFightBattle mfb =
(MustFightBattle) AbstractMoveDelegate.getBattleTracker(gameData).getPendingBattle(eg, false, null);
// only 2 ships are allowed to bombard (there are 1 battleship and 2 cruisers that COULD bombard, but only 2 ships
// may bombard total)
assertEquals(2, mfb.getBombardingUnits().size());
// Show that bombard casualties can return fire
// Note- the 3 & 2 hits below show default behavior of bombarding at attack strength
// 2= Battleship hitting a 3, 2=Cruiser hitting a 3, 15=British infantry hitting once
bridge.setRandomSource(new ScriptedRandomSource(2, 2, 1, 5, 5, 5, 5, 5));
battleDelegate(gameData).setDelegateBridgeAndPlayer(bridge);
battleDelegate(gameData).start();
// end result should be 2 italian infantry.
assertEquals(3, eg.getUnits().size());
}
@Test
public void testBombardStrengthVariable() {
final MoveDelegate move = moveDelegate(gameData);
final ITestDelegateBridge bridge = getDelegateBridge(italians(gameData));
when(dummyPlayer.selectShoreBombard(any())).thenReturn(true);
bridge.setRemote(dummyPlayer);
bridge.setStepName("CombatMove");
move.setDelegateBridgeAndPlayer(bridge);
move.start();
final Territory sz14 = territory("14 Sea Zone", gameData);
final Territory sz15 = territory("15 Sea Zone", gameData);
final Territory eg = territory("Egypt", gameData);
final Territory balkans = territory("Balkans", gameData);
// Clear all units
removeFrom(eg, eg.getUnits().getUnits());
removeFrom(sz14, sz14.getUnits().getUnits());
// Add 2 inf to the attacked terr
final PlayerID british = GameDataTestUtil.british(gameData);
addTo(eg, infantry(gameData).create(2, british));
// create/load the destroyers and transports
final PlayerID italians = GameDataTestUtil.italians(gameData);
addTo(sz14, transport(gameData).create(1, italians));
addTo(sz14, destroyer(gameData).create(2, italians));
// load the transports
load(balkans.getUnits().getMatches(Matches.UnitIsInfantry), new Route(balkans, sz14));
// move the fleet
move(sz14.getUnits().getUnits(), new Route(sz14, sz15));
// unload the transports
move(sz15.getUnits().getMatches(Matches.UnitIsLand), new Route(sz15, eg));
move.end();
// Set the tech for DDs bombard
// ww2v3 doesn't have this tech, so this does nothing...
// TechAttachment.get(italians).setDestroyerBombard("true");
UnitAttachment.get(destroyer(gameData)).setCanBombard("true");
// Set the bombard strength for the DDs
final Collection<Unit> dds = Match.getMatches(sz15.getUnits().getUnits(), Matches.UnitIsDestroyer);
final Iterator<Unit> ddIter = dds.iterator();
while (ddIter.hasNext()) {
final Unit unit = ddIter.next();
final UnitAttachment ua = UnitAttachment.get(unit.getType());
ua.setBombard("3");
}
// start the battle phase, this will ask the user to bombard
battleDelegate(gameData).setDelegateBridgeAndPlayer(bridge);
BattleDelegate.doInitialize(battleDelegate(gameData).getBattleTracker(), bridge);
battleDelegate(gameData).addBombardmentSources();
final MustFightBattle mfb =
(MustFightBattle) AbstractMoveDelegate.getBattleTracker(gameData).getPendingBattle(eg, false, null);
assertNotNull(mfb);
// Show that bombard casualties can return fire
// destroyer bombard hit/miss on rolls of 4 & 3
// landing inf miss
// defending inf hit
bridge.setRandomSource(new ScriptedRandomSource(3, 2, 6, 6, 1, 1));
battleDelegate(gameData).setDelegateBridgeAndPlayer(bridge);
BattleDelegate.doInitialize(battleDelegate(gameData).getBattleTracker(), bridge);
battleDelegate(gameData).addBombardmentSources();
fight(battleDelegate(gameData), eg);
// 1 defending inf remaining
assertEquals(1, eg.getUnits().size());
}
@Test
public void testAmphAttackUndoAndAttackAgainBombard() {
final MoveDelegate move = moveDelegate(gameData);
final ITestDelegateBridge bridge = getDelegateBridge(italians(gameData));
when(dummyPlayer.selectShoreBombard(any())).thenReturn(true);
bridge.setRemote(dummyPlayer);
bridge.setStepName("CombatMove");
move.setDelegateBridgeAndPlayer(bridge);
move.start();
final Territory sz14 = territory("14 Sea Zone", gameData);
final Territory sz15 = territory("15 Sea Zone", gameData);
final Territory eg = territory("Egypt", gameData);
final Territory li = territory("Libya", gameData);
final Territory balkans = territory("Balkans", gameData);
// load the transports
load(balkans.getUnits().getMatches(Matches.UnitIsInfantry), new Route(balkans, sz14));
// move the fleet
move(sz14.getUnits().getUnits(), new Route(sz14, sz15));
// move troops from Libya
move(li.getUnits().getMatches(Matches.unitOwnedBy(italians(gameData))), new Route(li, eg));
// unload the transports
move(sz15.getUnits().getMatches(Matches.UnitIsLand), new Route(sz15, eg));
// undo amphibious landing
move.undoMove(move.getMovesMade().size() - 1);
// move again
move(sz15.getUnits().getMatches(Matches.UnitIsLand), new Route(sz15, eg));
move.end();
// start the battle phase, this will ask the user to bombard
battleDelegate(gameData).setDelegateBridgeAndPlayer(bridge);
BattleDelegate.doInitialize(battleDelegate(gameData).getBattleTracker(), bridge);
battleDelegate(gameData).addBombardmentSources();
final MustFightBattle mfb =
(MustFightBattle) AbstractMoveDelegate.getBattleTracker(gameData).getPendingBattle(eg, false, null);
// only 2 battleships are allowed to bombard
assertEquals(2, mfb.getBombardingUnits().size());
}
@Test
public void testCarrierWithAlliedPlanes() {
final Territory sz8 = territory("8 Sea Zone", gameData);
final Territory sz1 = territory("1 Sea Zone", gameData);
addTo(sz8, carrier(gameData).create(1, british(gameData)));
addTo(sz8, fighter(gameData).create(1, americans(gameData)));
final Route route = new Route(sz8, sz1);
final ITestDelegateBridge bridge = getDelegateBridge(british(gameData));
bridge.setStepName("CombatMove");
moveDelegate(gameData).setDelegateBridgeAndPlayer(bridge);
moveDelegate(gameData).start();
move(sz8.getUnits().getUnits(), route);
// make sure the fighter moved
assertTrue(sz8.getUnits().getUnits().isEmpty());
assertFalse(sz1.getUnits().getMatches(Matches.UnitIsAir).isEmpty());
}
@Test
public void testAirCanLandWithAlliedFighters() {
// germany owns madagascar, with 2 fighters in it
// also 1 carrier, and 1 allied fighter in sz 40
// the fighters should not be able to move from madagascar
// to sz 40, since with the allied fighter, their is no room
// on the carrier
final Territory madagascar = territory("French Madagascar", gameData);
final PlayerID germans = germans(gameData);
madagascar.setOwner(germans);
final Territory sz40 = territory("40 Sea Zone", gameData);
addTo(sz40, carrier(gameData).create(1, germans));
addTo(sz40, fighter(gameData).create(1, italians(gameData)));
addTo(madagascar, fighter(gameData).create(2, germans));
final Route route = gameData.getMap().getRoute(madagascar, sz40);
final ITestDelegateBridge bridge = getDelegateBridge(germans);
bridge.setStepName("CombatMove");
moveDelegate(gameData).setDelegateBridgeAndPlayer(bridge);
moveDelegate(gameData).start();
// don't allow kamikaze
bridge.setRemote(dummyPlayer);
final String error = moveDelegate(gameData).move(madagascar.getUnits().getUnits(), route);
assertError(error);
}
@Test
public void testMechInfSimple() {
final PlayerID germans = germans(gameData);
final Territory france = territory("France", gameData);
final Territory germany = territory("Germany", gameData);
final Territory poland = territory("Poland", gameData);
TechAttachment.get(germans).setMechanizedInfantry("true");
final ITestDelegateBridge bridge = getDelegateBridge(germans);
bridge.setStepName("CombatMove");
moveDelegate(gameData).setDelegateBridgeAndPlayer(bridge);
moveDelegate(gameData).start();
final Route r = new Route(france, germany, poland);
final List<Unit> toMove = new ArrayList<>();
// 1 armour and 1 infantry
toMove.addAll(france.getUnits().getMatches(Matches.UnitCanBlitz));
toMove.add(france.getUnits().getMatches(Matches.UnitIsInfantry).get(0));
move(toMove, r);
}
@Test
public void testMechInfUnitAlreadyMovedSimple() {
final PlayerID germans = germans(gameData);
final Territory france = territory("France", gameData);
final Territory germany = territory("Germany", gameData);
TechAttachment.get(germans).setMechanizedInfantry("true");
final ITestDelegateBridge bridge = getDelegateBridge(germans);
bridge.setStepName("CombatMove");
moveDelegate(gameData).setDelegateBridgeAndPlayer(bridge);
moveDelegate(gameData).start();
// get rid of the infantry in france
removeFrom(france, france.getUnits().getMatches(Matches.UnitIsInfantry));
// move an infantry from germany to france
move(germany.getUnits().getMatches(Matches.UnitIsInfantry).subList(0, 1), new Route(germany, france));
// try to move all the units in france, the infantry should not be able to move
final Route r = new Route(france, germany);
final String error = moveDelegate(gameData).move(france.getUnits().getUnits(), r);
assertFalse(error == null);
}
@Test
public void testParatroopsWalkOnWater() {
final PlayerID germans = germans(gameData);
final Territory france = territory("France", gameData);
TechAttachment.get(germans).setParatroopers("true");
final Route r = gameData.getMap().getRoute(france, territory("7 Sea Zone", gameData));
final Collection<Unit> paratroopers = france.getUnits().getMatches(Matches.UnitIsAirTransportable);
assertFalse(paratroopers.isEmpty());
final MoveValidationResult results = MoveValidator.validateMove(paratroopers, r, germans,
Collections.<Unit>emptyList(), new HashMap<>(), false, null, gameData);
assertFalse(results.isMoveValid());
}
@Test
public void testBomberWithTankOverWaterParatroopers() {
final PlayerID germans = germans(gameData);
TechAttachment.get(germans).setParatroopers("true");
final Territory sz5 = territory("5 Sea Zone", gameData);
final Territory germany = territory("Germany", gameData);
final Territory karelia = territory("Karelia S.S.R.", gameData);
addTo(germany, armour(gameData).create(1, germans));
final Route r = new Route(germany, sz5, karelia);
final Collection<Unit> toMove = germany.getUnits().getMatches(Matches.UnitCanBlitz);
toMove.addAll(germany.getUnits().getMatches(Matches.UnitIsStrategicBomber));
assertEquals(2, toMove.size());
final MoveValidationResult results = MoveValidator.validateMove(toMove, r, germans, Collections.<Unit>emptyList(),
new HashMap<>(), false, null, gameData);
assertFalse(results.isMoveValid());
}
@Test
public void testBomberTankOverWater() {
// can't transport a tank over water using a bomber
final PlayerID germans = germans(gameData);
final Territory sz5 = territory("5 Sea Zone", gameData);
final Territory germany = territory("Germany", gameData);
final Territory karelia = territory("Karelia S.S.R.", gameData);
addTo(germany, armour(gameData).create(1, germans));
final Route r = new Route(germany, sz5, karelia);
final Collection<Unit> toMove = germany.getUnits().getMatches(Matches.UnitCanBlitz);
toMove.addAll(germany.getUnits().getMatches(Matches.UnitIsStrategicBomber));
assertEquals(2, toMove.size());
final MoveValidationResult results = MoveValidator.validateMove(toMove, r, germans, Collections.<Unit>emptyList(),
new HashMap<>(), false, null, gameData);
assertFalse(results.isMoveValid());
}
@Test
public void testMoveParatroopersAsNonPartroops() {
// move a bomber and a paratrooper
// one step, but as a normal movement
final PlayerID germans = germans(gameData);
final Territory germany = territory("Germany", gameData);
final Territory nwe = territory("Northwestern Europe", gameData);
final ITestDelegateBridge bridge = getDelegateBridge(germans);
bridge.setStepName("CombatMove");
moveDelegate(gameData).setDelegateBridgeAndPlayer(bridge);
moveDelegate(gameData).start();
TechAttachment.get(germans).setParatroopers("true");
List<Unit> paratrooper = germany.getUnits().getMatches(Matches.UnitIsAirTransportable);
paratrooper = paratrooper.subList(0, 1);
final List<Unit> bomberAndParatroop = new ArrayList<>(paratrooper);
bomberAndParatroop.addAll(germany.getUnits().getMatches(Matches.UnitIsAirTransport));
// move to nwe, this is a valid move, and it not a partroop move
move(bomberAndParatroop, new Route(germany, nwe));
}
@Test
public void testCantMoveParatroopersThatMovedPreviously() {
// make sure infantry can't be moved as paratroopers after moving
final PlayerID germans = germans(gameData);
final Territory germany = territory("Germany", gameData);
final Territory nwe = territory("Northwestern Europe", gameData);
final Territory poland = territory("Poland", gameData);
final Territory eastPoland = territory("East Poland", gameData);
final ITestDelegateBridge bridge = getDelegateBridge(germans);
bridge.setStepName("CombatMove");
moveDelegate(gameData).setDelegateBridgeAndPlayer(bridge);
moveDelegate(gameData).start();
TechAttachment.get(germans).setParatroopers("true");
final List<Unit> paratrooper = nwe.getUnits().getMatches(Matches.UnitIsAirTransportable);
move(paratrooper, new Route(nwe, germany));
final List<Unit> bomberAndParatroop = new ArrayList<>(paratrooper);
bomberAndParatroop.addAll(germany.getUnits().getMatches(Matches.UnitIsAirTransport));
// move the units to east poland
final String error = moveDelegate(gameData).move(bomberAndParatroop, new Route(germany, poland, eastPoland));
assertError(error);
}
@Test
public void testCantTransportParatroopersWithBombersThatMovedPreviously() {
// make sure bombers can't move then pick up paratroopers
final PlayerID germans = germans(gameData);
final Territory germany = territory("Germany", gameData);
final Territory bulgaria = territory("Bulgaria Romania", gameData);
final Territory poland = territory("Poland", gameData);
final Territory ukraine = territory("Ukraine", gameData);
final ITestDelegateBridge bridge = getDelegateBridge(germans);
bridge.setStepName("CombatMove");
moveDelegate(gameData).setDelegateBridgeAndPlayer(bridge);
moveDelegate(gameData).start();
TechAttachment.get(germans).setParatroopers("true");
// Move the bomber first
final List<Unit> bomber = germany.getUnits().getMatches(Matches.UnitIsAirTransport);
move(bomber, new Route(germany, poland));
// Pick up a paratrooper
final List<Unit> bomberAndParatroop = new ArrayList<>(bomber);
bomberAndParatroop.addAll(poland.getUnits().getUnits(GameDataTestUtil.infantry(gameData), 1));
// move them
final String error = moveDelegate(gameData).move(bomberAndParatroop, new Route(poland, bulgaria, ukraine));
assertError(error);
}
@Test
public void testMoveOneParatrooperPerBomber() {
// make sure only 1 paratroop per bomber can be moved
final PlayerID germans = germans(gameData);
final Territory germany = territory("Germany", gameData);
// Territory nwe = territory("Northwestern Europe", gameData);
final Territory poland = territory("Poland", gameData);
final Territory eastPoland = territory("East Poland", gameData);
final ITestDelegateBridge bridge = getDelegateBridge(germans);
bridge.setStepName("CombatMove");
moveDelegate(gameData).setDelegateBridgeAndPlayer(bridge);
moveDelegate(gameData).start();
TechAttachment.get(germans).setParatroopers("true");
final List<Unit> bomberAndParatroop = new ArrayList<>();
bomberAndParatroop.addAll(germany.getUnits().getMatches(Matches.UnitIsAirTransport));
// add 2 infantry
bomberAndParatroop.addAll(germany.getUnits().getUnits(GameDataTestUtil.infantry(gameData), 2));
// move the units to east poland
final String error = moveDelegate(gameData).move(bomberAndParatroop, new Route(germany, poland, eastPoland));
assertError(error);
}
@Test
public void testParatroopersMoveTwice() {
// After a battle move to put a bomber + infantry (paratroop) in a first enemy
// territory, you can make a new move (in the same battle move round) to put
// bomber+ infantry in a more internal enemy territory.
final PlayerID germans = germans(gameData);
final Territory germany = territory("Germany", gameData);
final Territory poland = territory("Poland", gameData);
final Territory eastPoland = territory("East Poland", gameData);
final Territory beloRussia = territory("Belorussia", gameData);
final ITestDelegateBridge bridge = getDelegateBridge(germans);
bridge.setStepName("CombatMove");
moveDelegate(gameData).setDelegateBridgeAndPlayer(bridge);
moveDelegate(gameData).start();
TechAttachment.get(germans).setParatroopers("true");
List<Unit> paratroopers = germany.getUnits().getMatches(Matches.UnitIsAirTransportable);
paratroopers = paratroopers.subList(0, 1);
final List<Unit> bomberAndParatroop = new ArrayList<>(paratroopers);
bomberAndParatroop.addAll(germany.getUnits().getMatches(Matches.UnitIsAirTransport));
final Route route = new Route(germany, poland, eastPoland);
final List<Unit> airTransports = germany.getUnits().getMatches(Matches.UnitIsAirTransport);
for (final Unit airTransport : airTransports) {
for (final Unit unit : paratroopers) {
final Change change = TransportTracker.loadTransportChange((TripleAUnit) airTransport, unit);
bridge.addChange(change);
}
}
// move the units to east poland
// airTransports
String error = moveDelegate(gameData).move(bomberAndParatroop, route);
assertValid(error);
// try to move them further, this should fail
error = moveDelegate(gameData).move(bomberAndParatroop, new Route(eastPoland, beloRussia));
assertError(error);
}
@Test
public void testParatroopersFlyOverBlitzedTerritory() {
// We should be able to blitz a territory, then fly over it with paratroops to battle.
final PlayerID germans = germans(gameData);
final Territory germany = territory("Germany", gameData);
final Territory poland = territory("Poland", gameData);
final Territory eastPoland = territory("East Poland", gameData);
final Territory beloRussia = territory("Belorussia", gameData);
// Clear East Poland
removeFrom(eastPoland, eastPoland.getUnits().getUnits());
// Set up test
final ITestDelegateBridge bridge = getDelegateBridge(germans);
bridge.setStepName("CombatMove");
moveDelegate(gameData).setDelegateBridgeAndPlayer(bridge);
moveDelegate(gameData).start();
TechAttachment.get(germans).setParatroopers("true");
List<Unit> paratrooper = germany.getUnits().getMatches(Matches.UnitIsAirTransportable);
paratrooper = paratrooper.subList(0, 1);
final List<Unit> bomberAndParatroop = new ArrayList<>(paratrooper);
bomberAndParatroop.addAll(germany.getUnits().getMatches(Matches.UnitIsAirTransport));
final List<Unit> tanks = poland.getUnits().getMatches(Matches.UnitCanBlitz);
move(tanks, new Route(poland, eastPoland, beloRussia));
final List<Unit> airTransports = Match.getMatches(bomberAndParatroop, Matches.UnitIsAirTransport);
for (final Unit airTransport : airTransports) {
for (final Unit unit : paratrooper) {
final Change change = TransportTracker.loadTransportChange((TripleAUnit) airTransport, unit);
bridge.addChange(change);
}
}
// Verify paratroops can overfly blitzed territory
final String error =
moveDelegate(gameData).move(bomberAndParatroop, new Route(germany, poland, eastPoland, beloRussia));
assertValid(error);
}
@Test
public void testAmphibAttackWithPlanesOnlyAskRetreatOnce() {
final PlayerID germans = germans(gameData);
final ITestDelegateBridge bridge = getDelegateBridge(germans);
bridge.setStepName("CombatMove");
moveDelegate(gameData).setDelegateBridgeAndPlayer(bridge);
moveDelegate(gameData).start();
final Territory france = territory("France", gameData);
final Territory egypt = territory("Egypt", gameData);
final Territory balkans = territory("Balkans", gameData);
final Territory libya = territory("Libya", gameData);
final Territory germany = territory("Germany", gameData);
final Territory sz13 = territory("13 Sea Zone", gameData);
final Territory sz14 = territory("14 Sea Zone", gameData);
final Territory sz15 = territory("15 Sea Zone", gameData);
;
when(dummyPlayer.retreatQuery(any(), anyBoolean(), any(),
any(), contains(BattleStepStrings.RETREAT_PLANES))).thenThrow(
new AssertionError("The Message is not allowed to contain the BattleStepStrings.RETREAT_PLANES constant"));
bridge.setRemote(dummyPlayer);
final ITripleADisplay dummyDisplay = mock(ITripleADisplay.class);
doThrow(new AssertionError(
"None of the Battle steps is allow to contain the BattleStepStrings.PLANES_WITHDRAW constant"))
.when(dummyDisplay).listBattleSteps(any(), argThat(list -> {
for (final String string : list) {
if (string.contains(BattleStepStrings.PLANES_WITHDRAW)) {
return true;
}
}
return false;
}));
bridge.setDisplay(dummyDisplay);
// move units for amphib assault
load(france.getUnits().getMatches(Matches.UnitIsInfantry), new Route(france, sz13));
move(sz13.getUnits().getUnits(), new Route(sz13, sz14, sz15));
move(sz15.getUnits().getMatches(Matches.UnitIsInfantry), new Route(sz15, egypt));
// ground attack
load(libya.getUnits().getMatches(Matches.UnitIsArtillery), new Route(libya, egypt));
// air units
move(germany.getUnits().getMatches(Matches.UnitIsStrategicBomber), new Route(germany, balkans, sz14, sz15, egypt));
moveDelegate(gameData).end();
bridge.setStepName("Combat");
// cook the dice so that all miss first round,all hit second round
bridge.setRandomSource(new ScriptedRandomSource(5, 5, 5, 5, 5, 5, 5, 5, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1));
battleDelegate(gameData).setDelegateBridgeAndPlayer(bridge);
battleDelegate(gameData).start();
}
@Test
public void testDefencelessTransportsDie() {
final PlayerID british = british(gameData);
final ITestDelegateBridge bridge = getDelegateBridge(british);
bridge.setStepName("CombatMove");
moveDelegate(gameData).setDelegateBridgeAndPlayer(bridge);
moveDelegate(gameData).start();
final Territory uk = territory("United Kingdom", gameData);
final Territory sz5 = territory("5 Sea Zone", gameData);
// remove the sub
removeFrom(sz5, sz5.getUnits().getMatches(Matches.UnitIsSub));
when(dummyPlayer.retreatQuery(any(), anyBoolean(), any(),
any(), any())).thenAnswer(new Answer<Territory>() {
@Override
public Territory answer(final InvocationOnMock invocation) throws Throwable {
throw new IllegalStateException(
"Should not be asked to retreat:" + invocation.getArgument(4));
}
});
bridge.setRemote(dummyPlayer);
move(uk.getUnits().getMatches(Matches.UnitIsAir), gameData.getMap().getRoute(uk, sz5));
// move units for amphib assault
moveDelegate(gameData).end();
bridge.setStepName("Combat");
// cook the dice so that 1 british fighters hits, and nothing else
// this will leave 1 transport alone in the sea zone
bridge.setRandomSource(new ScriptedRandomSource(1, 5, 5, 5, 5, 5, 5, 5, 5));
battleDelegate(gameData).setDelegateBridgeAndPlayer(bridge);
battleDelegate(gameData).start();
// make sure the transports died
assertTrue(sz5.getUnits().getMatches(Matches.unitIsOwnedBy(germans(gameData))).isEmpty());
}
@Test
public void testFighterLandsWhereCarrierCanBePlaced() {
final PlayerID germans = germans(gameData);
// germans have 1 carrier to place
addTo(germans, carrier(gameData).create(1, germans), gameData);
// start the move phase
final ITestDelegateBridge bridge = getDelegateBridge(germans);
bridge.setStepName("CombatMove");
moveDelegate(gameData).setDelegateBridgeAndPlayer(bridge);
moveDelegate(gameData).start();
bridge.setRemote(dummyPlayer);
// the fighter should be able to move and hover in the sea zone
// the fighter has no movement left
final Territory neEurope = territory("Northwestern Europe", gameData);
final Route route = new Route(neEurope, territory("Germany", gameData), territory("Poland", gameData),
territory("Baltic States", gameData), territory("5 Sea Zone", gameData));
// the fighter should be able to move, and hover in the sea zone until the carrier is placed
move(neEurope.getUnits().getMatches(Matches.UnitIsAir), route);
}
@Test
public void testFighterCantHoverWithNoCarrierToPlace() {
// start the move phase
final ITestDelegateBridge bridge = getDelegateBridge(germans(gameData));
bridge.setStepName("CombatMove");
moveDelegate(gameData).setDelegateBridgeAndPlayer(bridge);
moveDelegate(gameData).start();
bridge.setRemote(dummyPlayer);
// the fighter should not be able to move and hover in the sea zone
// since their are no carriers to place
// the fighter has no movement left
final Territory neEurope = territory("Northwestern Europe", gameData);
final Route route = new Route(neEurope, territory("Germany", gameData), territory("Poland", gameData),
territory("Baltic States", gameData), territory("5 Sea Zone", gameData));
final String error = moveDelegate(gameData).move(neEurope.getUnits().getMatches(Matches.UnitIsAir), route);
assertNotNull(error);
}
@Test
public void testRepair() {
final Territory germany = territory("Germany", gameData);
final Unit factory = germany.getUnits().getMatches(Matches.UnitCanBeDamaged).get(0);
final PurchaseDelegate del = purchaseDelegate(gameData);
del.setDelegateBridgeAndPlayer(getDelegateBridge(germans(gameData)));
del.start();
// Set up player
final PlayerID germans = GameDataTestUtil.germans(gameData);
final int initPUs = germans.getResources().getQuantity("PUs");
// damage a factory
IntegerMap<Unit> startHits = new IntegerMap<>();
startHits.put(factory, 1);
gameData.performChange(ChangeFactory.bombingUnitDamage(startHits));
assertEquals(((TripleAUnit) factory).getUnitDamage(), 1);
RepairRule repair = germans(gameData).getRepairFrontier().getRules().get(0);
IntegerMap<RepairRule> repairs = new IntegerMap<>();
repairs.put(repair, 1);
String error = del.purchaseRepair(Collections.singletonMap(
Match.getMatches(germany.getUnits().getUnits(), Matches.UnitCanBeDamaged).iterator().next(), repairs));
assertValid(error);
assertEquals(((TripleAUnit) factory).getUnitDamage(), 0);
// Find cost
final int midPUs = germans.getResources().getQuantity("PUs");
assertEquals(initPUs, midPUs + 1);
/*
* INCREASED_FACTORY_PRODUCTION repairs
*/
// Set up INCREASED_FACTORY_PRODUCTION
final ITestDelegateBridge delegateBridge = getDelegateBridge(germans(gameData));
TechTracker.addAdvance(germans, delegateBridge,
TechAdvance.findAdvance(TechAdvance.TECH_PROPERTY_INCREASED_FACTORY_PRODUCTION, gameData, germans));
// damage a factory
startHits = new IntegerMap<>();
startHits.put(factory, 2);
gameData.performChange(ChangeFactory.bombingUnitDamage(startHits));
assertEquals(((TripleAUnit) factory).getUnitDamage(), 2);
repair = germans(gameData).getRepairFrontier().getRules().get(0);
repairs = new IntegerMap<>();
repairs.put(repair, 2);
error = del.purchaseRepair(Collections.singletonMap(
Match.getMatches(germany.getUnits().getUnits(), Matches.UnitCanBeDamaged).iterator().next(), repairs));
assertValid(error);
assertEquals(((TripleAUnit) factory).getUnitDamage(), 0);
// Find cost
final int finalPUs = germans.getResources().getQuantity("PUs");
assertEquals(midPUs, finalPUs + 1);
}
@Test
public void testRepairMoreThanDamaged() {
final Territory germany = territory("Germany", gameData);
final Unit factory = germany.getUnits().getMatches(Matches.UnitCanBeDamaged).get(0);
final PurchaseDelegate del = purchaseDelegate(gameData);
del.setDelegateBridgeAndPlayer(getDelegateBridge(germans(gameData)));
del.start();
// dame a factory
final IntegerMap<Unit> startHits = new IntegerMap<>();
startHits.put(factory, 1);
gameData.performChange(ChangeFactory.bombingUnitDamage(startHits));
assertEquals(((TripleAUnit) factory).getUnitDamage(), 1);
final RepairRule repair = germans(gameData).getRepairFrontier().getRules().get(0);
final IntegerMap<RepairRule> repairs = new IntegerMap<>();
// we have 1 damaged marker, but trying to repair 2
repairs.put(repair, 2);
final String error = del.purchaseRepair(Collections.singletonMap(
Match.getMatches(germany.getUnits().getUnits(), Matches.UnitCanBeDamaged).iterator().next(), repairs));
// it is no longer an error, we just math max 0 it
assertValid(error);
assertEquals(((TripleAUnit) factory).getUnitDamage(), 0);
}
@Test
public void testOccupiedTerrOfAttachment() {
// Set up test
final PlayerID british = GameDataTestUtil.british(gameData);
final ITestDelegateBridge delegateBridge = getDelegateBridge(british(gameData));
// Set up the move delegate
final MoveDelegate moveDelegate = moveDelegate(gameData);
delegateBridge.setStepName("CombatMove");
moveDelegate(gameData).setDelegateBridgeAndPlayer(delegateBridge);
moveDelegate(gameData).start();
// Set up the territories
final Territory hupeh = territory("Hupeh", gameData);
final Territory kiangsu = territory("Kiangsu", gameData);
// Remove all units
removeFrom(kiangsu, kiangsu.getUnits().getUnits());
removeFrom(hupeh, hupeh.getUnits().getUnits());
// Set up the unit types
addTo(hupeh, infantry(gameData).create(1, british));
// Get units
final Collection<Unit> moveUnits = hupeh.getUnits().getUnits();
// Get Owner prior to battle
final String preOwner = kiangsu.getOwner().getName();
assertEquals(preOwner, Constants.PLAYER_NAME_JAPANESE);
// add a VALID attack
final String validResults = moveDelegate.move(moveUnits, new Route(hupeh, kiangsu));
assertValid(validResults);
// Ensure owner after attack doesn't match attacker
final String postOwner = kiangsu.getOwner().getName();
assertNotSame(postOwner, Constants.PLAYER_NAME_BRITISH);
// Check that original owner is now owner
assertEquals(postOwner, Constants.PLAYER_NAME_CHINESE);
}
@Test
public void testOccupiedTerrOfAttachmentWithCapital() {
// Set up test
final PlayerID british = GameDataTestUtil.british(gameData);
final ITestDelegateBridge delegateBridge = getDelegateBridge(british(gameData));
// Set up the move delegate
final MoveDelegate moveDelegate = moveDelegate(gameData);
delegateBridge.setStepName("CombatMove");
moveDelegate(gameData).setDelegateBridgeAndPlayer(delegateBridge);
moveDelegate(gameData).start();
// Set up the territories
final Territory hupeh = territory("Hupeh", gameData);
final Territory kiangsu = territory("Kiangsu", gameData);
final Territory mongolia = territory("Mongolia", gameData);
// Remove original capital
final TerritoryAttachment taMongolia = TerritoryAttachment.get(mongolia);
final TerritoryAttachment taKiangsu = TerritoryAttachment.get(kiangsu);
try {
final String noVal = null;
taMongolia.setCapital(noVal);
// Set as NEW capital
taKiangsu.setCapital(Constants.PLAYER_NAME_CHINESE);
} catch (final GameParseException e) {
ClientLogger.logError(e);
}
// Remove all units
removeFrom(kiangsu, kiangsu.getUnits().getUnits());
removeFrom(hupeh, hupeh.getUnits().getUnits());
// Set up the unit types
addTo(hupeh, infantry(gameData).create(1, british));
// Get units
final Collection<Unit> moveUnits = hupeh.getUnits().getUnits();
// Get Owner prior to battle
final String preOwner = kiangsu.getOwner().getName();
assertEquals(preOwner, Constants.PLAYER_NAME_JAPANESE);
// add a VALID attack
final String validResults = moveDelegate.move(moveUnits, new Route(hupeh, kiangsu));
assertValid(validResults);
// Ensure owner after attack doesn't match attacker
final String postOwner = kiangsu.getOwner().getName();
assertNotSame(postOwner, Constants.PLAYER_NAME_BRITISH);
// Check that original owner is now owner
assertEquals(postOwner, Constants.PLAYER_NAME_CHINESE);
}
@Test
public void testTwoStepBlitz() {
final ITestDelegateBridge delegateBridge = getDelegateBridge(british(gameData));
// Set up the territories
final Territory libya = territory("Libya", gameData);
final Territory egypt = territory("Egypt", gameData);
final Territory morrocco = territory("Morocco Algeria", gameData);
removeFrom(libya, libya.getUnits().getUnits());
// Set up the move delegate
final MoveDelegate moveDelegate = moveDelegate(gameData);
delegateBridge.setStepName("CombatMove");
moveDelegate.setDelegateBridgeAndPlayer(delegateBridge);
moveDelegate.start();
// blitz in two steps
final Collection<Unit> armour = egypt.getUnits().getMatches(Matches.UnitCanBlitz);
move(armour, new Route(egypt, libya));
assertEquals(libya.getOwner(), british(gameData));
move(armour, new Route(libya, morrocco));
}
/*
* Add Utilities here
*/
private Collection<Unit> getUnits(final IntegerMap<UnitType> units, final PlayerID from) {
final Iterator<UnitType> iter = units.keySet().iterator();
final Collection<Unit> rVal = new ArrayList<>(units.totalValues());
while (iter.hasNext()) {
final UnitType type = iter.next();
rVal.addAll(from.getUnits().getUnits(type, units.getInt(type)));
}
return rVal;
}
/*
* Add assertions here
*/
public void assertValid(final String string) {
assertNull(string, string);
}
public void assertError(final String string) {
assertNotNull(string, string);
}
}