Search in sources :

Example 16 with GameData

use of games.strategy.engine.data.GameData in project triplea by triplea-game.

the class MoveDelegate method removeAirThatCantLand.

private void removeAirThatCantLand() {
    final GameData data = getData();
    final boolean lhtrCarrierProd = AirThatCantLandUtil.isLhtrCarrierProduction(data) || AirThatCantLandUtil.isLandExistingFightersOnNewCarriers(data);
    boolean hasProducedCarriers = false;
    for (final PlayerID p : GameStepPropertiesHelper.getCombinedTurns(data, player)) {
        if (p.getUnits().anyMatch(Matches.unitIsCarrier())) {
            hasProducedCarriers = true;
            break;
        }
    }
    final AirThatCantLandUtil util = new AirThatCantLandUtil(bridge);
    util.removeAirThatCantLand(player, lhtrCarrierProd && hasProducedCarriers);
    // if edit mode has been on, we need to clean up after all players
    for (final PlayerID player : data.getPlayerList()) {
        // Check if player still has units to place
        if (!player.equals(this.player)) {
            util.removeAirThatCantLand(player, ((player.getUnits().anyMatch(Matches.unitIsCarrier()) || hasProducedCarriers) && lhtrCarrierProd));
        }
    }
}
Also used : PlayerID(games.strategy.engine.data.PlayerID) GameData(games.strategy.engine.data.GameData)

Example 17 with GameData

use of games.strategy.engine.data.GameData in project triplea by triplea-game.

the class MoveDelegate method move.

@Override
public String move(final Collection<Unit> units, final Route route, final Collection<Unit> transportsThatCanBeLoaded, final Map<Unit, Collection<Unit>> newDependents) {
    final GameData data = getData();
    // the reason we use this, is if we are in edit mode, we may have a different unit owner than the current player
    final PlayerID player = getUnitsOwner(units);
    final MoveValidationResult result = MoveValidator.validateMove(units, route, player, transportsThatCanBeLoaded, newDependents, GameStepPropertiesHelper.isNonCombatMove(data, false), movesToUndo, data);
    final StringBuilder errorMsg = new StringBuilder(100);
    final int numProblems = result.getTotalWarningCount() - (result.hasError() ? 0 : 1);
    final String numErrorsMsg = numProblems > 0 ? ("; " + numProblems + " " + MyFormatter.pluralize("error", numProblems) + " not shown") : "";
    if (result.hasError()) {
        return errorMsg.append(result.getError()).append(numErrorsMsg).toString();
    }
    if (result.hasDisallowedUnits()) {
        return errorMsg.append(result.getDisallowedUnitWarning(0)).append(numErrorsMsg).toString();
    }
    boolean isKamikaze = false;
    final boolean getKamikazeAir = Properties.getKamikazeAirplanes(data);
    Collection<Unit> kamikazeUnits = new ArrayList<>();
    // confirm kamikaze moves, and remove them from unresolved units
    if (getKamikazeAir || units.stream().anyMatch(Matches.unitIsKamikaze())) {
        kamikazeUnits = result.getUnresolvedUnits(MoveValidator.NOT_ALL_AIR_UNITS_CAN_LAND);
        if (kamikazeUnits.size() > 0 && getRemotePlayer().confirmMoveKamikaze()) {
            for (final Unit unit : kamikazeUnits) {
                if (getKamikazeAir || Matches.unitIsKamikaze().test(unit)) {
                    result.removeUnresolvedUnit(MoveValidator.NOT_ALL_AIR_UNITS_CAN_LAND, unit);
                    isKamikaze = true;
                }
            }
        }
    }
    if (result.hasUnresolvedUnits()) {
        return errorMsg.append(result.getUnresolvedUnitWarning(0)).append(numErrorsMsg).toString();
    }
    // allow user to cancel move if aa guns will fire
    final AAInMoveUtil aaInMoveUtil = new AAInMoveUtil();
    aaInMoveUtil.initialize(bridge);
    final Collection<Territory> aaFiringTerritores = aaInMoveUtil.getTerritoriesWhereAaWillFire(route, units);
    if (!aaFiringTerritores.isEmpty()) {
        if (!getRemotePlayer().confirmMoveInFaceOfAa(aaFiringTerritores)) {
            return null;
        }
    }
    // do the move
    final UndoableMove currentMove = new UndoableMove(units, route);
    final String transcriptText = MyFormatter.unitsToTextNoOwner(units) + " moved from " + route.getStart().getName() + " to " + route.getEnd().getName();
    bridge.getHistoryWriter().startEvent(transcriptText, currentMove.getDescriptionObject());
    if (isKamikaze) {
        bridge.getHistoryWriter().addChildToEvent("This was a kamikaze move, for at least some of the units", kamikazeUnits);
    }
    tempMovePerformer = new MovePerformer();
    tempMovePerformer.initialize(this);
    tempMovePerformer.moveUnits(units, route, player, transportsThatCanBeLoaded, newDependents, currentMove);
    tempMovePerformer = null;
    return null;
}
Also used : PlayerID(games.strategy.engine.data.PlayerID) Territory(games.strategy.engine.data.Territory) GameData(games.strategy.engine.data.GameData) ArrayList(java.util.ArrayList) TripleAUnit(games.strategy.triplea.TripleAUnit) Unit(games.strategy.engine.data.Unit) MoveValidationResult(games.strategy.triplea.delegate.dataObjects.MoveValidationResult)

