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);
}
}
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();
}
}
}
}
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;
}
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;
}
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);
}
}
Aggregations