Search in sources :

Example 6 with SOCBoard

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

the class SOCPlayerTracker method addOurNewSettlement.

/**
 * Add one of our settlements, and newly possible pieces from it.
 * Adds a new possible city; removes conflicting possible settlements (ours or other players).
 * On the large Sea board, if this is a coastal settlement adds newly possible ships, and if
 * we've just settled a new island, newly possible roads, because the coastal settlement is
 * a roads {@literal <->} ships transition.
 *<P>
 * Newly possible roads or ships next to the settlement are expanded by calling
 * {@link #expandRoadOrShip(SOCPossibleRoad, SOCPlayer, SOCPlayer, HashMap, int)}.
 * {@link #EXPAND_LEVEL} is the basic expansion length, and ships add
 * {@link #EXPAND_LEVEL_SHIP_EXTRA} to that for crossing the sea to nearby islands.
 *<P>
 * Called in 2 different conditions:
 *<UL>
 * <LI> To track an actual (not possible) settlement that's just been placed
 * <LI> To see the effects of trying to placing a possible settlement, in a copy of the PlayerTracker
 *      ({@link #tryPutPiece(SOCPlayingPiece, SOCGame, HashMap)})
 *</UL>
 *
 * @param settlement  the new settlement
 * @param trackers    player trackers for all of the players
 */
