Search in sources :

Example 6 with SOCCity

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

the class SOCRobotDM method smartGameStrategy.

/**
 * Plan building for the smart game strategy ({@link #SMART_STRATEGY}).
 * use player trackers' Win Game ETAs (WGETA) to determine best move
 * and update {@link #buildingPlan}.
 *<P>
 * For example, if {@link #favoriteSettlement} is chosen,
 * it's chosen from {@link #goodSettlements} or {@link #threatenedSettlements}.
 *<P>
 * Some scenarios require special moves or certain actions to win the game.  If we're playing in
 * such a scenario, after calculating {@link #favoriteSettlement}, {@link #favoriteCity}, etc, calls
 * {@link #scenarioGameStrategyPlan(float, float, boolean, boolean, SOCBuildingSpeedEstimate, int, boolean)}.
 * See that method for the list of scenarios which need such planning.
 *
 *<H4>Outline:</H4>
 *<UL>
 * <LI> Determine our Win Game ETA, leading player's WGETA
 * <LI> {@link #scorePossibleSettlements(int, int) scorePossibleSettlements(BuildETAs, leaderWGETA)}:
 *      For each settlement we can build now (no roads/ships needed), add its ETA bonus to its score
 * <LI> Build {@link #goodRoads} from possibleRoads' roads & ships we can build now
 * <LI> Pick a {@link #favoriteSettlement} from threatened/good settlements, with the highest
 *      {@link SOCPossiblePiece#getScore() getScore()}  (ETA bonus)
 * <LI> Pick a {@link #favoriteRoad} from threatened/good, with highest getWinGameETABonusForRoad
 * <LI> Pick a {@link #favoriteCity} from our possibleCities, with highest score (ETA bonus)
 * <LI> If {@code favoriteCity} has the best score (best ETA if tied), choose to build the city
 * <LI> Otherwise choose {@code favoriteRoad} or {@code favoriteSettlement} based on their scores
 * <LI> If buying a dev card scores higher than the chosen piece, choose to buy one instead of building
 * <LI> Check for and calc any scenario-specific {@code buildingPlan}
 *</UL>
 *
 * @param buildingETAs  the ETAs for building each piece type
 * @see #dumbFastGameStrategy(int[])
 */
