Search in sources :

Example 16 with SOCBoard

use of soc.game.SOCBoard in project JSettlers2 by jdmonin.

the class SOCPlayerTracker method addOurNewRoadOrShip.

/**
 * Add one of our roads or ships that has just been built.
 * Look for new adjacent possible settlements.
 * Calls {@link #expandRoadOrShip(SOCPossibleRoad, SOCPlayer, SOCPlayer, HashMap, int)}
 * on newly possible adjacent roads or ships.
 *
 * @param road         the road or ship
 * @param trackers     player trackers for the players
 * @param expandLevel  how far out we should expand roads/ships;
 *                     passed to {@link #expandRoadOrShip(SOCPossibleRoad, SOCPlayer, SOCPlayer, HashMap, int)}
 */
private void addOurNewRoadOrShip(SOCRoad road, HashMap<Integer, SOCPlayerTracker> trackers, int expandLevel) {
    // D.ebugPrintln("$$$ addOurNewRoad : "+road);
    // 
    // see if the new road was a possible road
    // 
    Iterator<SOCPossibleRoad> prIter = possibleRoads.values().iterator();
    while (prIter.hasNext()) {
        SOCPossibleRoad pr = prIter.next();
        // 
        // reset all expanded flags for possible roads
        // 
        pr.resetExpandedFlag();
        if (pr.getCoordinates() == road.getCoordinates()) {
            // 
            // if so, remove it
            // 
            // D.ebugPrintln("$$$ removing "+Integer.toHexString(road.getCoordinates()));
            possibleRoads.remove(Integer.valueOf(pr.getCoordinates()));
            removeFromNecessaryRoads(pr);
            break;
        }
    }
    // D.ebugPrintln("$$$ checking for possible settlements");
    // 
    // see if this road/ship adds any new possible settlements
    // 
    // check adjacent nodes to road for potential settlements
    // 
    final SOCBoard board = game.getBoard();
    Collection<Integer> adjNodeEnum = board.getAdjacentNodesToEdge(road.getCoordinates());
    for (Integer adjNode : adjNodeEnum) {
        if (player.canPlaceSettlement(adjNode.intValue())) {
            // 
            // see if possible settlement is already in the list
            // 
            // D.ebugPrintln("$$$ seeing if "+Integer.toHexString(adjNode.intValue())+" is already in the list");
            SOCPossibleSettlement posSet = possibleSettlements.get(adjNode);
            if (posSet != null) {
                // 
                // if so, clear necessary road list and remove from np lists
                // 
                // D.ebugPrintln("$$$ found it");
                removeFromNecessaryRoads(posSet);
                posSet.getNecessaryRoads().clear();
                posSet.setNumberOfNecessaryRoads(0);
            } else {
                // 
                // else, add new possible settlement
                // 
                // D.ebugPrintln("$$$ adding new possible settlement at "+Integer.toHexString(adjNode.intValue()));
                SOCPossibleSettlement newPosSet = new SOCPossibleSettlement(player, adjNode.intValue(), null);
                newPosSet.setNumberOfNecessaryRoads(0);
                possibleSettlements.put(adjNode, newPosSet);
                updateSettlementConflicts(newPosSet, trackers);
            }
        }
    }
    // D.ebugPrintln("$$$ checking roads adjacent to "+Integer.toHexString(road.getCoordinates()));
    // 
    // see if this road adds any new possible roads
    // 
    ArrayList<SOCPossibleRoad> newPossibleRoads = new ArrayList<SOCPossibleRoad>();
    ArrayList<SOCPossibleRoad> roadsToExpand = new ArrayList<SOCPossibleRoad>();
    // 
    for (Integer adjEdge : board.getAdjacentEdgesToEdge(road.getCoordinates())) {
        final int edge = adjEdge.intValue();
        // D.ebugPrintln("$$$ edge "+Integer.toHexString(adjEdge.intValue())+" is legal:"+player.isPotentialRoad(adjEdge.intValue()));
        // 
        // see if edge is a potential road
        // or ship to continue this route
        // 
        boolean edgeIsPotentialRoute = (road.isRoadNotShip()) ? player.isPotentialRoad(edge) : player.isPotentialShip(edge);
        // If true, this edge transitions
        // between ships <-> roads, at a
        // coastal settlement
        boolean edgeRequiresCoastalSettlement = false;
        if ((!edgeIsPotentialRoute) && game.hasSeaBoard) {
            // Determine if can transition ship <-> road
            // at a coastal settlement
            final int nodeBetween = ((SOCBoardLarge) board).getNodeBetweenAdjacentEdges(road.getCoordinates(), edge);
            if (player.canPlaceSettlement(nodeBetween)) {
                // check opposite type at transition
                edgeIsPotentialRoute = (road.isRoadNotShip()) ? player.isPotentialShip(edge) : player.isPotentialRoad(edge);
                if (edgeIsPotentialRoute)
                    edgeRequiresCoastalSettlement = true;
            }
        }
        if (edgeIsPotentialRoute) {
            // 
            // see if possible road is already in the list
            // 
            SOCPossibleRoad pr = possibleRoads.get(adjEdge);
            if (pr != null) {
                // For now, can't differ along a coastal route.
                if (edgeRequiresCoastalSettlement && (pr.isRoadNotShip() != road.isRoadNotShip())) {
                    // <--- road vs ship mismatch ---
                    continue;
                }
                // D.ebugPrintln("$$$ pr "+Integer.toHexString(pr.getCoordinates())+" already in list");
                if (!pr.getNecessaryRoads().isEmpty()) {
                    // D.ebugPrintln("$$$    clearing nr list");
                    removeFromNecessaryRoads(pr);
                    pr.getNecessaryRoads().clear();
                    pr.setNumberOfNecessaryRoads(0);
                }
                roadsToExpand.add(pr);
                pr.setExpandedFlag();
            } else {
                // 
                // else, add new possible road
                // 
                // D.ebugPrintln("$$$ adding new pr at "+Integer.toHexString(adjEdge.intValue()));
                SOCPossibleRoad newPR;
                // for effort if requires settlement
                final int roadsBetween;
                boolean isRoad = road.isRoadNotShip();
                if (edgeRequiresCoastalSettlement) {
                    isRoad = !isRoad;
                    // roughly account for effort & cost of new settlement
                    roadsBetween = 2;
                } else {
                    roadsBetween = 0;
                }
                // use coastal road/ship type (isCoastalRoadAndShip) only if we can
                // require a coastal settlement to switch from road-only or ship-only
                final boolean isCoastal = edgeRequiresCoastalSettlement && player.isPotentialRoad(edge) && player.isPotentialShip(edge);
                if (isRoad && !isCoastal) {
                    newPR = new SOCPossibleRoad(player, edge, null);
                } else {
                    newPR = new SOCPossibleShip(player, edge, isCoastal, null);
                    System.err.println("L793: " + toString() + ": new PossibleShip(" + isCoastal + ") at 0x" + Integer.toHexString(edge));
                }
                // 0 unless requires settlement
                newPR.setNumberOfNecessaryRoads(roadsBetween);
                newPossibleRoads.add(newPR);
                roadsToExpand.add(newPR);
                newPR.setExpandedFlag();
            }
        }
    }
    // 
    for (SOCPossibleRoad newPR : newPossibleRoads) {
        possibleRoads.put(Integer.valueOf(newPR.getCoordinates()), newPR);
    }
    // 
    // expand possible roads that we've touched or added
    // 
    SOCPlayer dummy = new SOCPlayer(player);
    for (SOCPossibleRoad expandPR : roadsToExpand) {
        expandRoadOrShip(expandPR, player, dummy, trackers, expandLevel);
    }
    dummy.destroyPlayer();
    // 
    if ((road instanceof SOCShip) && game.isGameOptionSet(SOCGameOption.K_SC_PIRI))
        updateScenario_SC_PIRI_closestShipToFortress((SOCShip) road, true);
}
Also used : SOCBoardLarge(soc.game.SOCBoardLarge) SOCBoard(soc.game.SOCBoard) ArrayList(java.util.ArrayList) SOCShip(soc.game.SOCShip) SOCPlayer(soc.game.SOCPlayer)

Aggregations

SOCBoard (soc.game.SOCBoard)16 ArrayList (java.util.ArrayList)6 SOCBoardLarge (soc.game.SOCBoardLarge)6 SOCRoad (soc.game.SOCRoad)5 SOCPlayer (soc.game.SOCPlayer)4 SOCShip (soc.game.SOCShip)4 SOCGame (soc.game.SOCGame)3 List (java.util.List)2 Stack (java.util.Stack)2 Vector (java.util.Vector)2 SOCLRPathData (soc.game.SOCLRPathData)2 TreeMap (java.util.TreeMap)1 SOCCity (soc.game.SOCCity)1 SOCFortress (soc.game.SOCFortress)1 SOCPlayerNumbers (soc.game.SOCPlayerNumbers)1 SOCPlayingPiece (soc.game.SOCPlayingPiece)1 SOCSettlement (soc.game.SOCSettlement)1 NodeLenVis (soc.util.NodeLenVis)1 Pair (soc.util.Pair)1