Search in sources :

Example 6 with SOCRoad

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

the class SOCRobotBrain method planAndPlaceInitRoad.

/**
 * Plan and place a road attached to our most recently placed initial settlement,
 * in game states {@link SOCGame#START1B START1B}, {@link SOCGame#START2B START2B}, {@link SOCGame#START3B START3B}.
 * Calls {@link OpeningBuildStrategy#planInitRoad()}.
 *<P>
 * Road choice is based on the best nearby potential settlements, and doesn't
 * directly check {@link SOCPlayer#isPotentialRoad(int) ourPlayerData.isPotentialRoad(edgeCoord)}.
 * If the server rejects our road choice, then {@link #cancelWrongPiecePlacementLocal(SOCPlayingPiece)}
 * will need to know which settlement node we were aiming for,
 * and call {@link SOCPlayer#clearPotentialSettlement(int) ourPlayerData.clearPotentialSettlement(nodeCoord)}.
 * The {@link #lastStartingRoadTowardsNode} field holds this coordinate.
 */
protected void planAndPlaceInitRoad() {
    // TODO handle ships here
    final int roadEdge = openingBuildStrategy.planInitRoad();
    // D.ebugPrintln("!!! PUTTING INIT ROAD !!!");
    pause(500);
    // D.ebugPrintln("Trying to build a road at "+Integer.toHexString(roadEdge));
    lastStartingPieceCoord = roadEdge;
    lastStartingRoadTowardsNode = openingBuildStrategy.getPlannedInitRoadDestinationNode();
    client.putPiece(game, new SOCRoad(ourPlayerData, roadEdge, null));
    pause(1000);
}
Also used : SOCRoad(soc.game.SOCRoad)

Example 7 with SOCRoad

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

the class SOCRobotBrain method cancelWrongPiecePlacement.

/**
 *  We've asked for an illegal piece placement.
 *  Cancel and invalidate this planned piece, make a new plan.
 *  If {@link SOCGame#isSpecialBuilding()}, will set variables to
 *  force the end of our special building turn.
 *  Also handles illegal requests to buy development cards
 *  (piece type -2 in {@link SOCCancelBuildRequest}).
 *<P>
 *  Must update game data by calling {@link SOCGame#setGameState(int)} before calling this method.
 *<P>
 *  This method increments {@link #failedBuildingAttempts},
 *  but won't leave the game if we've failed too many times.
 *  The brain's run loop should make that decision.
 *<UL>
 * <LI> If {@link SOCGame#getGameState()} is {@link SOCGame#PLAY1},
 *   server likely denied us due to resources, not due to building plan
 *   being interrupted by another player's building before our special building phase.
 *   (Could also be due to a bug in the chosen building plan.)
 *   Will clear our building plan so we'll make a new one.
 * <LI> In other gamestates, assumes requested piece placement location was illegal.
 *   Will call {@link #cancelWrongPiecePlacementLocal(SOCPlayingPiece)}
 *   so we don't try again to build there.
 * <LI> Either way, sends a {@link CancelBuildRequest} message to the server.
 *</UL>
 *
 * @param mes  Cancel message from server, including piece type
 */