Example 18 with GameData

use of games.strategy.engine.data.GameData in project triplea by triplea-game.

the class MoveDelegate method repairMultipleHitPointUnits.

static void repairMultipleHitPointUnits(final IDelegateBridge bridge, final PlayerID player) {
    final GameData data = bridge.getData();
    final boolean repairOnlyOwn = Properties.getBattleshipsRepairAtBeginningOfRound(bridge.getData());
    final Predicate<Unit> damagedUnits = Matches.unitHasMoreThanOneHitPointTotal().and(Matches.unitHasTakenSomeDamage());
    final Predicate<Unit> damagedUnitsOwned = damagedUnits.and(Matches.unitIsOwnedBy(player));
    final Map<Territory, Set<Unit>> damagedMap = new HashMap<>();
    for (final Territory current : data.getMap().getTerritories()) {
        final Set<Unit> damaged;
        if (!Properties.getTwoHitPointUnitsRequireRepairFacilities(data)) {
            damaged = new HashSet<>(current.getUnits().getMatches(repairOnlyOwn ? damagedUnitsOwned : damagedUnits));
        } else {
            damaged = new HashSet<>(current.getUnits().getMatches(damagedUnitsOwned.and(Matches.unitCanBeRepairedByFacilitiesInItsTerritory(current, player, data))));
        }
        if (!damaged.isEmpty()) {
            damagedMap.put(current, damaged);
        }
    }
    if (damagedMap.isEmpty()) {
        return;
    }
    final Map<Unit, Territory> fullyRepaired = new HashMap<>();
    final IntegerMap<Unit> newHitsMap = new IntegerMap<>();
    for (final Entry<Territory, Set<Unit>> entry : damagedMap.entrySet()) {
        for (final Unit u : entry.getValue()) {
            final int repairAmount = getLargestRepairRateForThisUnit(u, entry.getKey(), data);
            final int currentHits = u.getHits();
            final int newHits = Math.max(0, Math.min(currentHits, (currentHits - repairAmount)));
            if (newHits != currentHits) {
                newHitsMap.put(u, newHits);
            }
            if (newHits <= 0) {
                fullyRepaired.put(u, entry.getKey());
            }
        }
    }
    bridge.getHistoryWriter().startEvent(newHitsMap.size() + " " + MyFormatter.pluralize("unit", newHitsMap.size()) + " repaired.", new HashSet<>(newHitsMap.keySet()));
    bridge.addChange(ChangeFactory.unitsHit(newHitsMap));
    // now if damaged includes any carriers that are repairing, and have damaged abilities set for not allowing air
    // units to leave while damaged, we need to remove those air units now
    final Collection<Unit> damagedCarriers = CollectionUtils.getMatches(fullyRepaired.keySet(), Matches.unitHasWhenCombatDamagedEffect(UnitAttachment.UNITSMAYNOTLEAVEALLIEDCARRIER));
    // now cycle through those now-repaired carriers, and remove allied air from being dependent
    final CompositeChange clearAlliedAir = new CompositeChange();
    for (final Unit carrier : damagedCarriers) {
        final CompositeChange change = MustFightBattle.clearTransportedByForAlliedAirOnCarrier(Collections.singleton(carrier), fullyRepaired.get(carrier), carrier.getOwner(), data);
        if (!change.isEmpty()) {
            clearAlliedAir.add(change);
        }
    }
    if (!clearAlliedAir.isEmpty()) {
        bridge.addChange(clearAlliedAir);
    }
    // Check if any repaired units change into different unit types
    for (final Territory territory : damagedMap.keySet()) {
        repairedChangeInto(damagedMap.get(territory), territory, bridge);
    }
}
Also used : IntegerMap(games.strategy.util.IntegerMap) Territory(games.strategy.engine.data.Territory) GameData(games.strategy.engine.data.GameData) HashSet(java.util.HashSet) Set(java.util.Set) HashMap(java.util.HashMap) TripleAUnit(games.strategy.triplea.TripleAUnit) Unit(games.strategy.engine.data.Unit) CompositeChange(games.strategy.engine.data.CompositeChange)

