Search in sources :

Example 16 with SOCShip

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

the class SOCDisplaylessPlayerClient method handleREMOVEPIECE.

/**
 * A player's piece (a ship) has been removed from the board. Updates game state.
 *<P>
 * Currently, only ships can be removed, in game scenario {@code _SC_PIRI}.
 * Other {@code pieceType}s are ignored.
 * @since 2.0.00
 */
protected void handleREMOVEPIECE(SOCRemovePiece mes) {
    final String gaName = mes.getGame();
    SOCGame ga = games.get(gaName);
    if (ga == null)
        // Not one of our games
        return;
    SOCPlayer player = ga.getPlayer(mes.getParam1());
    final int pieceType = mes.getParam2();
    final int pieceCoordinate = mes.getParam3();
    switch(pieceType) {
        case SOCPlayingPiece.SHIP:
            ga.removeShip(new SOCShip(player, pieceCoordinate, null));
            break;
        default:
            System.err.println("Displayless.updateAtPieceRemoved called for un-handled type " + pieceType);
    }
}
Also used : SOCShip(soc.game.SOCShip) SOCPlayer(soc.game.SOCPlayer) SOCGame(soc.game.SOCGame)

Example 17 with SOCShip

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

the class SOCRobotBrain method buildOrGetResourceByTradeOrCard.

/**
 * Either ask to build a planned piece, or use trading or development cards to get resources to build it.
 * Examines {@link #buildingPlan} for the next piece wanted.
 * Sets {@link #whatWeWantToBuild} by calling {@link #buildRequestPlannedPiece()}
 * or using a Road Building dev card.
 *<P>
 * If we need resources and we can't get them through the robber,
 * the {@link SOCDevCardConstants#ROADS Road Building} or
 * {@link SOCDevCardConstants#MONO Monopoly} or
 * {@link SOCDevCardConstants#DISC Discovery} development cards,
 * then trades with the bank ({@link #tradeToTarget2(SOCResourceSet)})
 * or with other players ({@link #makeOffer(SOCPossiblePiece)}).
 *<P>
 * Call when these conditions are all true:
 * <UL>
 *<LI> {@link #ourTurn}
 *<LI> {@link #planBuilding()} already called
 *<LI> ! {@link #buildingPlan}.empty()
 *<LI> gameState {@link SOCGame#PLAY1} or {@link SOCGame#SPECIAL_BUILDING}
 *<LI> <tt>waitingFor...</tt> flags all false ({@link #waitingForGameState}, etc)
 *     except possibly {@link #waitingForSpecialBuild}
 *<LI> <tt>expect...</tt> flags all false ({@link #expectPLACING_ROAD}, etc)
 *<LI> ! {@link #waitingForOurTurn}
 *<LI> ! ({@link #expectROLL_OR_CARD} && (counter < 4000))
 *</UL>
 *<P>
 * May set any of these flags:
 * <UL>
 *<LI> {@link #waitingForGameState}, and {@link #expectWAITING_FOR_DISCOVERY} or {@link #expectWAITING_FOR_MONOPOLY}
 *<LI> {@link #waitingForTradeMsg} or {@link #waitingForTradeResponse} or {@link #doneTrading}
 *<LI> {@link #waitingForDevCard}, or {@link #waitingForGameState} and {@link #expectPLACING_SETTLEMENT} (etc).
 *<LI> {@link #waitingForPickSpecialItem}
 *<LI> Scenario actions such as {@link #waitingForSC_PIRI_FortressRequest}
 *</UL>
 *<P>
 * In a future iteration of the run() loop with the expected {@code PLACING_} state, the
 * bot will build {@link #whatWeWantToBuild} by calling {@link #placeIfExpectPlacing()}.
 *
 * @since 1.1.08
 * @throws IllegalStateException  if {@link #buildingPlan}{@link Stack#isEmpty() .isEmpty()}
 */