protected void cancelWrongPiecePlacement(SOCCancelBuildRequest mes) {
    // == -2
    final boolean cancelBuyDevCard = (mes.getPieceType() == SOCPossiblePiece.CARD);
    if (cancelBuyDevCard) {
        waitingForDevCard = false;
    } else {
        whatWeFailedToBuild = whatWeWantToBuild;
        ++failedBuildingAttempts;
    }
    waitingForGameState = false;
    final int gameState = game.getGameState();
    /**
     * if true, server likely denied us due to resources, not due to building plan
     * being interrupted by another player's building before our special building phase.
     * (Could also be due to a bug in the chosen building plan.)
     */
    final boolean gameStateIsPLAY1 = (gameState == SOCGame.PLAY1);
    if (!(gameStateIsPLAY1 || cancelBuyDevCard)) {
        int coord = -1;
        switch(gameState) {
            case SOCGame.START1A:
            case SOCGame.START1B:
            case SOCGame.START2A:
            case SOCGame.START2B:
            case SOCGame.START3A:
            case SOCGame.START3B:
                coord = lastStartingPieceCoord;
                break;
            default:
                if (whatWeWantToBuild != null)
                    coord = whatWeWantToBuild.getCoordinates();
        }
        if (coord != -1) {
            SOCPlayingPiece cancelPiece;
            /**
             * First, invalidate that piece in trackers, so we don't try again to
             * build it. If we treat it like another player's new placement, we
             * can remove any of our planned pieces depending on this one.
             */
            switch(mes.getPieceType()) {
                case SOCPlayingPiece.ROAD:
                    cancelPiece = new SOCRoad(dummyCancelPlayerData, coord, null);
                    break;
                case SOCPlayingPiece.SETTLEMENT:
                    cancelPiece = new SOCSettlement(dummyCancelPlayerData, coord, null);
                    break;
                case SOCPlayingPiece.CITY:
                    cancelPiece = new SOCCity(dummyCancelPlayerData, coord, null);
                    break;
                case SOCPlayingPiece.SHIP:
                    cancelPiece = new SOCShip(dummyCancelPlayerData, coord, null);
                    break;
                default:
                    // To satisfy javac
                    cancelPiece = null;
            }
            cancelWrongPiecePlacementLocal(cancelPiece);
        }
    } else {
        /**
         *  stop trying to build it now, but don't prevent
         *  us from trying later to build it.
         */
        whatWeWantToBuild = null;
        buildingPlan.clear();
    }
    if (gameStateIsPLAY1 || game.isSpecialBuilding()) {
        // Shouldn't have asked to build this piece at this time.
        // End our confusion by ending our current turn. Can re-plan on next turn.
        failedBuildingAttempts = MAX_DENIED_BUILDING_PER_TURN;
        expectPLACING_ROAD = false;
        expectPLACING_SETTLEMENT = false;
        expectPLACING_CITY = false;
        expectPLACING_SHIP = false;
        decidedIfSpecialBuild = true;
        if (!cancelBuyDevCard) {
            // special building, currently in state PLACING_* ;
            // get our resources back, get state PLAY1 or SPECIALBUILD
            waitingForGameState = true;
            expectPLAY1 = true;
            client.cancelBuildRequest(game, mes.getPieceType());
        }
    } else if (gameState <= SOCGame.START3B) {
        switch(gameState) {
            case SOCGame.START1A:
                expectPUTPIECE_FROM_START1A = false;
                expectSTART1A = true;
                break;
            case SOCGame.START1B:
                expectPUTPIECE_FROM_START1B = false;
                expectSTART1B = true;
                break;
            case SOCGame.START2A:
                expectPUTPIECE_FROM_START2A = false;
                expectSTART2A = true;
                break;
            case SOCGame.START2B:
                expectPUTPIECE_FROM_START2B = false;
                expectSTART2B = true;
                break;
            case SOCGame.START3A:
                expectPUTPIECE_FROM_START3A = false;
                expectSTART3A = true;
                break;
            case SOCGame.START3B:
                expectPUTPIECE_FROM_START3B = false;
                expectSTART3B = true;
                break;
        }
    // The run loop will check if failedBuildingAttempts > (2 * MAX_DENIED_BUILDING_PER_TURN).
    // This bot will leave the game there if it can't recover.
    } else {
        expectPLAY1 = true;
        waitingForGameState = true;
        counter = 0;
        client.cancelBuildRequest(game, mes.getPieceType());
    // Now wait for the play1 message, then can re-plan another piece.
    }
}
Also used : SOCSettlement(soc.game.SOCSettlement) SOCCity(soc.game.SOCCity) SOCPlayingPiece(soc.game.SOCPlayingPiece) SOCShip(soc.game.SOCShip) SOCRoad(soc.game.SOCRoad)

Example 8 with SOCRoad

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

the class SOCRobotDM method getWinGameETABonusForRoad.