protected void smartGameStrategy(final int[] buildingETAs) {
    D.ebugPrintln("***** smartGameStrategy *****");
    // If this game is on the 6-player board, check whether we're planning for
    // the Special Building Phase.  Can't buy cards or trade in that phase.
    final boolean forSpecialBuildingPhase = game.isSpecialBuilding() || (game.getCurrentPlayerNumber() != ourPlayerNumber);
    // 
    // save the lr paths list to restore later
    // 
    @SuppressWarnings("unchecked") List<SOCLRPathData>[] savedLRPaths = new List[game.maxPlayers];
    for (int pn = 0; pn < game.maxPlayers; pn++) {
        savedLRPaths[pn] = new ArrayList<SOCLRPathData>();
        savedLRPaths[pn].addAll(game.getPlayer(pn).getLRPaths());
    }
    int ourCurrentWGETA = ourPlayerTracker.getWinGameETA();
    D.ebugPrintln("ourCurrentWGETA = " + ourCurrentWGETA);
    int leadersCurrentWGETA = ourCurrentWGETA;
    Iterator<SOCPlayerTracker> trackersIter = playerTrackers.values().iterator();
    while (trackersIter.hasNext()) {
        SOCPlayerTracker tracker = trackersIter.next();
        int wgeta = tracker.getWinGameETA();
        if (wgeta < leadersCurrentWGETA) {
            leadersCurrentWGETA = wgeta;
        }
    }
    // /
    if (ourPlayerData.getNumPieces(SOCPlayingPiece.SETTLEMENT) > 0) {
        scorePossibleSettlements(buildingETAs[SOCBuildingSpeedEstimate.SETTLEMENT], leadersCurrentWGETA);
    }
    // /
    if (ourPlayerData.getNumPieces(SOCPlayingPiece.ROAD) > 0) {
        Iterator<SOCPossibleRoad> posRoadsIter = ourPlayerTracker.getPossibleRoads().values().iterator();
        while (posRoadsIter.hasNext()) {
            SOCPossibleRoad posRoad = posRoadsIter.next();
            if (!posRoad.isRoadNotShip())
                // ignore ships in this loop, ships have other conditions to check
                continue;
            if ((posRoad.getNecessaryRoads().isEmpty()) && (!threatenedRoads.contains(posRoad)) && (!goodRoads.contains(posRoad))) {
                goodRoads.add(posRoad);
            }
        }
    }
    // /
    if (ourPlayerData.getNumPieces(SOCPlayingPiece.SHIP) > 0) {
        final SOCBoard board = game.getBoard();
        final int pirateHex = (board instanceof SOCBoardLarge) ? ((SOCBoardLarge) board).getPirateHex() : 0;
        final int[] pirateEdges = (pirateHex != 0) ? ((SOCBoardLarge) board).getAdjacentEdgesToHex_arr(pirateHex) : null;
        Iterator<SOCPossibleRoad> posRoadsIter = ourPlayerTracker.getPossibleRoads().values().iterator();
        while (posRoadsIter.hasNext()) {
            final SOCPossibleRoad posRoad = posRoadsIter.next();
            if (posRoad.isRoadNotShip())
                // ignore roads in this loop, we want ships
                continue;
            if (posRoad.getNecessaryRoads().isEmpty() && (!threatenedRoads.contains(posRoad)) && (!goodRoads.contains(posRoad))) {
                boolean edgeOK = true;
                if (pirateEdges != null) {
                    final int edge = posRoad.getCoordinates();
                    for (int i = 0; i < pirateEdges.length; ++i) {
                        if (edge == pirateEdges[i]) {
                            edgeOK = false;
                            break;
                        }
                    }
                }
                if (edgeOK)
                    goodRoads.add(posRoad);
            }
        }
    }
    /*
    ///
    /// check everything
    ///
    Enumeration threatenedSetEnum = threatenedSettlements.elements();
    while (threatenedSetEnum.hasMoreElements()) {
      SOCPossibleSettlement threatenedSet = (SOCPossibleSettlement)threatenedSetEnum.nextElement();
      D.ebugPrintln("*** threatened settlement at "+Integer.toHexString(threatenedSet.getCoordinates())+" has a score of "+threatenedSet.getScore());
      if (threatenedSet.getNecessaryRoads().isEmpty() &&
	  ! ourPlayerData.isPotentialSettlement(threatenedSet.getCoordinates())) {
	D.ebugPrintln("POTENTIAL SETTLEMENT ERROR");
	//System.exit(0);
      }
    }
    Enumeration goodSetEnum = goodSettlements.elements();
    while (goodSetEnum.hasMoreElements()) {
      SOCPossibleSettlement goodSet = (SOCPossibleSettlement)goodSetEnum.nextElement();
      D.ebugPrintln("*** good settlement at "+Integer.toHexString(goodSet.getCoordinates())+" has a score of "+goodSet.getScore());
      if (goodSet.getNecessaryRoads().isEmpty() &&
	  ! ourPlayerData.isPotentialSettlement(goodSet.getCoordinates())) {
	D.ebugPrintln("POTENTIAL SETTLEMENT ERROR");
	//System.exit(0);
      }
    }
    Enumeration threatenedRoadEnum = threatenedRoads.elements();
    while (threatenedRoadEnum.hasMoreElements()) {
      SOCPossibleRoad threatenedRoad = (SOCPossibleRoad)threatenedRoadEnum.nextElement();
      D.ebugPrintln("*** threatened road at "+Integer.toHexString(threatenedRoad.getCoordinates())+" has a score of "+threatenedRoad.getScore());
      if (threatenedRoad.getNecessaryRoads().isEmpty() &&
	  ! ourPlayerData.isPotentialRoad(threatenedRoad.getCoordinates())) {
	D.ebugPrintln("POTENTIAL ROAD ERROR");
	//System.exit(0);
      }
    }
    Enumeration goodRoadEnum = goodRoads.elements();
    while (goodRoadEnum.hasMoreElements()) {
      SOCPossibleRoad goodRoad = (SOCPossibleRoad)goodRoadEnum.nextElement();
      D.ebugPrintln("*** good road at "+Integer.toHexString(goodRoad.getCoordinates())+" has a score of "+goodRoad.getScore());
      if (goodRoad.getNecessaryRoads().isEmpty() &&
	  ! ourPlayerData.isPotentialRoad(goodRoad.getCoordinates())) {
	D.ebugPrintln("POTENTIAL ROAD ERROR");
	//System.exit(0);
      }
    }
    */
    D.ebugPrintln("PICKING WHAT TO BUILD");
    // /
    if (ourPlayerData.getNumPieces(SOCPlayingPiece.SETTLEMENT) > 0) {
        for (SOCPossibleSettlement threatenedSet : threatenedSettlements) {
            if (threatenedSet.getNecessaryRoads().isEmpty()) {
                D.ebugPrintln("$$$$$ threatened settlement at " + Integer.toHexString(threatenedSet.getCoordinates()) + " has a score of " + threatenedSet.getScore());
                if ((favoriteSettlement == null) || (threatenedSet.getScore() > favoriteSettlement.getScore())) {
                    favoriteSettlement = threatenedSet;
                }
            }
        }
        for (SOCPossibleSettlement goodSet : goodSettlements) {
            if (goodSet.getNecessaryRoads().isEmpty()) {
                D.ebugPrintln("$$$$$ good settlement at " + Integer.toHexString(goodSet.getCoordinates()) + " has a score of " + goodSet.getScore());
                if ((favoriteSettlement == null) || (goodSet.getScore() > favoriteSettlement.getScore())) {
                    favoriteSettlement = goodSet;
                }
            }
        }
    }
    // 
    // restore the LRPath list
    // 
    D.ebugPrintln("%%% RESTORING LRPATH LIST %%%");
    for (int pn = 0; pn < game.maxPlayers; pn++) {
        game.getPlayer(pn).setLRPaths(savedLRPaths[pn]);
    }
    // /
    if (ourPlayerData.getNumPieces(SOCPlayingPiece.ROAD) > 0) {
        for (SOCPossibleRoad threatenedRoad : threatenedRoads) {
            D.ebugPrintln("$$$$$ threatened road at " + Integer.toHexString(threatenedRoad.getCoordinates()));
            if ((brain != null) && (brain.getDRecorder().isOn())) {
                brain.getDRecorder().startRecording("ROAD" + threatenedRoad.getCoordinates());
                brain.getDRecorder().record("Estimate value of road at " + game.getBoard().edgeCoordToString(threatenedRoad.getCoordinates()));
            }
            // 
            // see how building this piece impacts our winETA
            // 
            threatenedRoad.resetScore();
            float wgetaScore = getWinGameETABonusForRoad(threatenedRoad, buildingETAs[SOCBuildingSpeedEstimate.ROAD], leadersCurrentWGETA, playerTrackers);
            if ((brain != null) && (brain.getDRecorder().isOn())) {
                brain.getDRecorder().stopRecording();
            }
            D.ebugPrintln("wgetaScore = " + wgetaScore);
            if (favoriteRoad == null) {
                favoriteRoad = threatenedRoad;
            } else {
                if (threatenedRoad.getScore() > favoriteRoad.getScore()) {
                    favoriteRoad = threatenedRoad;
                }
            }
        }
        for (SOCPossibleRoad goodRoad : goodRoads) {
            D.ebugPrintln("$$$$$ good road at " + Integer.toHexString(goodRoad.getCoordinates()));
            if ((brain != null) && (brain.getDRecorder().isOn())) {
                brain.getDRecorder().startRecording("ROAD" + goodRoad.getCoordinates());
                brain.getDRecorder().record("Estimate value of road at " + game.getBoard().edgeCoordToString(goodRoad.getCoordinates()));
            }
            // 
            // see how building this piece impacts our winETA
            // 
            // TODO better ETA scoring for coastal ships/roads
            // 
            goodRoad.resetScore();
            final int etype = ((goodRoad instanceof SOCPossibleShip) && !((SOCPossibleShip) goodRoad).isCoastalRoadAndShip) ? SOCBuildingSpeedEstimate.ROAD : SOCBuildingSpeedEstimate.SHIP;
            float wgetaScore = getWinGameETABonusForRoad(goodRoad, buildingETAs[etype], leadersCurrentWGETA, playerTrackers);
            if ((brain != null) && (brain.getDRecorder().isOn())) {
                brain.getDRecorder().stopRecording();
            }
            D.ebugPrintln("wgetaScore = " + wgetaScore);
            if (favoriteRoad == null) {
                favoriteRoad = goodRoad;
            } else {
                if (goodRoad.getScore() > favoriteRoad.getScore()) {
                    favoriteRoad = goodRoad;
                }
            }
        }
    }
    // 
    // restore the LRPath list
    // 
    D.ebugPrintln("%%% RESTORING LRPATH LIST %%%");
    for (int pn = 0; pn < game.maxPlayers; pn++) {
        game.getPlayer(pn).setLRPaths(savedLRPaths[pn]);
    }
    // /
    if (ourPlayerData.getNumPieces(SOCPlayingPiece.CITY) > 0) {
        HashMap<Integer, SOCPlayerTracker> trackersCopy = SOCPlayerTracker.copyPlayerTrackers(playerTrackers);
        SOCPlayerTracker ourTrackerCopy = trackersCopy.get(Integer.valueOf(ourPlayerNumber));
        int[] originalWGETAs = new int[game.maxPlayers];
        int[] WGETAdiffs = new int[game.maxPlayers];
        Vector<SOCPlayerTracker> leaders = new Vector<SOCPlayerTracker>();
        int bestWGETA = 1000;
        // int bonus = 0;
        Iterator<SOCPossibleCity> posCitiesIter = ourPlayerTracker.getPossibleCities().values().iterator();
        while (posCitiesIter.hasNext()) {
            SOCPossibleCity posCity = posCitiesIter.next();
            if ((brain != null) && (brain.getDRecorder().isOn())) {
                brain.getDRecorder().startRecording("CITY" + posCity.getCoordinates());
                brain.getDRecorder().record("Estimate value of city at " + game.getBoard().nodeCoordToString(posCity.getCoordinates()));
            }
            // 
            // see how building this piece impacts our winETA
            // 
            leaders.clear();
            if ((brain != null) && (brain.getDRecorder().isOn())) {
                brain.getDRecorder().suspend();
            }
            SOCPlayerTracker.updateWinGameETAs(trackersCopy);
            // TODO refactor? This section is like a copy of calcWGETABonus, with something added in the middle
            Iterator<SOCPlayerTracker> trackersBeforeIter = trackersCopy.values().iterator();
            while (trackersBeforeIter.hasNext()) {
                SOCPlayerTracker trackerBefore = trackersBeforeIter.next();
                final int pn = trackerBefore.getPlayer().getPlayerNumber();
                D.ebugPrintln("$$$ win game ETA for player " + pn + " = " + trackerBefore.getWinGameETA());
                originalWGETAs[pn] = trackerBefore.getWinGameETA();
                WGETAdiffs[pn] = trackerBefore.getWinGameETA();
                if (trackerBefore.getWinGameETA() < bestWGETA) {
                    bestWGETA = trackerBefore.getWinGameETA();
                    leaders.removeAllElements();
                    leaders.addElement(trackerBefore);
                } else if (trackerBefore.getWinGameETA() == bestWGETA) {
                    leaders.addElement(trackerBefore);
                }
            }
            D.ebugPrintln("^^^^ bestWGETA = " + bestWGETA);
            if ((brain != null) && (brain.getDRecorder().isOn())) {
                brain.getDRecorder().resume();
            }
            // 
            // place the city
            // 
            SOCCity tmpCity = new SOCCity(ourPlayerData, posCity.getCoordinates(), null);
            game.putTempPiece(tmpCity);
            ourTrackerCopy.addOurNewCity(tmpCity);
            SOCPlayerTracker.updateWinGameETAs(trackersCopy);
            float wgetaScore = calcWGETABonusAux(originalWGETAs, trackersCopy, leaders);
            // 
            // remove the city
            // 
            ourTrackerCopy.undoAddOurNewCity(posCity);
            game.undoPutTempPiece(tmpCity);
            D.ebugPrintln("*** ETA for city = " + buildingETAs[SOCBuildingSpeedEstimate.CITY]);
            if ((brain != null) && (brain.getDRecorder().isOn())) {
                brain.getDRecorder().record("ETA = " + buildingETAs[SOCBuildingSpeedEstimate.CITY]);
            }
            float etaBonus = getETABonus(buildingETAs[SOCBuildingSpeedEstimate.CITY], leadersCurrentWGETA, wgetaScore);
            D.ebugPrintln("etaBonus = " + etaBonus);
            posCity.addToScore(etaBonus);
            if ((brain != null) && (brain.getDRecorder().isOn())) {
                brain.getDRecorder().record("WGETA score = " + df1.format(wgetaScore));
                brain.getDRecorder().record("Total city score = " + df1.format(etaBonus));
                brain.getDRecorder().stopRecording();
            }
            D.ebugPrintln("$$$  final score = " + posCity.getScore());
            D.ebugPrintln("$$$$$ possible city at " + Integer.toHexString(posCity.getCoordinates()) + " has a score of " + posCity.getScore());
            if ((favoriteCity == null) || (posCity.getScore() > favoriteCity.getScore())) {
                favoriteCity = posCity;
            }
        }
    }
    if (favoriteSettlement != null) {
        D.ebugPrintln("### FAVORITE SETTLEMENT IS AT " + Integer.toHexString(favoriteSettlement.getCoordinates()));
        D.ebugPrintln("###   WITH A SCORE OF " + favoriteSettlement.getScore());
        D.ebugPrintln("###   WITH AN ETA OF " + buildingETAs[SOCBuildingSpeedEstimate.SETTLEMENT]);
        D.ebugPrintln("###   WITH A TOTAL SPEEDUP OF " + favoriteSettlement.getSpeedupTotal());
    }
    if (favoriteCity != null) {
        D.ebugPrintln("### FAVORITE CITY IS AT " + Integer.toHexString(favoriteCity.getCoordinates()));
        D.ebugPrintln("###   WITH A SCORE OF " + favoriteCity.getScore());
        D.ebugPrintln("###   WITH AN ETA OF " + buildingETAs[SOCBuildingSpeedEstimate.CITY]);
        D.ebugPrintln("###   WITH A TOTAL SPEEDUP OF " + favoriteCity.getSpeedupTotal());
    }
    final int road_eta_type = ((favoriteRoad != null) && (favoriteRoad instanceof SOCPossibleShip) && // TODO better ETA calc for coastal roads/ships
    !((SOCPossibleShip) favoriteRoad).isCoastalRoadAndShip) ? SOCBuildingSpeedEstimate.SHIP : SOCBuildingSpeedEstimate.ROAD;
    if (favoriteRoad != null) {
        D.ebugPrintln("### FAVORITE ROAD IS AT " + Integer.toHexString(favoriteRoad.getCoordinates()));
        D.ebugPrintln("###   WITH AN ETA OF " + buildingETAs[road_eta_type]);
        D.ebugPrintln("###   WITH A SCORE OF " + favoriteRoad.getScore());
    }
    // piece type, if any, to be pushed onto buildingPlan;
    int pick = -1;
    // use ROAD for road or ship, use MAXPLUSONE for dev card
    // getScore() of picked piece
    float pickScore = 0f;
    // /
    if ((favoriteCity != null) && (ourPlayerData.getNumPieces(SOCPlayingPiece.CITY) > 0) && (favoriteCity.getScore() > 0) && ((favoriteSettlement == null) || (ourPlayerData.getNumPieces(SOCPlayingPiece.SETTLEMENT) == 0) || (favoriteCity.getScore() > favoriteSettlement.getScore()) || ((favoriteCity.getScore() == favoriteSettlement.getScore()) && (buildingETAs[SOCBuildingSpeedEstimate.CITY] < buildingETAs[SOCBuildingSpeedEstimate.SETTLEMENT]))) && ((favoriteRoad == null) || (ourPlayerData.getNumPieces(favoriteRoad.getType()) == 0) || (favoriteCity.getScore() > favoriteRoad.getScore()) || ((favoriteCity.getScore() == favoriteRoad.getScore()) && (buildingETAs[SOCBuildingSpeedEstimate.CITY] < buildingETAs[road_eta_type])))) {
        D.ebugPrintln("### PICKED FAVORITE CITY");
        pick = SOCPlayingPiece.CITY;
        pickScore = favoriteCity.getScore();
    } else // /
    if ((favoriteRoad != null) && (ourPlayerData.getNumPieces(favoriteRoad.getType()) > 0) && (favoriteRoad.getScore() > 0) && ((favoriteSettlement == null) || (ourPlayerData.getNumPieces(SOCPlayingPiece.SETTLEMENT) == 0) || (favoriteSettlement.getScore() < favoriteRoad.getScore()))) {
        D.ebugPrintln("### PICKED FAVORITE ROAD");
        // also represents SHIP here
        pick = SOCPlayingPiece.ROAD;
        pickScore = favoriteRoad.getScore();
    } else if ((favoriteSettlement != null) && (ourPlayerData.getNumPieces(SOCPlayingPiece.SETTLEMENT) > 0)) {
        D.ebugPrintln("### PICKED FAVORITE SETTLEMENT");
        pick = SOCPlayingPiece.SETTLEMENT;
        pickScore = favoriteSettlement.getScore();
    }
    // /
    // / if buying a card is better than building...
    // /
    // 
    // see how buying a card improves our win game ETA
    // 
    float devCardScore = 0;
    if ((game.getNumDevCards() > 0) && !forSpecialBuildingPhase) {
        if ((brain != null) && (brain.getDRecorder().isOn())) {
            brain.getDRecorder().startRecording("DEVCARD");
            brain.getDRecorder().record("Estimate value of a dev card");
        }
        possibleCard = getDevCardScore(buildingETAs[SOCBuildingSpeedEstimate.CARD], leadersCurrentWGETA);
        devCardScore = possibleCard.getScore();
        D.ebugPrintln("### DEV CARD SCORE: " + devCardScore);
        if ((brain != null) && (brain.getDRecorder().isOn())) {
            brain.getDRecorder().stopRecording();
        }
        if ((pick == -1) || (devCardScore > pickScore)) {
            D.ebugPrintln("### BUY DEV CARD");
            pick = SOCPlayingPiece.MAXPLUSONE;
            pickScore = devCardScore;
        }
    }
    if (game.isGameOptionSet(SOCGameOption.K_SC_PIRI) || game.isGameOptionSet(SOCGameOption.K_SC_WOND)) {
        if (scenarioGameStrategyPlan(pickScore, devCardScore, true, (pick == SOCPlayingPiece.MAXPLUSONE), new SOCBuildingSpeedEstimate(ourPlayerData.getNumbers()), leadersCurrentWGETA, forSpecialBuildingPhase))
            // <--- Early return: Scenario-specific buildingPlan was pushed ---
            return;
    }
    // 
    switch(pick) {
        case SOCPlayingPiece.ROAD:
            D.ebugPrintln("$ PUSHING " + favoriteRoad);
            buildingPlan.push(favoriteRoad);
            break;
        case SOCPlayingPiece.SETTLEMENT:
            D.ebugPrintln("$ PUSHING " + favoriteSettlement);
            buildingPlan.push(favoriteSettlement);
            break;
        case SOCPlayingPiece.CITY:
            D.ebugPrintln("$ PUSHING " + favoriteCity);
            buildingPlan.push(favoriteCity);
            break;
        case SOCPlayingPiece.MAXPLUSONE:
            D.ebugPrintln("$ PUSHING " + possibleCard);
            buildingPlan.push(possibleCard);
            break;
    }
}
Also used : SOCBoard(soc.game.SOCBoard) ArrayList(java.util.ArrayList) List(java.util.List) Vector(java.util.Vector) SOCBoardLarge(soc.game.SOCBoardLarge) SOCCity(soc.game.SOCCity) SOCLRPathData(soc.game.SOCLRPathData)