public synchronized void addOurNewSettlement(SOCSettlement settlement, HashMap<Integer, SOCPlayerTracker> trackers) {
    // D.ebugPrintln();
    D.ebugPrintln("$$$ addOurNewSettlement : " + settlement);
    SOCBoard board = game.getBoard();
    final Integer settlementCoords = Integer.valueOf(settlement.getCoordinates());
    /**
     * add a new possible city
     */
    possibleCities.put(settlementCoords, new SOCPossibleCity(player, settlement.getCoordinates()));
    /**
     * see if the new settlement was a possible settlement in
     * the list.  if so, remove it.
     */
    SOCPossibleSettlement ps = possibleSettlements.get(settlementCoords);
    if (ps != null) {
        D.ebugPrintln("$$$ was a possible settlement");
        /**
         * copy a list of all the conflicting settlements
         */
        List<SOCPossibleSettlement> conflicts = new ArrayList<SOCPossibleSettlement>(ps.getConflicts());
        /**
         * remove the possible settlement that is now a real settlement
         */
        D.ebugPrintln("$$$ removing " + Integer.toHexString(settlement.getCoordinates()));
        possibleSettlements.remove(settlementCoords);
        removeFromNecessaryRoads(ps);
        /**
         * remove possible settlements that this one cancels out
         */
        for (SOCPossibleSettlement conflict : conflicts) {
            D.ebugPrintln("$$$ checking conflict with " + conflict.getPlayer().getPlayerNumber() + ":" + Integer.toHexString(conflict.getCoordinates()));
            SOCPlayerTracker tracker = trackers.get(Integer.valueOf(conflict.getPlayer().getPlayerNumber()));
            if (tracker != null) {
                D.ebugPrintln("$$$ removing " + Integer.toHexString(conflict.getCoordinates()));
                tracker.getPossibleSettlements().remove(Integer.valueOf(conflict.getCoordinates()));
                removeFromNecessaryRoads(conflict);
                /**
                 * remove the conflicts that this settlement made
                 */
                for (SOCPossibleSettlement otherConflict : conflict.getConflicts()) {
                    D.ebugPrintln("$$$ removing conflict " + Integer.toHexString(conflict.getCoordinates()) + " from " + Integer.toHexString(otherConflict.getCoordinates()));
                    otherConflict.removeConflict(conflict);
                }
            }
        }
    } else {
        /**
         * if the new settlement wasn't a possible settlement,
         * we still need to cancel out other players possible settlements
         */
        D.ebugPrintln("$$$ wasn't possible settlement");
        ArrayList<SOCPossibleSettlement> trash = new ArrayList<SOCPossibleSettlement>();
        List<Integer> adjNodes = board.getAdjacentNodesToNode(settlement.getCoordinates());
        Iterator<SOCPlayerTracker> trackersIter = trackers.values().iterator();
        while (trackersIter.hasNext()) {
            SOCPlayerTracker tracker = trackersIter.next();
            SOCPossibleSettlement posSet = tracker.getPossibleSettlements().get(settlementCoords);
            D.ebugPrintln("$$$ tracker for player " + tracker.getPlayer().getPlayerNumber());
            /**
             * check the node that the settlement is on
             */
            D.ebugPrintln("$$$ checking node " + Integer.toHexString(settlement.getCoordinates()));
            if (posSet != null) {
                D.ebugPrintln("$$$ trashing " + Integer.toHexString(posSet.getCoordinates()));
                trash.add(posSet);
                /**
                 * remove the conflicts that this settlement made
                 */
                for (SOCPossibleSettlement conflict : posSet.getConflicts()) {
                    D.ebugPrintln("$$$ removing conflict " + Integer.toHexString(posSet.getCoordinates()) + " from " + Integer.toHexString(conflict.getCoordinates()));
                    conflict.removeConflict(posSet);
                }
            }
            /**
             * check adjacent nodes
             */
            for (Integer adjNode : adjNodes) {
                D.ebugPrintln("$$$ checking node " + Integer.toHexString(adjNode.intValue()));
                posSet = tracker.getPossibleSettlements().get(adjNode);
                if (posSet != null) {
                    D.ebugPrintln("$$$ trashing " + Integer.toHexString(posSet.getCoordinates()));
                    trash.add(posSet);
                    /**
                     * remove the conflicts that this settlement made
                     */
                    for (SOCPossibleSettlement conflict : posSet.getConflicts()) {
                        D.ebugPrintln("$$$ removing conflict " + Integer.toHexString(posSet.getCoordinates()) + " from " + Integer.toHexString(conflict.getCoordinates()));
                        conflict.removeConflict(posSet);
                    }
                }
            }
            /**
             * take out the trash
             * (no-longer-possible settlements, roads that support it)
             */
            D.ebugPrintln("$$$ removing trash for " + tracker.getPlayer().getPlayerNumber());
            for (SOCPossibleSettlement pset : trash) {
                D.ebugPrintln("$$$ removing " + Integer.toHexString(pset.getCoordinates()) + " owned by " + pset.getPlayer().getPlayerNumber());
                tracker.getPossibleSettlements().remove(Integer.valueOf(pset.getCoordinates()));
                removeFromNecessaryRoads(pset);
            }
            trash.clear();
        }
    }
    /**
     * Add possible road-ship transitions made possible by the new settlement.
     * Normally a new settlement placement doesn't need to add possible roads or ships,
     * because each road/ship placement adds possibles past the new far end of the route
     * in addOurNewRoadOrShip.
     */
    if (board instanceof SOCBoardLarge) {
        ArrayList<SOCPossibleRoad> roadsToExpand = null;
        /**
         * Only add new possible roads if we're on a new island
         * (that is, the newly placed settlement has no adjacent roads already).
         * Coastal ships/roads may still be added even if settleAlreadyHasRoad.
         */
        boolean settleAlreadyHasRoad = false;
        ArrayList<SOCPossibleRoad> possibleNewIslandRoads = null;
        final List<Integer> adjacEdges = board.getAdjacentEdgesToNode(settlementCoords);
        // First, loop to check for settleAlreadyHasRoad
        for (Integer edge : adjacEdges) {
            if (possibleRoads.get(edge) != null)
                // already a possible road or ship here
                continue;
            SOCRoad road = board.roadAtEdge(edge);
            if ((road != null) && road.isRoadNotShip()) {
                settleAlreadyHasRoad = true;
                break;
            }
        }
        // Now, possibly add new roads/ships/coastals
        for (Integer edge : adjacEdges) {
            // TODO remove these debug prints soon
            // System.err.println("L1348: examine edge 0x"
            // + Integer.toHexString(edge) + " for placed settle 0x"
            // + Integer.toHexString(settlementCoords));
            SOCPossibleRoad pRoad = possibleRoads.get(edge);
            if (pRoad != null) {
                // already a possible road or ship
                continue;
            }
            if (board.roadAtEdge(edge) != null) {
                // not new, something's already there
                continue;
            }
            if (player.isPotentialRoad(edge)) {
                // Add newly possible roads from settlement placement.
                // Probably won't need to happen (usually added in addOurNewRoadOrShip, see newPossibleRoads)
                // but could on a new island's first settlement
                final boolean isCoastline = player.isPotentialShip(edge);
                if (settleAlreadyHasRoad && !isCoastline)
                    continue;
                if (possibleNewIslandRoads == null)
                    possibleNewIslandRoads = new ArrayList<SOCPossibleRoad>();
                possibleNewIslandRoads.add((isCoastline) ? new SOCPossibleShip(player, edge, true, null) : new SOCPossibleRoad(player, edge, null));
                if (isCoastline)
                    System.err.println("L1675: " + toString() + ": new PossibleShip(true) at 0x" + Integer.toHexString(edge));
            } else if (player.isPotentialShip(edge)) {
                // A way out to a new island
                SOCPossibleShip newPS = new SOCPossibleShip(player, edge, false, null);
                possibleRoads.put(edge, newPS);
                System.err.println("L1685: " + toString() + ": new PossibleShip(false) at 0x" + Integer.toHexString(edge) + " from coastal settle 0x" + Integer.toHexString(settlementCoords));
                if (roadsToExpand == null)
                    roadsToExpand = new ArrayList<SOCPossibleRoad>();
                roadsToExpand.add(newPS);
                newPS.setExpandedFlag();
            }
        }
        if ((possibleNewIslandRoads != null) && !game.isInitialPlacement()) {
            // (Make sure this isn't initial placement, where nothing has adjacent roads)
            for (SOCPossibleRoad pr : possibleNewIslandRoads) {
                possibleRoads.put(Integer.valueOf(pr.getCoordinates()), pr);
                System.err.println("L1396: new possible road at edge 0x" + Integer.toHexString(pr.getCoordinates()) + " from coastal settle 0x" + Integer.toHexString(settlementCoords));
                if (roadsToExpand == null)
                    roadsToExpand = new ArrayList<SOCPossibleRoad>();
                roadsToExpand.add(pr);
                pr.setExpandedFlag();
            }
        }
        if (roadsToExpand != null) {
            // 
            // expand possible ships/roads that we've added
            // 
            SOCPlayer dummy = new SOCPlayer(player);
            for (SOCPossibleRoad expandPR : roadsToExpand) {
                final int expand = EXPAND_LEVEL + (expandPR.isRoadNotShip() ? 0 : EXPAND_LEVEL_SHIP_EXTRA);
                expandRoadOrShip(expandPR, player, dummy, trackers, expand);
            }
            dummy.destroyPlayer();
        }
    }
}
Also used : SOCBoardLarge(soc.game.SOCBoardLarge) SOCBoard(soc.game.SOCBoard) ArrayList(java.util.ArrayList) SOCRoad(soc.game.SOCRoad) SOCPlayer(soc.game.SOCPlayer)