/**
 * For {@link #SMART_STRATEGY}, add a bonus to the road or ship score
 * based on the change in win game ETA for this one road or ship
 * (possible settlements are 1 road closer, longest road bonus, etc).
 *<UL>
 * <LI> Calls {@link SOCPlayerTracker#tryPutPiece(SOCPlayingPiece, SOCGame, HashMap)}
 *      which makes a copy of the player trackers and puts the piece there.
 *      This also updates our player's VP total, including any special VP from placement.
 * <LI> Calls {@link SOCPlayerTracker#updateWinGameETAs(HashMap)} on that copy
 * <LI> Calls {@link #calcWGETABonus(HashMap, HashMap)} to compare WGETA before and after placement
 * <LI> Calls {@link #getETABonus(int, int, float)} to weigh that bonus
 * <LI> Adds that to {@code posRoad}'s {@link SOCPossiblePiece#getScore()}
 * <LI> Cleans up with {@link SOCPlayerTracker#undoTryPutPiece(SOCPlayingPiece, SOCGame)}
 *</UL>
 *
 * @param posRoad  the possible piece that we're scoring
 * @param roadETA  the ETA for a road or ship, from building speed estimates
 * @param leadersCurrentWGETA  the leaders current WGETA
 * @param playerTrackers  the player trackers (for figuring out road building plan and bonus/ETA)
 */
protected float getWinGameETABonusForRoad(final SOCPossibleRoad posRoad, final int roadETA, final int leadersCurrentWGETA, HashMap<Integer, SOCPlayerTracker> playerTrackers) {
    D.ebugPrintln("--- addWinGameETABonusForRoad");
    int ourCurrentWGETA = ourPlayerTracker.getWinGameETA();
    D.ebugPrintln("ourCurrentWGETA = " + ourCurrentWGETA);
    HashMap<Integer, SOCPlayerTracker> trackersCopy = null;
    SOCRoad tmpRoad1 = null;
    // Building road or ship?  TODO Better ETA calc for coastal road/ship
    final boolean isShip = (posRoad instanceof SOCPossibleShip) && !((SOCPossibleShip) posRoad).isCoastalRoadAndShip;
    final SOCResourceSet rsrcs = (isShip ? SOCShip.COST : SOCRoad.COST);
    D.ebugPrintln("--- before [start] ---");
    SOCResourceSet originalResources = ourPlayerData.getResources().copy();
    SOCBuildingSpeedEstimate estimate = new SOCBuildingSpeedEstimate(ourPlayerData.getNumbers());
    // SOCPlayerTracker.playerTrackersDebug(playerTrackers);
    D.ebugPrintln("--- before [end] ---");
    try {
        SOCResSetBuildTimePair btp = estimate.calculateRollsAndRsrcFast(ourPlayerData.getResources(), rsrcs, 50, ourPlayerData.getPortFlags());
        btp.getResources().subtract(rsrcs);
        ourPlayerData.getResources().setAmounts(btp.getResources());
    } catch (CutoffExceededException e) {
        D.ebugPrintln("crap in getWinGameETABonusForRoad - " + e);
    }
    tmpRoad1 = (isShip) ? new SOCShip(ourPlayerData, posRoad.getCoordinates(), null) : new SOCRoad(ourPlayerData, posRoad.getCoordinates(), null);
    trackersCopy = SOCPlayerTracker.tryPutPiece(tmpRoad1, game, playerTrackers);
    SOCPlayerTracker.updateWinGameETAs(trackersCopy);
    float score = calcWGETABonus(playerTrackers, trackersCopy);
    if (!posRoad.getThreats().isEmpty()) {
        score *= threatMultiplier;
        D.ebugPrintln("***  (THREAT MULTIPLIER) score * " + threatMultiplier + " = " + score);
    }
    D.ebugPrintln("*** ETA for road = " + roadETA);
    float etaBonus = getETABonus(roadETA, leadersCurrentWGETA, score);
    D.ebugPrintln("$$$ score = " + score);
    D.ebugPrintln("etaBonus = " + etaBonus);
    posRoad.addToScore(etaBonus);
    if ((brain != null) && (brain.getDRecorder().isOn())) {
        brain.getDRecorder().record("ETA = " + roadETA);
        brain.getDRecorder().record("WGETA Score = " + df1.format(score));
        brain.getDRecorder().record("Total road score = " + df1.format(etaBonus));
    }
    D.ebugPrintln("--- after [end] ---");
    SOCPlayerTracker.undoTryPutPiece(tmpRoad1, game);
    ourPlayerData.getResources().clear();
    ourPlayerData.getResources().add(originalResources);
    D.ebugPrintln("--- cleanup done ---");
    return etaBonus;
}
Also used : SOCShip(soc.game.SOCShip) SOCRoad(soc.game.SOCRoad) CutoffExceededException(soc.util.CutoffExceededException) SOCResourceSet(soc.game.SOCResourceSet)