Example 7 with SOCCity

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

the class SOCPossibleCity method updateSpeedup.

/**
 * calculate the speedup that this city gives.
 * Call when any player's new city or settlement is added to the board.
 * @see #getSpeedup()
 */
public void updateSpeedup() {
    // D.ebugPrintln("****************************** (CITY) updateSpeedup at "+Integer.toHexString(coord));
    SOCBuildingSpeedEstimate bse1 = new SOCBuildingSpeedEstimate(player.getNumbers());
    int[] ourBuildingSpeed = bse1.getEstimatesFromNothingFast(player.getPortFlags());
    SOCPlayerNumbers newNumbers = new SOCPlayerNumbers(player.getNumbers());
    newNumbers.updateNumbers(new SOCCity(player, coord, null), player.getGame().getBoard());
    SOCBuildingSpeedEstimate bse2 = new SOCBuildingSpeedEstimate(newNumbers);
    int[] speed = bse2.getEstimatesFromNothingFast(player.getPortFlags());
    for (int buildingType = SOCBuildingSpeedEstimate.MIN; buildingType < SOCBuildingSpeedEstimate.MAXPLUSONE; buildingType++) {
        // D.ebugPrintln("!@#$% ourBuildingSpeed[buildingType]="+ourBuildingSpeed[buildingType]+" speed[buildingType]="+speed[buildingType]);
        speedup[buildingType] = ourBuildingSpeed[buildingType] - speed[buildingType];
    }
}
Also used : SOCCity(soc.game.SOCCity) SOCPlayerNumbers(soc.game.SOCPlayerNumbers)