private void buildOrGetResourceByTradeOrCard() throws IllegalStateException {
    if (buildingPlan.isEmpty())
        throw new IllegalStateException("buildingPlan empty when called");
    /**
     * If we're in SPECIAL_BUILDING (not PLAY1),
     * can't trade or play development cards.
     */
    final boolean gameStatePLAY1 = (game.getGameState() == SOCGame.PLAY1);
    /**
     * check to see if this is a Road Building plan
     */
    boolean roadBuildingPlan = false;
    if (gameStatePLAY1 && (!ourPlayerData.hasPlayedDevCard()) && (ourPlayerData.getNumPieces(SOCPlayingPiece.ROAD) >= 2) && ourPlayerData.getInventory().hasPlayable(SOCDevCardConstants.ROADS) && (rejectedPlayDevCardType != SOCDevCardConstants.ROADS)) {
        // D.ebugPrintln("** Checking for Road Building Plan **");
        SOCPossiblePiece topPiece = buildingPlan.pop();
        // D.ebugPrintln("$ POPPED "+topPiece);
        if ((topPiece != null) && (topPiece instanceof SOCPossibleRoad)) {
            SOCPossiblePiece secondPiece = (buildingPlan.isEmpty()) ? null : buildingPlan.peek();
            // D.ebugPrintln("secondPiece="+secondPiece);
            if ((secondPiece != null) && (secondPiece instanceof SOCPossibleRoad)) {
                roadBuildingPlan = true;
                // builds ships only if the 2 possible pieces are non-coastal ships
                if ((topPiece instanceof SOCPossibleShip) && (!((SOCPossibleShip) topPiece).isCoastalRoadAndShip) && (secondPiece instanceof SOCPossibleShip) && (!((SOCPossibleShip) secondPiece).isCoastalRoadAndShip))
                    whatWeWantToBuild = new SOCShip(ourPlayerData, topPiece.getCoordinates(), null);
                else
                    whatWeWantToBuild = new SOCRoad(ourPlayerData, topPiece.getCoordinates(), null);
                if (!whatWeWantToBuild.equals(whatWeFailedToBuild)) {
                    waitingForGameState = true;
                    counter = 0;
                    expectPLACING_FREE_ROAD1 = true;
                    // D.ebugPrintln("!! PLAYING ROAD BUILDING CARD");
                    client.playDevCard(game, SOCDevCardConstants.ROADS);
                } else {
                    // We already tried to build this.
                    roadBuildingPlan = false;
                    cancelWrongPiecePlacementLocal(whatWeWantToBuild);
                // cancel sets whatWeWantToBuild = null;
                }
            } else {
                // D.ebugPrintln("$ PUSHING "+topPiece);
                buildingPlan.push(topPiece);
            }
        } else {
            // D.ebugPrintln("$ PUSHING "+topPiece);
            buildingPlan.push(topPiece);
        }
    }
    if (roadBuildingPlan) {
        // <---- Early return: Road Building dev card ----
        return;
    }
    // /
    // / figure out what resources we need
    // /
    SOCPossiblePiece targetPiece = buildingPlan.peek();
    // may be null
    SOCResourceSet targetResources = targetPiece.getResourcesToBuild();
    // D.ebugPrintln("^^^ targetPiece = "+targetPiece);
    // D.ebugPrintln("^^^ ourResources = "+ourPlayerData.getResources());
    negotiator.setTargetPiece(ourPlayerNumber, targetPiece);
    // /
    if (gameStatePLAY1 && (!ourPlayerData.hasPlayedDevCard()) && ourPlayerData.getInventory().hasPlayable(SOCDevCardConstants.DISC) && (rejectedPlayDevCardType != SOCDevCardConstants.DISC)) {
        if (chooseFreeResourcesIfNeeded(targetResources, 2, false)) {
            // /
            // / play the card
            // /
            expectWAITING_FOR_DISCOVERY = true;
            waitingForGameState = true;
            counter = 0;
            client.playDevCard(game, SOCDevCardConstants.DISC);
            pause(1500);
        }
    }
    if (!expectWAITING_FOR_DISCOVERY) {
        // /
        if (gameStatePLAY1 && (!ourPlayerData.hasPlayedDevCard()) && ourPlayerData.getInventory().hasPlayable(SOCDevCardConstants.MONO) && (rejectedPlayDevCardType != SOCDevCardConstants.MONO) && monopolyStrategy.decidePlayMonopoly()) {
            // /
            // / play the card
            // /
            expectWAITING_FOR_MONOPOLY = true;
            waitingForGameState = true;
            counter = 0;
            client.playDevCard(game, SOCDevCardConstants.MONO);
            pause(1500);
        }
        if (!expectWAITING_FOR_MONOPOLY) {
            if (gameStatePLAY1 && (!doneTrading) && (!ourPlayerData.getResources().contains(targetResources))) {
                waitingForTradeResponse = false;
                if (robotParameters.getTradeFlag() == 1) {
                    makeOffer(targetPiece);
                // makeOffer will set waitingForTradeResponse or doneTrading.
                }
            }
            if (gameStatePLAY1 && !waitingForTradeResponse) {
                /**
                 * trade with the bank/ports
                 */
                if (tradeToTarget2(targetResources)) {
                    counter = 0;
                    waitingForTradeMsg = true;
                    pause(1500);
                }
            }
            // /
            if ((!(waitingForTradeMsg || waitingForTradeResponse)) && ourPlayerData.getResources().contains(targetResources)) {
                // Remember that targetPiece == buildingPlan.peek().
                // Calls buildingPlan.pop().
                // Checks against whatWeFailedToBuild to see if server has rejected this already.
                // Calls client.buyDevCard or client.buildRequest.
                // Sets waitingForDevCard, or waitingForGameState and expectPLACING_SETTLEMENT (etc).
                // Sets waitingForPickSpecialItem if target piece is SOCPossiblePickSpecialItem.
                buildRequestPlannedPiece();
            }
        }
    }
}
Also used : SOCShip(soc.game.SOCShip) SOCResourceSet(soc.game.SOCResourceSet) SOCRoad(soc.game.SOCRoad)