Example 7 with SOCBoard

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

the class SOCDisplaylessPlayerClient method handleSIMPLEACTION.

/**
 * Update any game data from "simple action" announcements from the server.
 * Currently ignores them except for:
 *<UL>
 * <LI> {@link SOCSimpleAction#TRADE_PORT_REMOVED TRADE_PORT_REMOVED}:
 *     Calls {@link SOCGame#removePort(SOCPlayer, int)}
 *</UL>
 *
 * @param games  Games the client is playing, for method reuse by SOCPlayerClient
 * @param mes  the message
 * @since 1.1.19
 */
public static void handleSIMPLEACTION(final Map<String, SOCGame> games, final SOCSimpleAction mes) {
    final String gaName = mes.getGame();
    SOCGame ga = games.get(gaName);
    if (ga == null)
        // Not one of our games
        return;
    final int atype = mes.getActionType();
    switch(atype) {
        case SOCSimpleAction.BOARD_EDGE_SET_SPECIAL:
            {
                final SOCBoard bd = ga.getBoard();
                if (bd instanceof SOCBoardLarge)
                    ((SOCBoardLarge) bd).setSpecialEdge(mes.getValue1(), mes.getValue2());
            }
            break;
        case SOCSimpleAction.TRADE_PORT_REMOVED:
            if (ga.hasSeaBoard)
                ga.removePort(null, mes.getValue1());
            break;
        case SOCSimpleAction.DEVCARD_BOUGHT:
        case SOCSimpleAction.RSRC_TYPE_MONOPOLIZED:
        case SOCSimpleAction.SC_PIRI_FORT_ATTACK_RESULT:
            // game data updates are sent in preceding or following messages, can ignore this one
            break;
        default:
            // ignore unknown types
            // Since the bots and server are almost always the same version, this
            // shouldn't often occur: print for debugging.
            System.err.println("handleSIMPLEACTION: Unknown type ignored: " + atype + " in game " + gaName);
    }
}
Also used : SOCBoardLarge(soc.game.SOCBoardLarge) SOCBoard(soc.game.SOCBoard) SOCGame(soc.game.SOCGame)