Example 8 with SOCCity

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

the class SOCBoardPanel method drawBoard.

/**
 * Draw the whole board, including pieces and tooltip ({@link #hilight}, {@link #hoverTip}) if applicable.
 * The basic board without pieces is drawn just once, then buffered.
 * If the board layout changes (at start of game, for example),
 * call {@link #flushBoardLayoutAndRepaint()} to clear the buffered copy.
 *
 * @see #drawBoardEmpty(Graphics)
 */
private void drawBoard(Graphics g) {
    Image ebb = emptyBoardBuffer;
    if (scaledMissedImage || ebb == null) {
        if (ebb == null) {
            ebb = createImage(scaledPanelW, scaledPanelH);
            emptyBoardBuffer = ebb;
        }
        drawnEmptyAt = System.currentTimeMillis();
        // drawBoardEmpty, drawHex will set this flag if missed
        scaledMissedImage = false;
        drawBoardEmpty(ebb.getGraphics());
        ebb.flush();
        if (scaledMissedImage && (scaledAt != 0) && (RESCALE_MAX_RETRY_MS < (drawnEmptyAt - scaledAt)))
            // eventually give up scaling it
            scaledMissedImage = false;
    }
    // draw ebb from local variable, not emptyBoardBuffer field, to avoid occasional NPE
    g.setPaintMode();
    g.drawImage(ebb, 0, 0, this);
    // ask for antialiasing if available
    if (g instanceof Graphics2D)
        ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    final boolean xlat = (panelMarginX != 0) || (panelMarginY != 0);
    if (xlat)
        g.translate(panelMarginX, panelMarginY);
    final int gameState = game.getGameState();
    if (board.getRobberHex() != -1) {
        drawRobber(g, board.getRobberHex(), (gameState != SOCGame.PLACING_ROBBER), true);
    }
    if (board.getPreviousRobberHex() != -1) {
        drawRobber(g, board.getPreviousRobberHex(), (gameState != SOCGame.PLACING_ROBBER), false);
    }
    if (isLargeBoard) {
        int hex = ((SOCBoardLarge) board).getPirateHex();
        if (hex > 0) {
            drawRoadOrShip(g, hex, -2, (gameState == SOCGame.PLACING_PIRATE), false, false);
        }
        hex = ((SOCBoardLarge) board).getPreviousPirateHex();
        if (hex > 0) {
            drawRoadOrShip(g, hex, -3, (gameState == SOCGame.PLACING_PIRATE), false, false);
        }
    }
    /**
     * draw the roads and ships
     */
    if (!game.isGameOptionSet(SOCGameOption.K_SC_PIRI)) {
        for (SOCRoad r : board.getRoads()) {
            drawRoadOrShip(g, r.getCoordinates(), r.getPlayerNumber(), false, !(r instanceof SOCShip), false);
        }
    } else {
        for (int pn = 0; pn < game.maxPlayers; ++pn) {
            final SOCPlayer pl = game.getPlayer(pn);
            // count warships here, for efficiency, instead of calling SOCGame.isShipWarship for each one
            int numWarships = pl.getNumWarships();
            for (SOCRoad r : pl.getRoads()) {
                final boolean isShip = (r instanceof SOCShip);
                final boolean isWarship = isShip && (numWarships > 0);
                drawRoadOrShip(g, r.getCoordinates(), pn, false, !isShip, isWarship);
                if (isWarship)
                    // this works since warships begin with player's 1st-placed ship in getRoads()
                    --numWarships;
            }
            /**
             * draw the player's fortress, if any
             */
            SOCFortress fo = pl.getFortress();
            if (fo != null)
                drawFortress(g, fo, pn, false);
        }
    }
    /**
     * draw the settlements
     */
    for (SOCSettlement s : board.getSettlements()) {
        drawSettlement(g, s.getCoordinates(), s.getPlayerNumber(), false, false);
    }
    /**
     * draw the cities
     */
    for (SOCCity c : board.getCities()) {
        drawCity(g, c.getCoordinates(), c.getPlayerNumber(), false);
    }
    if (xlat)
        g.translate(-panelMarginX, -panelMarginY);
    /**
     * draw the current-player arrow after ("above") pieces,
     * but below any hilighted piece, in case of overlap at
     * edge of board. More likely on 6-player board for the
     * two players whose handpanels are vertically centered.
     */
    if (gameState != SOCGame.NEW) {
        drawArrow(g, game.getCurrentPlayerNumber(), game.getCurrentDice());
    }
    if (player != null) {
        if (xlat)
            g.translate(panelMarginX, panelMarginY);
        /**
         * Draw the hilight when in interactive mode;
         * No hilight when null player (before game started).
         * The "hovering" road/settlement/city are separately painted
         * in {@link soc.client.SOCBoardPanel.BoardToolTip#paint()}.
         */
        switch(mode) {
            case MOVE_SHIP:
                if (moveShip_fromEdge != 0)
                    drawRoadOrShip(g, moveShip_fromEdge, -1, false, false, moveShip_isWarship);
            case PLACE_ROAD:
            case PLACE_INIT_ROAD:
            case PLACE_FREE_ROAD_OR_SHIP:
                if (hilight != 0) {
                    drawRoadOrShip(g, hilight, playerNumber, true, !hilightIsShip, (moveShip_isWarship && (moveShip_fromEdge != 0)));
                }
                break;
            case PLACE_SETTLEMENT:
            case PLACE_INIT_SETTLEMENT:
                if (hilight > 0) {
                    drawSettlement(g, hilight, playerNumber, true, false);
                }
                break;
            case PLACE_CITY:
                if (hilight > 0) {
                    drawCity(g, hilight, playerNumber, true);
                }
                break;
            case PLACE_SHIP:
                if (hilight > 0) {
                    drawRoadOrShip(g, hilight, playerNumber, true, false, false);
                }
                break;
            case CONSIDER_LM_SETTLEMENT:
            case CONSIDER_LT_SETTLEMENT:
                if (hilight > 0) {
                    drawSettlement(g, hilight, otherPlayer.getPlayerNumber(), true, false);
                }
                break;
            case CONSIDER_LM_ROAD:
            case CONSIDER_LT_ROAD:
                if (hilight != 0) {
                    drawRoadOrShip(g, hilight, otherPlayer.getPlayerNumber(), false, true, false);
                }
                break;
            case CONSIDER_LM_CITY:
            case CONSIDER_LT_CITY:
                if (hilight > 0) {
                    drawCity(g, hilight, otherPlayer.getPlayerNumber(), true);
                }
                break;
            case PLACE_ROBBER:
                if (hilight > 0) {
                    drawRobber(g, hilight, true, true);
                }
                break;
            case PLACE_PIRATE:
                if (hilight > 0) {
                    drawRoadOrShip(g, hilight, -2, false, false, false);
                }
                break;
            case SC_FTRI_PLACE_PORT:
                drawBoard_SC_FTRI_placePort(g);
                break;
        }
        if (xlat)
            g.translate(-panelMarginX, -panelMarginY);
    }
    if (superText1 != null) {
        drawSuperText(g);
    }
    if (superTextTop != null) {
        drawSuperTextTop(g);
    }
}
Also used : SOCSettlement(soc.game.SOCSettlement) SOCBoardLarge(soc.game.SOCBoardLarge) SOCCity(soc.game.SOCCity) SOCShip(soc.game.SOCShip) SOCPlayer(soc.game.SOCPlayer) SOCFortress(soc.game.SOCFortress) Image(java.awt.Image) BufferedImage(java.awt.image.BufferedImage) SOCRoad(soc.game.SOCRoad) Graphics2D(java.awt.Graphics2D)