Example 18 with SOCShip

use of soc.game.SOCShip 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)

Example 19 with SOCShip

use of soc.game.SOCShip 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 20 with SOCShip

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

the class SOCPlayerInterface method updateAtPutPiece.

/**
 * Handle updates after putting a piece on the board,
 * or moving a ship that was already placed.
 * Place or move the piece within our {@link SOCGame}
 * and visually on our {@link SOCBoardPanel}.
 *
 * @param mesPn  The piece's player number
 * @param coord  The piece's coordinate.  If <tt>isMove</tt>, the coordinate to move <em>from</em>.
 * @param pieceType  Piece type, like {@link SOCPlayingPiece#CITY}
 * @param isMove   If true, it's a move, not a new placement; valid only for ships.
 * @param moveToCoord  If <tt>isMove</tt>, the coordinate to move <em>to</em>.  Otherwise ignored.
 *
 * @see #updateAtPiecesChanged()
 * @since 2.0.00
 */
public void updateAtPutPiece(final int mesPn, final int coord, final int pieceType, final boolean isMove, final int moveToCoord) {
    // TODO consider more effic way for flushBoardLayoutAndRepaint, without the =null
    final SOCPlayer pl = (pieceType != SOCPlayingPiece.VILLAGE) ? game.getPlayer(mesPn) : null;
    final SOCPlayer oldLongestRoadPlayer = game.getPlayerWithLongestRoad();
    final SOCHandPanel mesHp = (pieceType != SOCPlayingPiece.VILLAGE) ? getPlayerHandPanel(mesPn) : null;
    final boolean[] debugShowPotentials = boardPanel.debugShowPotentials;
    final SOCPlayingPiece pp;
    switch(pieceType) {
        case SOCPlayingPiece.ROAD:
            pp = new SOCRoad(pl, coord, null);
            game.putPiece(pp);
            mesHp.updateValue(PlayerClientListener.UpdateType.Road);
            if (debugShowPotentials[4] || debugShowPotentials[5] || debugShowPotentials[7])
                boardPanel.flushBoardLayoutAndRepaint();
            break;
        case SOCPlayingPiece.SETTLEMENT:
            pp = new SOCSettlement(pl, coord, null);
            game.putPiece(pp);
            mesHp.updateValue(PlayerClientListener.UpdateType.Settlement);
            /**
             * if this is the second initial settlement, then update the resource display
             */
            mesHp.updateValue(PlayerClientListener.UpdateType.ResourceTotalAndDetails);
            if (debugShowPotentials[4] || debugShowPotentials[5] || debugShowPotentials[7] || debugShowPotentials[6])
                boardPanel.flushBoardLayoutAndRepaint();
            break;
        case SOCPlayingPiece.CITY:
            pp = new SOCCity(pl, coord, null);
            game.putPiece(pp);
            mesHp.updateValue(PlayerClientListener.UpdateType.Settlement);
            mesHp.updateValue(PlayerClientListener.UpdateType.City);
            if (debugShowPotentials[4] || debugShowPotentials[5] || debugShowPotentials[7] || debugShowPotentials[6])
                boardPanel.flushBoardLayoutAndRepaint();
            break;
        case SOCPlayingPiece.SHIP:
            pp = new SOCShip(pl, coord, null);
            if (!isMove) {
                game.putPiece(pp);
                mesHp.updateValue(PlayerClientListener.UpdateType.Ship);
            } else {
                game.moveShip((SOCShip) pp, moveToCoord);
                if (mesHp == clientHand)
                    // just in case; it probably wasn't enabled
                    mesHp.disableBankUndoButton();
            }
            if (debugShowPotentials[4] || debugShowPotentials[5] || debugShowPotentials[7])
                boardPanel.flushBoardLayoutAndRepaint();
            break;
        case SOCPlayingPiece.VILLAGE:
            // no need to refresh boardPanel after receiving each village
            pp = new SOCVillage(coord, game.getBoard());
            game.putPiece(pp);
            // <--- Early return: Piece is part of board initial layout, not player info ---
            return;
        case SOCPlayingPiece.FORTRESS:
            pp = new SOCFortress(pl, coord, game.getBoard());
            game.putPiece(pp);
            // <--- Early return: Piece is part of board initial layout, not added during game ---
            return;
        default:
            chatPrintDebug("* Unknown piece type " + pieceType + " at coord 0x" + Integer.toHexString(coord));
            // <--- Early return ---
            return;
    }
    mesHp.updateValue(PlayerClientListener.UpdateType.VictoryPoints);
    boardPanel.repaint();
    buildingPanel.updateButtonStatus();
    if (game.isDebugFreePlacement() && game.isInitialPlacement())
        // update here, since gamestate doesn't change to trigger update
        boardPanel.updateMode();
    if (hasCalledBegan && (game.getGameState() >= SOCGame.START1A))
        playSound(SOUND_PUT_PIECE);
    /**
     * Check for and announce change in longest road; update all players' victory points.
     */
    SOCPlayer newLongestRoadPlayer = game.getPlayerWithLongestRoad();
    if (newLongestRoadPlayer != oldLongestRoadPlayer) {
        updateLongestLargest(true, oldLongestRoadPlayer, newLongestRoadPlayer);
    }
}
Also used : SOCSettlement(soc.game.SOCSettlement) SOCVillage(soc.game.SOCVillage) SOCCity(soc.game.SOCCity) SOCPlayingPiece(soc.game.SOCPlayingPiece) SOCShip(soc.game.SOCShip) SOCPlayer(soc.game.SOCPlayer) SOCFortress(soc.game.SOCFortress) SOCRoad(soc.game.SOCRoad)

Aggregations

SOCShip (soc.game.SOCShip)27 SOCRoad (soc.game.SOCRoad)17 SOCPlayer (soc.game.SOCPlayer)12 SOCSettlement (soc.game.SOCSettlement)11 SOCCity (soc.game.SOCCity)10 SOCFortress (soc.game.SOCFortress)8 SOCBoardLarge (soc.game.SOCBoardLarge)6 SOCBoard (soc.game.SOCBoard)4 SOCPlayingPiece (soc.game.SOCPlayingPiece)3 SOCResourceSet (soc.game.SOCResourceSet)3 ArrayList (java.util.ArrayList)2 SOCGame (soc.game.SOCGame)2 SOCVillage (soc.game.SOCVillage)2 Graphics2D (java.awt.Graphics2D)1 Image (java.awt.Image)1 BufferedImage (java.awt.image.BufferedImage)1 Vector (java.util.Vector)1 SOCInventoryItem (soc.game.SOCInventoryItem)1 SOCAcceptOffer (soc.message.SOCAcceptOffer)1 SOCChoosePlayerRequest (soc.message.SOCChoosePlayerRequest)1