Example 19 with GameData

use of games.strategy.engine.data.GameData in project triplea by triplea-game.

the class MovePerformer method populateStack.

/**
 * We assume that the move is valid.
 */
private void populateStack(final Collection<Unit> units, final Route route, final PlayerID id, final Collection<Unit> transportsToLoad) {
    final IExecutable preAaFire = new IExecutable() {

        private static final long serialVersionUID = -7945930782650355037L;

        @Override
        public void execute(final ExecutionStack stack, final IDelegateBridge bridge) {
            // this can happen for air units moving out of a battle zone
            for (final IBattle battle : getBattleTracker().getPendingBattles(route.getStart(), null)) {
                for (final Unit unit : units) {
                    final Route routeUnitUsedToMove = moveDelegate.getRouteUsedToMoveInto(unit, route.getStart());
                    if (battle != null) {
                        battle.removeAttack(routeUnitUsedToMove, Collections.singleton(unit));
                    }
                }
            }
        }
    };
    // hack to allow the executables to share state
    final IExecutable fireAa = new IExecutable() {

        private static final long serialVersionUID = -3780228078499895244L;

        @Override
        public void execute(final ExecutionStack stack, final IDelegateBridge bridge) {
            final Collection<Unit> aaCasualties = fireAa(route, units);
            final Set<Unit> aaCasualtiesWithDependents = new HashSet<>();
            // need to remove any dependents here
            if (aaCasualties != null) {
                aaCasualtiesWithDependents.addAll(aaCasualties);
                final Map<Unit, Collection<Unit>> dependencies = TransportTracker.transporting(units, units);
                for (final Unit u : aaCasualties) {
                    final Collection<Unit> dependents = dependencies.get(u);
                    if (dependents != null) {
                        aaCasualtiesWithDependents.addAll(dependents);
                    }
                    // we might have new dependents too (ie: paratroopers)
                    final Collection<Unit> newDependents = m_newDependents.get(u);
                    if (newDependents != null) {
                        aaCasualtiesWithDependents.addAll(newDependents);
                    }
                }
            }
            arrivingUnits = CollectionUtils.difference(units, aaCasualtiesWithDependents);
        }
    };
    final IExecutable postAaFire = new IExecutable() {

        private static final long serialVersionUID = 670783657414493643L;

        @Override
        public void execute(final ExecutionStack stack, final IDelegateBridge bridge) {
            // if any non enemy territories on route
            // or if any enemy units on route the
            // battles on (note water could have enemy but its
            // not owned)
            final GameData data = bridge.getData();
            final Predicate<Territory> mustFightThrough = getMustFightThroughMatch(id, data);
            final Collection<Unit> arrived = Collections.unmodifiableList(CollectionUtils.intersection(units, arrivingUnits));
            // Reset Optional
            arrivingUnits = new ArrayList<>();
            final Collection<Unit> arrivedCopyForBattles = new ArrayList<>(arrived);
            final Map<Unit, Unit> transporting = TransportUtils.mapTransports(route, arrived, transportsToLoad);
            // If we have paratrooper land units being carried by air units, they should be dropped off in the last
            // territory. This means they
            // are still dependent during the middle steps of the route.
            final Collection<Unit> dependentOnSomethingTilTheEndOfRoute = new ArrayList<>();
            final Collection<Unit> airTransports = CollectionUtils.getMatches(arrived, Matches.unitIsAirTransport());
            final Collection<Unit> paratroops = CollectionUtils.getMatches(arrived, Matches.unitIsAirTransportable());
            if (!airTransports.isEmpty() && !paratroops.isEmpty()) {
                final Map<Unit, Unit> transportingAir = TransportUtils.mapTransportsToLoad(paratroops, airTransports);
                dependentOnSomethingTilTheEndOfRoute.addAll(transportingAir.keySet());
            }
            final Collection<Unit> presentFromStartTilEnd = new ArrayList<>(arrived);
            presentFromStartTilEnd.removeAll(dependentOnSomethingTilTheEndOfRoute);
            final CompositeChange change = new CompositeChange();
            // markFuelCostResourceChange must be done before we load/unload units
            change.add(Route.getFuelChanges(units, route, id, data));
            markTransportsMovement(arrived, transporting, route);
            if (route.anyMatch(mustFightThrough) && arrived.size() != 0) {
                boolean bombing = false;
                boolean ignoreBattle = false;
                // could it be a bombing raid
                final Collection<Unit> enemyUnits = route.getEnd().getUnits().getMatches(Matches.enemyUnit(id, data));
                final Collection<Unit> enemyTargetsTotal = CollectionUtils.getMatches(enemyUnits, Matches.unitCanBeDamaged().and(Matches.unitIsBeingTransported().negate()));
                final boolean canCreateAirBattle = !enemyTargetsTotal.isEmpty() && Properties.getRaidsMayBePreceededByAirBattles(data) && AirBattle.territoryCouldPossiblyHaveAirBattleDefenders(route.getEnd(), id, data, true);
                final Predicate<Unit> allBombingRaid = PredicateBuilder.of(Matches.unitIsStrategicBomber()).orIf(canCreateAirBattle, Matches.unitCanEscort()).build();
                final boolean allCanBomb = !arrived.isEmpty() && arrived.stream().allMatch(allBombingRaid);
                final Collection<Unit> enemyTargets = CollectionUtils.getMatches(enemyTargetsTotal, Matches.unitIsOfTypes(UnitAttachment.getAllowedBombingTargetsIntersection(CollectionUtils.getMatches(arrived, Matches.unitIsStrategicBomber()), data)));
                final boolean targetsOrEscort = !enemyTargets.isEmpty() || (!enemyTargetsTotal.isEmpty() && canCreateAirBattle && !arrived.isEmpty() && arrived.stream().allMatch(Matches.unitCanEscort()));
                boolean targetedAttack = false;
                // if it's all bombers and there's something to bomb
                if (allCanBomb && targetsOrEscort && GameStepPropertiesHelper.isCombatMove(data)) {
                    bombing = getRemotePlayer().shouldBomberBomb(route.getEnd());
                    // if bombing and there's something to target- ask what to bomb
                    if (bombing) {
                        // CompositeMatchOr<Unit> unitsToBeBombed = new CompositeMatchOr<Unit>(Matches.UnitIsFactory,
                        // Matches.UnitCanBeDamagedButIsNotFactory);
                        // determine which unit to bomb
                        final Unit target;
                        if (enemyTargets.size() > 1 && Properties.getDamageFromBombingDoneToUnitsInsteadOfTerritories(data) && !canCreateAirBattle) {
                            target = getRemotePlayer().whatShouldBomberBomb(route.getEnd(), enemyTargets, arrived);
                        } else if (!enemyTargets.isEmpty()) {
                            target = enemyTargets.iterator().next();
                        } else {
                            // in case we are escorts only
                            target = enemyTargetsTotal.iterator().next();
                        }
                        if (target == null) {
                            bombing = false;
                            targetedAttack = false;
                        } else {
                            targetedAttack = true;
                            final HashMap<Unit, HashSet<Unit>> targets = new HashMap<>();
                            targets.put(target, new HashSet<>(arrived));
                            // createdBattle = true;
                            getBattleTracker().addBattle(route, arrivedCopyForBattles, bombing, id, MovePerformer.this.bridge, m_currentMove, dependentOnSomethingTilTheEndOfRoute, targets, false);
                        }
                    }
                }
                // Ignore Trn on Trn forces.
                if (isIgnoreTransportInMovement(bridge.getData())) {
                    final boolean allOwnedTransports = !arrived.isEmpty() && arrived.stream().allMatch(Matches.unitIsTransportButNotCombatTransport());
                    final boolean allEnemyTransports = !enemyUnits.isEmpty() && enemyUnits.stream().allMatch(Matches.unitIsTransportButNotCombatTransport());
                    // If everybody is a transport, don't create a battle
                    if (allOwnedTransports && allEnemyTransports) {
                        ignoreBattle = true;
                    }
                }
                if (!ignoreBattle && GameStepPropertiesHelper.isCombatMove(data) && !targetedAttack) {
                    // createdBattle = true;
                    if (bombing) {
                        getBattleTracker().addBombingBattle(route, arrivedCopyForBattles, id, MovePerformer.this.bridge, m_currentMove, dependentOnSomethingTilTheEndOfRoute);
                    } else {
                        getBattleTracker().addBattle(route, arrivedCopyForBattles, id, MovePerformer.this.bridge, m_currentMove, dependentOnSomethingTilTheEndOfRoute);
                    }
                }
                if (!ignoreBattle && GameStepPropertiesHelper.isNonCombatMove(data, false) && !targetedAttack) {
                    // difficult if we want these recorded in battle records).
                    for (final Territory t : route.getMatches(Matches.territoryIsOwnedByPlayerWhosRelationshipTypeCanTakeOverOwnedTerritoryAndPassableAndNotWater(id).and(Matches.territoryIsBlitzable(id, data)))) {
                        if (Matches.isTerritoryEnemy(id, data).test(t) || Matches.territoryHasEnemyUnits(id, data).test(t)) {
                            continue;
                        }
                        if ((t.equals(route.getEnd()) && !arrivedCopyForBattles.isEmpty() && arrivedCopyForBattles.stream().allMatch(Matches.unitIsAir())) || (!t.equals(route.getEnd()) && !presentFromStartTilEnd.isEmpty() && presentFromStartTilEnd.stream().allMatch(Matches.unitIsAir()))) {
                            continue;
                        }
                        // createdBattle = true;
                        getBattleTracker().takeOver(t, id, bridge, m_currentMove, arrivedCopyForBattles);
                    }
                }
            }
            // mark movement
            final Change moveChange = markMovementChange(arrived, route, id);
            change.add(moveChange);
            // actually move the units
            if (route.getStart() != null && route.getEnd() != null) {
                // ChangeFactory.addUnits(route.getEnd(), arrived);
                final Change remove = ChangeFactory.removeUnits(route.getStart(), units);
                final Change add = ChangeFactory.addUnits(route.getEnd(), arrived);
                change.add(add, remove);
            }
            MovePerformer.this.bridge.addChange(change);
            m_currentMove.addChange(change);
            m_currentMove.setDescription(MyFormatter.unitsToTextNoOwner(arrived) + " moved from " + route.getStart().getName() + " to " + route.getEnd().getName());
            moveDelegate.updateUndoableMoves(m_currentMove);
        }
    };
    m_executionStack.push(postAaFire);
    m_executionStack.push(fireAa);
    m_executionStack.push(preAaFire);
    m_executionStack.execute(bridge);
}
Also used : Territory(games.strategy.engine.data.Territory) GameData(games.strategy.engine.data.GameData) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) CompositeChange(games.strategy.engine.data.CompositeChange) Change(games.strategy.engine.data.Change) TripleAUnit(games.strategy.triplea.TripleAUnit) Unit(games.strategy.engine.data.Unit) Collection(java.util.Collection) CompositeChange(games.strategy.engine.data.CompositeChange) Route(games.strategy.engine.data.Route) IDelegateBridge(games.strategy.engine.delegate.IDelegateBridge) HashSet(java.util.HashSet)