Example 9 with SOCCity

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

the class SOCBoardPanel method mouseClicked.

/**
 * DOCUMENT ME!
 *
 * @param evt DOCUMENT ME!
 */
public void mouseClicked(MouseEvent evt) {
    try {
        int x = evt.getX();
        int y = evt.getY();
        if (evt.isPopupTrigger()) {
            popupMenuSystime = evt.getWhen();
            evt.consume();
            doBoardMenuPopup(x, y);
            // <--- Pop up menu, nothing else to do ---
            return;
        }
        if (evt.getWhen() < (popupMenuSystime + POPUP_MENU_IGNORE_MS)) {
            // <--- Ignore click: too soon after popup click ---
            return;
        }
        boolean tempChangedMode = false;
        if ((mode == NONE) && hoverTip.isVisible()) {
            if (game.isDebugFreePlacement()) {
                if (hoverTip.hoverSettlementID != 0) {
                    hilight = hoverTip.hoverSettlementID;
                    hilightIsShip = false;
                    mode = PLACE_SETTLEMENT;
                    tempChangedMode = true;
                } else if (hoverTip.hoverCityID != 0) {
                    hilight = hoverTip.hoverCityID;
                    hilightIsShip = false;
                    mode = PLACE_CITY;
                    tempChangedMode = true;
                } else if (hoverTip.hoverRoadID != 0) {
                    hilight = hoverTip.hoverRoadID;
                    hilightIsShip = false;
                    mode = PLACE_ROAD;
                    tempChangedMode = true;
                } else if (hoverTip.hoverShipID != 0) {
                    hilight = hoverTip.hoverShipID;
                    hilightIsShip = true;
                    mode = PLACE_SHIP;
                    tempChangedMode = true;
                }
            } else if (((evt.getModifiers() & InputEvent.BUTTON1_MASK) == InputEvent.BUTTON1_MASK) && (player != null) && (game.getCurrentPlayerNumber() == playerNumber) && (player.getPublicVP() == 2) && (hintShownCount_RightClickToBuild < 2)) {
                // To help during the start of the game, display a hint message
                // reminding new users to right-click to build (OSX: control-click).
                // Show it at most twice to avoid annoying the user.
                ++hintShownCount_RightClickToBuild;
                final String prompt = (SOCPlayerClient.isJavaOnOSX) ? "board.popup.hint_build_click.osx" : // "To build pieces, hold Control while clicking the build location."
                "board.popup.hint_build_click";
                // "To build pieces, right-click the build location."
                NotifyDialog.createAndShow(playerInterface.getGameDisplay(), playerInterface, "\n" + strings.get(prompt), null, true);
            // start prompt with \n to prevent it being a lengthy popup-dialog title
            }
        }
        if ((hilight != 0) && (player != null) && (x == ptrOldX) && (y == ptrOldY)) {
            SOCPlayerClient client = playerInterface.getClient();
            switch(mode) {
                case NONE:
                    break;
                case TURN_STARTING:
                    break;
                case PLACE_INIT_ROAD:
                case PLACE_ROAD:
                case PLACE_FREE_ROAD_OR_SHIP:
                    if (hilight == -1)
                        // Road on edge 0x00
                        hilight = 0;
                    if (player.isPotentialRoad(hilight) && !hilightIsShip) {
                        client.getGameManager().putPiece(game, new SOCRoad(player, hilight, board));
                        // Now that we've placed, clear the mode and the hilight.
                        clearModeAndHilight(SOCPlayingPiece.ROAD);
                        if (tempChangedMode)
                            hoverTip.hideHoverAndPieces();
                    } else if (// checks isPotentialShip, pirate ship
                    game.canPlaceShip(player, hilight)) {
                        if (game.isGameOptionSet(SOCGameOption.K_SC_FTRI) && ((SOCBoardLarge) board).canRemovePort(hilight)) {
                            java.awt.EventQueue.invokeLater(new ConfirmPlaceShipDialog(hilight, false, -1));
                        } else {
                            client.getGameManager().putPiece(game, new SOCShip(player, hilight, board));
                            // Now that we've placed, clear the mode and the hilight.
                            clearModeAndHilight(SOCPlayingPiece.SHIP);
                        }
                        if (tempChangedMode)
                            hoverTip.hideHoverAndPieces();
                    }
                    break;
                case MOVE_SHIP:
                    // check and move ship to hilight from fromEdge;
                    // also sets moveShip_fromEdge = 0, calls clearModeAndHilight.
                    moveShip_toEdge = hilight;
                    tryMoveShipToEdge();
                    break;
                case PLACE_INIT_SETTLEMENT:
                    if (playerNumber == playerInterface.getClientPlayerNumber()) {
                        initSettlementNode = hilight;
                    }
                case PLACE_SETTLEMENT:
                    if (player.canPlaceSettlement(hilight)) {
                        client.getGameManager().putPiece(game, new SOCSettlement(player, hilight, board));
                        clearModeAndHilight(SOCPlayingPiece.SETTLEMENT);
                        if (tempChangedMode)
                            hoverTip.hideHoverAndPieces();
                    }
                    break;
                case PLACE_CITY:
                    if (player.isPotentialCity(hilight)) {
                        client.getGameManager().putPiece(game, new SOCCity(player, hilight, board));
                        clearModeAndHilight(SOCPlayingPiece.CITY);
                        if (tempChangedMode)
                            hoverTip.hideHoverAndPieces();
                    }
                    break;
                case PLACE_SHIP:
                    if (// checks isPotentialShip, pirate ship
                    game.canPlaceShip(player, hilight)) {
                        if (game.isGameOptionSet(SOCGameOption.K_SC_FTRI) && ((SOCBoardLarge) board).canRemovePort(hilight)) {
                            java.awt.EventQueue.invokeLater(new ConfirmPlaceShipDialog(hilight, false, -1));
                        } else {
                            client.getGameManager().putPiece(game, new SOCShip(player, hilight, board));
                            clearModeAndHilight(SOCPlayingPiece.SHIP);
                        }
                        if (tempChangedMode)
                            hoverTip.hideHoverAndPieces();
                    }
                    break;
                case PLACE_ROBBER:
                    if (hilight != board.getRobberHex()) {
                        // do we have an adjacent settlement/city?
                        boolean cliAdjacent = false;
                        {
                            for (SOCPlayer pl : game.getPlayersOnHex(hilight)) {
                                if (pl.getPlayerNumber() == playerNumber) {
                                    cliAdjacent = true;
                                    break;
                                }
                            }
                        }
                        if (cliAdjacent) {
                            // ask player to confirm first
                            java.awt.EventQueue.invokeLater(new MoveRobberConfirmDialog(player, hilight));
                        } else {
                            // ask server to move it
                            client.getGameManager().moveRobber(game, player, hilight);
                            clearModeAndHilight(-1);
                        }
                    }
                    break;
                case PLACE_PIRATE:
                    if (hilight != ((SOCBoardLarge) board).getPirateHex()) {
                        // do we have an adjacent ship?
                        boolean cliAdjacent = false;
                        {
                            for (SOCPlayer pl : game.getPlayersShipsOnHex(hilight)) {
                                if (pl.getPlayerNumber() == playerNumber) {
                                    cliAdjacent = true;
                                    break;
                                }
                            }
                        }
                        if (cliAdjacent) {
                            // ask player to confirm first
                            java.awt.EventQueue.invokeLater(new MoveRobberConfirmDialog(player, -hilight));
                        } else {
                            // ask server to move it
                            client.getGameManager().moveRobber(game, player, -hilight);
                            clearModeAndHilight(-1);
                        }
                    }
                    break;
                case SC_FTRI_PLACE_PORT:
                    if (hilight != 0) {
                        int edge = hilight;
                        if (edge == -1)
                            edge = 0;
                        if (game.canPlacePort(player, edge)) {
                            // Ask server to place here.
                            client.getGameManager().sendSimpleRequest(player, SOCSimpleRequest.TRADE_PORT_PLACE, hilight, 0);
                            hilight = 0;
                        }
                    }
                    break;
                case CONSIDER_LM_SETTLEMENT:
                    if (otherPlayer.canPlaceSettlement(hilight)) {
                        client.getGameManager().considerMove(game, otherPlayer.getName(), new SOCSettlement(otherPlayer, hilight, board));
                        clearModeAndHilight(SOCPlayingPiece.SETTLEMENT);
                    }
                    break;
                case CONSIDER_LM_ROAD:
                    if (otherPlayer.isPotentialRoad(hilight)) {
                        client.getGameManager().considerMove(game, otherPlayer.getName(), new SOCRoad(otherPlayer, hilight, board));
                        clearModeAndHilight(SOCPlayingPiece.ROAD);
                    }
                    break;
                case CONSIDER_LM_CITY:
                    if (otherPlayer.isPotentialCity(hilight)) {
                        client.getGameManager().considerMove(game, otherPlayer.getName(), new SOCCity(otherPlayer, hilight, board));
                        clearModeAndHilight(SOCPlayingPiece.CITY);
                    }
                    break;
                case CONSIDER_LT_SETTLEMENT:
                    if (otherPlayer.canPlaceSettlement(hilight)) {
                        client.getGameManager().considerTarget(game, otherPlayer.getName(), new SOCSettlement(otherPlayer, hilight, board));
                        clearModeAndHilight(SOCPlayingPiece.SETTLEMENT);
                    }
                    break;
                case CONSIDER_LT_ROAD:
                    if (otherPlayer.isPotentialRoad(hilight)) {
                        client.getGameManager().considerTarget(game, otherPlayer.getName(), new SOCRoad(otherPlayer, hilight, board));
                        clearModeAndHilight(SOCPlayingPiece.ROAD);
                    }
                    break;
                case CONSIDER_LT_CITY:
                    if (otherPlayer.isPotentialCity(hilight)) {
                        client.getGameManager().considerTarget(game, otherPlayer.getName(), new SOCCity(otherPlayer, hilight, board));
                        clearModeAndHilight(SOCPlayingPiece.CITY);
                    }
                    break;
            }
        } else if ((player != null) && ((game.getCurrentPlayerNumber() == playerNumber) || game.isDebugFreePlacement())) {
            // No hilight. But, they clicked the board, expecting something.
            // It's possible the mode is incorrect.
            // Update and wait for the next click.
            updateMode();
            ptrOldX = 0;
            ptrOldY = 0;
            // mouseMoved will establish hilight using click's x,y
            mouseMoved(evt);
        }
        evt.consume();
        if (tempChangedMode)
            mode = NONE;
    } catch (Throwable th) {
        playerInterface.chatPrintStackTrace(th);
    }
}
Also used : SOCBoardLarge(soc.game.SOCBoardLarge) SOCShip(soc.game.SOCShip) SOCRoad(soc.game.SOCRoad) SOCSettlement(soc.game.SOCSettlement) SOCCity(soc.game.SOCCity) SOCPlayer(soc.game.SOCPlayer)