Example 8 with SOCBoard

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

the class SOCDisplaylessPlayerClient method handleBOARDLAYOUT.

/**
 * handle the "board layout" message
 * @param mes  the message
 */
protected void handleBOARDLAYOUT(SOCBoardLayout mes) {
    SOCGame ga = games.get(mes.getGame());
    if (ga != null) {
        // BOARDLAYOUT is always the v1 board encoding (oldest format)
        SOCBoard bd = ga.getBoard();
        bd.setHexLayout(mes.getHexLayout());
        bd.setNumberLayout(mes.getNumberLayout());
        bd.setRobberHex(mes.getRobberHex(), false);
        ga.updateAtBoardLayout();
    }
}
Also used : SOCBoard(soc.game.SOCBoard) SOCGame(soc.game.SOCGame)

Example 9 with SOCBoard

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

the class SOCRobotDM method scenarioGameStrategyPlan_SC_PIRI_buildNextShip.

/**
 * If possible, calculate where our next ship would be placed, and add it to {@link #buildingPlan}.
 * Assumes our player's {@link SOCPlayer#getFortress()} is west of all boats we've already placed.
 * If our line of ships has reached the fortress per {@link SOCPlayer#getMostRecentShip()},
 * nothing to do: That goal is complete.
 * @return True if next ship is possible and was added to {@link #buildingPlan}
 * @since 2.0.00
 */
private final boolean scenarioGameStrategyPlan_SC_PIRI_buildNextShip() {
    SOCShip prevShip = ourPlayerData.getMostRecentShip();
    if (prevShip == null)
        // player starts with 1 ship, so should never be null
        return false;
    final int fortressNode;
    {
        final SOCFortress fo = ourPlayerData.getFortress();
        if (fo == null)
            // already defeated it
            return false;
        fortressNode = fo.getCoordinates();
    }
    final int prevShipNode;
    {
        final int[] nodes = prevShip.getAdjacentNodes();
        final int c0 = nodes[0] & 0xFF, c1 = nodes[1] & 0xFF;
        if (c0 < c1)
            prevShipNode = nodes[0];
        else if (c1 < c0)
            prevShipNode = nodes[1];
        else {
            // prevShip goes north-south; check its node rows vs fortress row
            final int r0 = nodes[0] >> 8, r1 = nodes[1] >> 8, rFort = fortressNode >> 8;
            if (Math.abs(rFort - r0) < Math.abs(rFort - r1))
                prevShipNode = nodes[0];
            else
                prevShipNode = nodes[1];
        }
    }
    if (prevShipNode == fortressNode) {
        return false;
    }
    // Get the player's ship path towards fortressNode from prevShip.
    // We need to head west, possibly north or south.
    final HashSet<Integer> lse = ourPlayerData.getRestrictedLegalShips();
    if (lse == null)
        // null lse should not occur in _SC_PIRI
        return false;
    // Need 1 or 2 edges that are in lse and aren't prevShipEdge,
    // and the edge's far node is either further west than prevShipNode,
    // or is vertical and takes us closer north or south to the fortress.
    int edge1 = -9, edge2 = -9;
    final SOCBoard board = game.getBoard();
    final int prevShipEdge = prevShip.getCoordinates();
    int[] nextPossiEdges = board.getAdjacentEdgesToNode_arr(prevShipNode);
    for (int i = 0; i < nextPossiEdges.length; ++i) {
        final int edge = nextPossiEdges[i];
        if ((edge == -9) || (edge == prevShipEdge) || !lse.contains(Integer.valueOf(edge)))
            continue;
        // be sure this edge takes us towards fortressNode
        final int farNode = board.getAdjacentNodeFarEndOfEdge(edge, prevShipNode);
        final int cShip = prevShipNode & 0xFF, cEdge = farNode & 0xFF;
        if (cEdge > cShip) {
            // farNode is east, not west
            continue;
        } else if (cEdge == cShip) {
            final int rShip = prevShipNode >> 8, rEdge = farNode >> 8, rFort = fortressNode >> 8;
            if (Math.abs(rFort - rEdge) > Math.abs(rFort - rShip))
                // farNode isn't closer to fortress
                continue;
        }
        // OK
        if (edge1 == -9)
            edge1 = edge;
        else
            edge2 = edge;
    }
    if (edge1 == -9)
        // happens if we've built ships out to fortressNode already
        return false;
    final int newEdge;
    if ((edge2 == -9) || (Math.random() < 0.5))
        newEdge = edge1;
    else
        newEdge = edge2;
    buildingPlan.add(new SOCPossibleShip(ourPlayerData, newEdge, false, null));
    System.err.println("L2112 ** " + ourPlayerData.getName() + ": Planned possible ship at 0x" + Integer.toHexString(newEdge) + " towards fortress");
    return true;
}
Also used : SOCBoard(soc.game.SOCBoard) SOCShip(soc.game.SOCShip) SOCFortress(soc.game.SOCFortress)