Example 9 with SOCRoad

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

the class SOCRobotDM method planRoadBuildingTwoRoads.

/**
 * For {@link #planStuff(int)}, if we have a road building card, make sure we build two roads first.
 * Pick 2 good potential roads, and push them onto {@link #buildingPlan}.
 *<P>
 * Call only when our {@code SOCPlayer}:
 *<UL>
 * <LI> Has 2 more more road pieces left
 * <LI> Has an old {@link SOCDevCardConstants#ROADS} card to play
 * <LI> ! {@link SOCPlayer#hasPlayedDevCard() hasPlayedDevCard()}
 *</UL>
 * @since 2.0.00
 */
private final void planRoadBuildingTwoRoads() {
    SOCPossibleRoad secondFavoriteRoad = null;
    D.ebugPrintln("*** making a plan for road building");
    // /
    if (favoriteRoad != null) {
        // 
        // pretend to put the favorite road down,
        // and then score the new pos roads
        // 
        // TODO for now, coastal roads/ships are always built as roads not ships
        // 
        final SOCRoad tmpRoad;
        if ((favoriteRoad instanceof SOCPossibleShip) && !((SOCPossibleShip) favoriteRoad).isCoastalRoadAndShip)
            tmpRoad = new SOCShip(ourPlayerData, favoriteRoad.getCoordinates(), null);
        else
            tmpRoad = new SOCRoad(ourPlayerData, favoriteRoad.getCoordinates(), null);
        HashMap<Integer, SOCPlayerTracker> trackersCopy = SOCPlayerTracker.tryPutPiece(tmpRoad, game, playerTrackers);
        SOCPlayerTracker.updateWinGameETAs(trackersCopy);
        SOCPlayerTracker ourPlayerTrackerCopy = trackersCopy.get(Integer.valueOf(ourPlayerNumber));
        final int ourCurrentWGETACopy = ourPlayerTrackerCopy.getWinGameETA();
        D.ebugPrintln("ourCurrentWGETACopy = " + ourCurrentWGETACopy);
        int leadersCurrentWGETACopy = ourCurrentWGETACopy;
        Iterator<SOCPlayerTracker> trackersCopyIter = trackersCopy.values().iterator();
        while (trackersCopyIter.hasNext()) {
            SOCPlayerTracker tracker = trackersCopyIter.next();
            int wgeta = tracker.getWinGameETA();
            if (wgeta < leadersCurrentWGETACopy) {
                leadersCurrentWGETACopy = wgeta;
            }
        }
        for (SOCPossiblePiece newPos : favoriteRoad.getNewPossibilities()) {
            if (newPos instanceof SOCPossibleRoad) {
                newPos.resetScore();
                // float wgetaScore = getWinGameETABonusForRoad
                // ((SOCPossibleRoad)newPos, currentBuildingETAs[SOCBuildingSpeedEstimate.ROAD], leadersCurrentWGETACopy, trackersCopy);
                // +" has a score of "+newPos.getScore());
                D.ebugPrintln("$$$ new pos road at " + Integer.toHexString(newPos.getCoordinates()));
                if (favoriteRoad.getCoordinates() != newPos.getCoordinates()) {
                    if (secondFavoriteRoad == null) {
                        secondFavoriteRoad = (SOCPossibleRoad) newPos;
                    } else {
                        if (newPos.getScore() > secondFavoriteRoad.getScore()) {
                            secondFavoriteRoad = (SOCPossibleRoad) newPos;
                        }
                    }
                }
            }
        }
        for (SOCPossibleRoad threatenedRoad : threatenedRoads) {
            D.ebugPrintln("$$$ threatened road at " + Integer.toHexString(threatenedRoad.getCoordinates()));
            // 
            // see how building this piece impacts our winETA
            // 
            threatenedRoad.resetScore();
            // float wgetaScore = getWinGameETABonusForRoad
            // (threatenedRoad, currentBuildingETAs[SOCBuildingSpeedEstimate.ROAD], leadersCurrentWGETA, playerTrackers);
            // +threatenedRoad.getScore());
            D.ebugPrintln("$$$  final score = 0");
            if (favoriteRoad.getCoordinates() != threatenedRoad.getCoordinates()) {
                if (secondFavoriteRoad == null) {
                    secondFavoriteRoad = threatenedRoad;
                } else {
                    if (threatenedRoad.getScore() > secondFavoriteRoad.getScore()) {
                        secondFavoriteRoad = threatenedRoad;
                    }
                }
            }
        }
        for (SOCPossibleRoad goodRoad : goodRoads) {
            D.ebugPrintln("$$$ good road at " + Integer.toHexString(goodRoad.getCoordinates()));
            // 
            // see how building this piece impacts our winETA
            // 
            goodRoad.resetScore();
            // float wgetaScore = getWinGameETABonusForRoad
            // (goodRoad, currentBuildingETAs[SOCBuildingSpeedEstimate.ROAD], leadersCurrentWGETA, playerTrackers);
            // +goodRoad.getScore());
            D.ebugPrintln("$$$  final score = 0");
            if (favoriteRoad.getCoordinates() != goodRoad.getCoordinates()) {
                if (secondFavoriteRoad == null) {
                    secondFavoriteRoad = goodRoad;
                } else {
                    if (goodRoad.getScore() > secondFavoriteRoad.getScore()) {
                        secondFavoriteRoad = goodRoad;
                    }
                }
            }
        }
        SOCPlayerTracker.undoTryPutPiece(tmpRoad, game);
        if (!buildingPlan.empty()) {
            SOCPossiblePiece planPeek = buildingPlan.peek();
            if ((planPeek == null) || (!(planPeek instanceof SOCPossibleRoad))) {
                if (secondFavoriteRoad != null) {
                    D.ebugPrintln("### SECOND FAVORITE ROAD IS AT " + Integer.toHexString(secondFavoriteRoad.getCoordinates()));
                    D.ebugPrintln("###   WITH A SCORE OF " + secondFavoriteRoad.getScore());
                    D.ebugPrintln("$ PUSHING " + secondFavoriteRoad);
                    buildingPlan.push(secondFavoriteRoad);
                    D.ebugPrintln("$ PUSHING " + favoriteRoad);
                    buildingPlan.push(favoriteRoad);
                }
            } else if (secondFavoriteRoad != null) {
                SOCPossiblePiece tmp = buildingPlan.pop();
                D.ebugPrintln("$ POPPED OFF");
                D.ebugPrintln("### SECOND FAVORITE ROAD IS AT " + Integer.toHexString(secondFavoriteRoad.getCoordinates()));
                D.ebugPrintln("###   WITH A SCORE OF " + secondFavoriteRoad.getScore());
                D.ebugPrintln("$ PUSHING " + secondFavoriteRoad);
                buildingPlan.push(secondFavoriteRoad);
                D.ebugPrintln("$ PUSHING " + tmp);
                buildingPlan.push(tmp);
            }
        }
    }
}
Also used : SOCShip(soc.game.SOCShip) SOCRoad(soc.game.SOCRoad)