Example 10 with SOCCity

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

the class SOCRobotDM method getWinGameETABonus.

/**
 * add a bonus to the possible piece score based
 * on the change in win game ETA
 *
 * @param posPiece  the possible piece that we're scoring
 */
protected float getWinGameETABonus(final SOCPossiblePiece posPiece) {
    HashMap<Integer, SOCPlayerTracker> trackersCopy = null;
    SOCSettlement tmpSet = null;
    SOCCity tmpCity = null;
    // road or ship
    SOCRoad tmpRoad = null;
    float bonus = 0;
    D.ebugPrintln("--- before [start] ---");
    // SOCPlayerTracker.playerTrackersDebug(playerTrackers);
    D.ebugPrintln("our player numbers = " + ourPlayerData.getNumbers());
    D.ebugPrintln("--- before [end] ---");
    switch(posPiece.getType()) {
        case SOCPossiblePiece.SETTLEMENT:
            tmpSet = new SOCSettlement(ourPlayerData, posPiece.getCoordinates(), null);
            trackersCopy = SOCPlayerTracker.tryPutPiece(tmpSet, game, playerTrackers);
            break;
        case SOCPossiblePiece.CITY:
            trackersCopy = SOCPlayerTracker.copyPlayerTrackers(playerTrackers);
            tmpCity = new SOCCity(ourPlayerData, posPiece.getCoordinates(), null);
            game.putTempPiece(tmpCity);
            SOCPlayerTracker trackerCopy = trackersCopy.get(Integer.valueOf(ourPlayerNumber));
            if (trackerCopy != null) {
                trackerCopy.addOurNewCity(tmpCity);
            }
            break;
        case SOCPossiblePiece.ROAD:
            tmpRoad = new SOCRoad(ourPlayerData, posPiece.getCoordinates(), null);
            trackersCopy = SOCPlayerTracker.tryPutPiece(tmpRoad, game, playerTrackers);
            break;
        case SOCPossiblePiece.SHIP:
            tmpRoad = new SOCShip(ourPlayerData, posPiece.getCoordinates(), null);
            trackersCopy = SOCPlayerTracker.tryPutPiece(tmpRoad, game, playerTrackers);
            break;
    }
    // trackersCopyIter = trackersCopy.iterator();
    // while (trackersCopyIter.hasNext()) {
    // SOCPlayerTracker trackerCopy = (SOCPlayerTracker)trackersCopyIter.next();
    // trackerCopy.updateThreats(trackersCopy);
    // }
    D.ebugPrintln("--- after [start] ---");
    // SOCPlayerTracker.playerTrackersDebug(trackersCopy);
    SOCPlayerTracker.updateWinGameETAs(trackersCopy);
    float WGETABonus = calcWGETABonus(playerTrackers, trackersCopy);
    D.ebugPrintln("$$$ win game ETA bonus : +" + WGETABonus);
    bonus = WGETABonus;
    D.ebugPrintln("our player numbers = " + ourPlayerData.getNumbers());
    D.ebugPrintln("--- after [end] ---");
    switch(posPiece.getType()) {
        case SOCPossiblePiece.SETTLEMENT:
            SOCPlayerTracker.undoTryPutPiece(tmpSet, game);
            break;
        case SOCPossiblePiece.CITY:
            game.undoPutTempPiece(tmpCity);
            break;
        // fall through to ROAD
        case SOCPossiblePiece.SHIP:
        case SOCPossiblePiece.ROAD:
            SOCPlayerTracker.undoTryPutPiece(tmpRoad, game);
            break;
    }
    D.ebugPrintln("our player numbers = " + ourPlayerData.getNumbers());
    D.ebugPrintln("--- cleanup done ---");
    return bonus;
}
Also used : SOCSettlement(soc.game.SOCSettlement) SOCCity(soc.game.SOCCity) SOCShip(soc.game.SOCShip) SOCRoad(soc.game.SOCRoad)

Aggregations

SOCCity (soc.game.SOCCity)12 SOCRoad (soc.game.SOCRoad)10 SOCSettlement (soc.game.SOCSettlement)10 SOCShip (soc.game.SOCShip)10 SOCPlayer (soc.game.SOCPlayer)7 SOCBoardLarge (soc.game.SOCBoardLarge)3 SOCFortress (soc.game.SOCFortress)3 SOCPlayingPiece (soc.game.SOCPlayingPiece)3 SOCVillage (soc.game.SOCVillage)2 Graphics2D (java.awt.Graphics2D)1 Image (java.awt.Image)1 BufferedImage (java.awt.image.BufferedImage)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1 Vector (java.util.Vector)1 SOCBoard (soc.game.SOCBoard)1 SOCLRPathData (soc.game.SOCLRPathData)1 SOCPlayerNumbers (soc.game.SOCPlayerNumbers)1