Example 20 with GameData

use of games.strategy.engine.data.GameData in project triplea by triplea-game.

the class PoliticsDelegate method chainAlliancesTogether.

static void chainAlliancesTogether(final IDelegateBridge bridge) {
    final GameData data = bridge.getData();
    if (!Properties.getAlliancesCanChainTogether(data)) {
        return;
    }
    final Collection<RelationshipType> allTypes = data.getRelationshipTypeList().getAllRelationshipTypes();
    RelationshipType alliedType = null;
    RelationshipType warType = null;
    for (final RelationshipType type : allTypes) {
        if (type.getRelationshipTypeAttachment().isDefaultWarPosition()) {
            warType = type;
        } else if (type.getRelationshipTypeAttachment().canAlliancesChainTogether()) {
            alliedType = type;
        }
    }
    if (alliedType == null) {
        return;
    }
    // first do alliances. then, do war (since we don't want to declare war on a potential ally).
    final Collection<PlayerID> players = data.getPlayerList().getPlayers();
    for (final PlayerID p1 : players) {
        final HashSet<PlayerID> p1NewAllies = new HashSet<>();
        final Collection<PlayerID> p1AlliedWith = CollectionUtils.getMatches(players, Matches.isAlliedAndAlliancesCanChainTogether(p1, data));
        for (final PlayerID p2 : p1AlliedWith) {
            p1NewAllies.addAll(CollectionUtils.getMatches(players, Matches.isAlliedAndAlliancesCanChainTogether(p2, data)));
        }
        p1NewAllies.removeAll(p1AlliedWith);
        p1NewAllies.remove(p1);
        for (final PlayerID p3 : p1NewAllies) {
            if (!data.getRelationshipTracker().getRelationshipType(p1, p3).equals(alliedType)) {
                final RelationshipType current = data.getRelationshipTracker().getRelationshipType(p1, p3);
                bridge.addChange(ChangeFactory.relationshipChange(p1, p3, current, alliedType));
                bridge.getHistoryWriter().addChildToEvent(p1.getName() + " and " + p3.getName() + " are joined together in an " + alliedType.getName() + " treaty");
                MoveDelegate.getBattleTracker(data).addRelationshipChangesThisTurn(p1, p3, current, alliedType);
            }
        }
    }
    // now war
    if (warType == null) {
        return;
    }
    for (final PlayerID p1 : players) {
        final HashSet<PlayerID> p1NewWar = new HashSet<>();
        final Collection<PlayerID> p1WarWith = CollectionUtils.getMatches(players, Matches.isAtWar(p1, data));
        final Collection<PlayerID> p1AlliedWith = CollectionUtils.getMatches(players, Matches.isAlliedAndAlliancesCanChainTogether(p1, data));
        for (final PlayerID p2 : p1AlliedWith) {
            p1NewWar.addAll(CollectionUtils.getMatches(players, Matches.isAtWar(p2, data)));
        }
        p1NewWar.removeAll(p1WarWith);
        p1NewWar.remove(p1);
        for (final PlayerID p3 : p1NewWar) {
            if (!data.getRelationshipTracker().getRelationshipType(p1, p3).equals(warType)) {
                final RelationshipType current = data.getRelationshipTracker().getRelationshipType(p1, p3);
                bridge.addChange(ChangeFactory.relationshipChange(p1, p3, current, warType));
                bridge.getHistoryWriter().addChildToEvent(p1.getName() + " and " + p3.getName() + " declare " + warType.getName() + " on each other");
                MoveDelegate.getBattleTracker(data).addRelationshipChangesThisTurn(p1, p3, current, warType);
            }
        }
    }
}
Also used : PlayerID(games.strategy.engine.data.PlayerID) GameData(games.strategy.engine.data.GameData) RelationshipType(games.strategy.engine.data.RelationshipType) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

Aggregations

GameData (games.strategy.engine.data.GameData)204 Unit (games.strategy.engine.data.Unit)100 PlayerID (games.strategy.engine.data.PlayerID)92 Territory (games.strategy.engine.data.Territory)92 ArrayList (java.util.ArrayList)83 TripleAUnit (games.strategy.triplea.TripleAUnit)64 HashSet (java.util.HashSet)50 CompositeChange (games.strategy.engine.data.CompositeChange)40 List (java.util.List)36 HashMap (java.util.HashMap)32 Set (java.util.Set)32 Route (games.strategy.engine.data.Route)31 UnitAttachment (games.strategy.triplea.attachments.UnitAttachment)30 Collection (java.util.Collection)29 UnitType (games.strategy.engine.data.UnitType)26 Change (games.strategy.engine.data.Change)24 Test (org.junit.jupiter.api.Test)23 Resource (games.strategy.engine.data.Resource)22 TestMapGameData (games.strategy.triplea.xml.TestMapGameData)22 Map (java.util.Map)21