Example 10 with SOCRoad

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

the class SOCPlayerTracker method updateScenario_SC_PIRI_closestShipToFortress.

/**
 * For scenario {@code _SC_PIRI}, update the player's ship closest to their Fortress.
 * Assumes no ship will ever be west of the fortress (smaller column number).
 * Must be called after adding or removing a ship from our player's {@link SOCPlayer#getRoads()}.
 * @param ship  Ship that was added or removed, or {@code null} to check all ships after removal
 * @param shipAdded  True if {@code ship} was added; false if {@code ship} or any other ship was removed
 *            or if we're updating Closest Ship without adding or removing a ship
 * @throws IllegalArgumentException if {@code shipAdded} is true, but null {@code ship}
 * @since 2.0.00
 */
void updateScenario_SC_PIRI_closestShipToFortress(final SOCShip ship, final boolean shipAdded) throws IllegalArgumentException {
    if (shipAdded && (ship == null))
        throw new IllegalArgumentException();
    if ((scen_SC_PIRI_closestShipToFortress == null) && (ship != null)) {
        if (shipAdded)
            // closest by default
            scen_SC_PIRI_closestShipToFortress = ship;
        // <--- Early return: no other ships to compare ---
        return;
    }
    if (!shipAdded) {
        if ((ship != null) && (scen_SC_PIRI_closestShipToFortress != null) && (ship.getCoordinates() != scen_SC_PIRI_closestShipToFortress.getCoordinates()))
            // <--- Early return: Not the closest ship ---
            return;
    }
    // may be null towards end of game
    final SOCFortress fort = player.getFortress();
    // If fort's null, we can still compare columns, just not rows, of ship coordinates.
    final int fortR = (fort != null) ? (fort.getCoordinates() >> 8) : -1;
    if (shipAdded) {
        final int shipEdge = ship.getCoordinates(), prevShipEdge = scen_SC_PIRI_closestShipToFortress.getCoordinates();
        final int shipR = shipEdge >> 8, shipC = shipEdge & 0xFF, prevR = prevShipEdge >> 8, prevC = prevShipEdge & 0xFF;
        if ((shipC < prevC) || ((shipC == prevC) && (fortR != -1) && (Math.abs(shipR - fortR) < Math.abs(prevR - fortR)))) {
            scen_SC_PIRI_closestShipToFortress = ship;
        }
    } else {
        // A ship has been removed.  We don't know which one.
        // So, check all ships for distance from fortress.
        Enumeration<SOCRoad> roadAndShipEnum = player.getRoads().elements();
        SOCShip closest = null;
        int closeR = -1, closeC = -1;
        while (roadAndShipEnum.hasMoreElements()) {
            final SOCRoad rs = roadAndShipEnum.nextElement();
            if (!(rs instanceof SOCShip))
                continue;
            final int shipEdge = rs.getCoordinates();
            final int shipR = shipEdge >> 8, shipC = shipEdge & 0xFF;
            if ((closest == null) || (shipC < closeC) || ((shipC == closeC) && (fortR != -1) && (Math.abs(shipR - fortR) < Math.abs(closeR - fortR)))) {
                closest = (SOCShip) rs;
                closeR = shipR;
                closeC = shipC;
            }
        }
        // null if no ships
        scen_SC_PIRI_closestShipToFortress = closest;
    }
}
Also used : SOCShip(soc.game.SOCShip) SOCFortress(soc.game.SOCFortress) SOCRoad(soc.game.SOCRoad)

Aggregations

SOCRoad (soc.game.SOCRoad)21 SOCShip (soc.game.SOCShip)17 SOCCity (soc.game.SOCCity)10 SOCSettlement (soc.game.SOCSettlement)10 SOCPlayer (soc.game.SOCPlayer)9 SOCBoard (soc.game.SOCBoard)5 SOCBoardLarge (soc.game.SOCBoardLarge)4 SOCFortress (soc.game.SOCFortress)4 SOCPlayingPiece (soc.game.SOCPlayingPiece)3 ArrayList (java.util.ArrayList)2 SOCResourceSet (soc.game.SOCResourceSet)2 SOCVillage (soc.game.SOCVillage)2 Graphics2D (java.awt.Graphics2D)1 Image (java.awt.Image)1 BufferedImage (java.awt.image.BufferedImage)1 Stack (java.util.Stack)1 CutoffExceededException (soc.util.CutoffExceededException)1