Example 10 with SOCBoard

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

the class SOCRobotDM method scorePossibleSettlements.

/**
 * Score possible settlements for for the smart game strategy ({@link #SMART_STRATEGY}),
 * from {@link #ourPlayerTracker}{@link SOCPlayerTracker#getPossibleSettlements() .getPossibleSettlements()}
 * into {@link #threatenedSettlements} and {@link #goodSettlements};
 * calculate those settlements' {@link SOCPossiblePiece#getScore()}s.
 * Ignores possible settlements that require roads or ships.
 *
 * @see #scoreSettlementsForDumb(int, SOCBuildingSpeedEstimate)
 */
protected void scorePossibleSettlements(final int settlementETA, final int leadersCurrentWGETA) {
    D.ebugPrintln("****** scorePossibleSettlements");
    // int ourCurrentWGETA = ourPlayerTracker.getWinGameETA();
    /*
    boolean goingToPlayRB = false;
    if (! ourPlayerData.hasPlayedDevCard() &&
	ourPlayerData.getNumPieces(SOCPlayingPiece.ROAD) >= 2 &&
	ourPlayerData.getInventory().getAmount(SOCInventory.OLD, SOCDevCardConstants.ROADS) > 0) {
      goingToPlayRB = true;
    }
    */
    Iterator<SOCPossibleSettlement> posSetsIter = ourPlayerTracker.getPossibleSettlements().values().iterator();
    while (posSetsIter.hasNext()) {
        SOCPossibleSettlement posSet = posSetsIter.next();
        D.ebugPrintln("*** scoring possible settlement at " + Integer.toHexString(posSet.getCoordinates()));
        if (!threatenedSettlements.contains(posSet)) {
            threatenedSettlements.add(posSet);
        } else if (!goodSettlements.contains(posSet)) {
            goodSettlements.add(posSet);
        }
        // 
        if (posSet.getNecessaryRoads().isEmpty()) {
            D.ebugPrintln("*** no roads needed");
            // 
            // no roads needed
            // 
            // 
            // get wgeta score
            // 
            SOCBoard board = game.getBoard();
            SOCSettlement tmpSet = new SOCSettlement(ourPlayerData, posSet.getCoordinates(), board);
            if ((brain != null) && (brain.getDRecorder().isOn())) {
                brain.getDRecorder().startRecording("SETTLEMENT" + posSet.getCoordinates());
                brain.getDRecorder().record("Estimate value of settlement at " + board.nodeCoordToString(posSet.getCoordinates()));
            }
            HashMap<Integer, SOCPlayerTracker> trackersCopy = SOCPlayerTracker.tryPutPiece(tmpSet, game, playerTrackers);
            SOCPlayerTracker.updateWinGameETAs(trackersCopy);
            float wgetaScore = calcWGETABonus(playerTrackers, trackersCopy);
            D.ebugPrintln("***  wgetaScore = " + wgetaScore);
            D.ebugPrintln("*** ETA for settlement = " + settlementETA);
            if ((brain != null) && (brain.getDRecorder().isOn())) {
                brain.getDRecorder().record("ETA = " + settlementETA);
            }
            float etaBonus = getETABonus(settlementETA, leadersCurrentWGETA, wgetaScore);
            D.ebugPrintln("etaBonus = " + etaBonus);
            // posSet.addToScore(wgetaScore);
            posSet.addToScore(etaBonus);
            if ((brain != null) && (brain.getDRecorder().isOn())) {
                brain.getDRecorder().record("WGETA score = " + df1.format(wgetaScore));
                brain.getDRecorder().record("Total settlement score = " + df1.format(etaBonus));
                brain.getDRecorder().stopRecording();
            }
            SOCPlayerTracker.undoTryPutPiece(tmpSet, game);
        }
    }
}
Also used : SOCSettlement(soc.game.SOCSettlement) SOCBoard(soc.game.SOCBoard)

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