use of soc.game.SOCRoad in project JSettlers2 by jdmonin.
the class SOCPlayerTracker method updateThreats.
/**
* update threats for pieces that need to be updated
*
* @param trackers all of the player trackers
*/
public void updateThreats(HashMap<Integer, SOCPlayerTracker> trackers) {
// D.ebugPrintln("&&&& updateThreats");
/**
* check roads that need updating and don't have necessary roads
*/
SOCBoard board = game.getBoard();
Iterator<SOCPossibleRoad> posRoadsIter = possibleRoads.values().iterator();
while (posRoadsIter.hasNext()) {
SOCPossibleRoad posRoad = posRoadsIter.next();
if ((!posRoad.isThreatUpdated()) && posRoad.getNecessaryRoads().isEmpty()) {
// D.ebugPrintln("&&&& examining road at "+Integer.toHexString(posRoad.getCoordinates()));
/**
* look for possible settlements that can block this road
*/
final int[] adjNodesToPosRoad = board.getAdjacentNodesToEdge_arr(posRoad.getCoordinates());
Enumeration<Integer> adjEdgeEnum = board.getAdjacentEdgesToEdge(posRoad.getCoordinates()).elements();
while (adjEdgeEnum.hasMoreElements()) {
final int adjEdge = adjEdgeEnum.nextElement().intValue();
Enumeration<SOCRoad> realRoadEnum = player.getRoads().elements();
while (realRoadEnum.hasMoreElements()) {
SOCRoad realRoad = realRoadEnum.nextElement();
if (adjEdge == realRoad.getCoordinates()) {
/**
* found an adjacent supporting road, now find the node between
* the supporting road and the possible road
*/
final int[] adjNodesToRealRoad = realRoad.getAdjacentNodes();
for (int pi = 0; pi < 2; ++pi) {
final int adjNodeToPosRoad = adjNodesToPosRoad[pi];
for (int ri = 0; ri < 2; ++ri) {
final int adjNodeToRealRoad = adjNodesToRealRoad[ri];
if (adjNodeToPosRoad == adjNodeToRealRoad) {
/**
* we found the common node
* now see if there is a possible enemy settlement
*/
final Integer adjNodeToPosRoadInt = Integer.valueOf(adjNodeToPosRoad);
Iterator<SOCPlayerTracker> trackersIter = trackers.values().iterator();
while (trackersIter.hasNext()) {
SOCPlayerTracker tracker = trackersIter.next();
if (tracker.getPlayer().getPlayerNumber() != playerNumber) {
SOCPossibleSettlement posEnemySet = tracker.getPossibleSettlements().get(adjNodeToPosRoadInt);
if (posEnemySet != null) {
/**
* we found a settlement that threatens our possible road
*/
// D.ebugPrintln("&&&& adding threat from settlement at "+Integer.toHexString(posEnemySet.getCoordinates()));
posRoad.addThreat(posEnemySet);
}
}
}
}
}
}
}
}
}
/**
* look for enemy roads that can block this road
*/
Iterator<SOCPlayerTracker> trackersIter = trackers.values().iterator();
while (trackersIter.hasNext()) {
SOCPlayerTracker tracker = trackersIter.next();
if (tracker.getPlayer().getPlayerNumber() != playerNumber) {
SOCPossibleRoad posEnemyRoad = tracker.getPossibleRoads().get(Integer.valueOf(posRoad.getCoordinates()));
if (posEnemyRoad != null) {
/**
* we found a road that threatens our possible road
*/
// D.ebugPrintln("&&&& adding threat from road at "+Integer.toHexString(posEnemyRoad.getCoordinates()));
posRoad.addThreat(posEnemyRoad);
}
}
}
/**
* look at all of the roads that this possible road supports.
* if any of those roads are solely dependent on this
* possible road, then all of the possible pieces that
* threaten this road, also threaten those pieces
*/
final List<SOCPossiblePiece> threats = posRoad.getThreats();
final Stack<SOCPossiblePiece> stack = new Stack<SOCPossiblePiece>();
stack.push(posRoad);
while (!stack.empty()) {
SOCPossiblePiece curPosPiece = stack.pop();
if ((curPosPiece.getType() == SOCPossiblePiece.ROAD) || ((curPosPiece instanceof SOCPossibleShip) && ((SOCPossibleShip) curPosPiece).isCoastalRoadAndShip)) {
for (SOCPossiblePiece newPosPiece : ((SOCPossibleRoad) curPosPiece).getNewPossibilities()) {
if ((newPosPiece.getType() == SOCPossiblePiece.ROAD) || ((newPosPiece instanceof SOCPossibleShip) && ((SOCPossibleShip) newPosPiece).isCoastalRoadAndShip)) {
final List<SOCPossibleRoad> necRoadList = ((SOCPossibleRoad) newPosPiece).getNecessaryRoads();
if ((necRoadList.size() == 1) && (necRoadList.get(0) == curPosPiece)) {
// D.ebugPrintln("&&&& adding threats to road at "+Integer.toHexString(newPosPiece.getCoordinates()));
for (SOCPossiblePiece threat : threats) ((SOCPossibleRoad) newPosPiece).addThreat(threat);
}
/**
* put this piece on the stack
*/
stack.push(newPosPiece);
}
}
}
}
// D.ebugPrintln("&&&& done updating road at "+Integer.toHexString(posRoad.getCoordinates()));
posRoad.threatUpdated();
}
}
/**
* check roads that need updating and DO have necessary roads
*/
posRoadsIter = possibleRoads.values().iterator();
while (posRoadsIter.hasNext()) {
SOCPossibleRoad posRoad = posRoadsIter.next();
if (!posRoad.isThreatUpdated()) {
// D.ebugPrintln("&&&& examining road at "+Integer.toHexString(posRoad.getCoordinates()));
/**
* check for enemy roads with
* the same coordinates
*/
Iterator<SOCPlayerTracker> trackersIter = trackers.values().iterator();
while (trackersIter.hasNext()) {
SOCPlayerTracker tracker = trackersIter.next();
if (tracker.getPlayer().getPlayerNumber() != playerNumber) {
SOCPossibleRoad posEnemyRoad = tracker.getPossibleRoads().get(Integer.valueOf(posRoad.getCoordinates()));
if (posEnemyRoad != null) {
/**
* we found a road that threatens our possible road
*/
// D.ebugPrintln("&&&& adding threat from road at "+Integer.toHexString(posEnemyRoad.getCoordinates()));
posRoad.addThreat(posEnemyRoad);
posRoad.threatUpdated();
}
}
}
/**
* look for possible settlements that can block this road
*/
/**
* if this road has only one supporting road,
* find the node between this and the supporting road
*/
final List<SOCPossibleRoad> necRoadList = posRoad.getNecessaryRoads();
if (necRoadList.size() == 1) {
final SOCPossibleRoad necRoad = necRoadList.get(0);
final int[] adjNodes1 = board.getAdjacentNodesToEdge_arr(posRoad.getCoordinates());
for (int i1 = 0; i1 < 2; ++i1) {
final int adjNode1 = adjNodes1[i1];
final int[] adjNodes2 = board.getAdjacentNodesToEdge_arr(necRoad.getCoordinates());
for (int i2 = 0; i2 < 2; ++i2) {
final int adjNode2 = adjNodes2[i2];
if (adjNode1 == adjNode2) {
/**
* see if there is a possible enemy settlement at
* the node between the two possible roads
*/
trackersIter = trackers.values().iterator();
final Integer adjNodeInt = Integer.valueOf(adjNode1);
while (trackersIter.hasNext()) {
SOCPlayerTracker tracker = trackersIter.next();
if (tracker.getPlayer().getPlayerNumber() != playerNumber) {
SOCPossibleSettlement posEnemySet = tracker.getPossibleSettlements().get(adjNodeInt);
if (posEnemySet != null) {
/**
* we found a settlement that threatens our possible road
*/
// D.ebugPrintln("&&&& adding threat from settlement at "+Integer.toHexString(posEnemySet.getCoordinates()));
posRoad.addThreat(posEnemySet);
}
}
}
}
}
}
}
// D.ebugPrintln("&&&& done updating road at "+Integer.toHexString(posRoad.getCoordinates()));
posRoad.threatUpdated();
}
}
/**
* check settlements that need updating
*/
Iterator<SOCPossibleSettlement> posSetsIter = possibleSettlements.values().iterator();
while (posSetsIter.hasNext()) {
SOCPossibleSettlement posSet = posSetsIter.next();
if (!posSet.isThreatUpdated()) {
// D.ebugPrintln("&&&& examining settlement at "+Integer.toHexString(posSet.getCoordinates()));
/**
* see if there are enemy settlements with the same coords
*/
Iterator<SOCPlayerTracker> trackersIter = trackers.values().iterator();
while (trackersIter.hasNext()) {
SOCPlayerTracker tracker = trackersIter.next();
if (tracker.getPlayer().getPlayerNumber() != playerNumber) {
SOCPossibleSettlement posEnemySet = tracker.getPossibleSettlements().get(Integer.valueOf(posSet.getCoordinates()));
if (posEnemySet != null) {
// D.ebugPrintln("&&&& adding threat from settlement at "+Integer.toHexString(posEnemySet.getCoordinates()));
posSet.addThreat(posEnemySet);
}
}
}
//
// if this settlement doesn't rely on anything, then we're done
//
final List<SOCPossibleRoad> necRoadList = posSet.getNecessaryRoads();
if (necRoadList.isEmpty()) {
;
} else if (necRoadList.size() == 1) {
for (SOCPossiblePiece nrThreat : necRoadList.get(0).getThreats()) posSet.addThreat(nrThreat);
} else {
//
// this settlement relies on more than one road.
// if all of the roads have the same threat,
// then add that threat to this settlement
//
final SOCPossibleRoad nr = necRoadList.get(0);
for (SOCPossiblePiece nrThreat : nr.getThreats()) {
boolean allHaveIt = true;
for (SOCPossibleRoad nr2 : necRoadList) {
if ((nr2 != nr) && !nr2.getThreats().contains(nrThreat)) {
allHaveIt = false;
break;
}
}
if (allHaveIt) {
// D.ebugPrintln("&&&& adding threat from "+Integer.toHexString(nrThreat.getCoordinates()));
posSet.addThreat(nrThreat);
}
}
}
// D.ebugPrintln("&&&& done updating settlement at "+Integer.toHexString(posSet.getCoordinates()));
posSet.threatUpdated();
}
}
}
use of soc.game.SOCRoad in project JSettlers2 by jdmonin.
the class SOCPlayerTracker method addOurNewSettlement.
/**
* Add one of our settlements, and newly possible pieces from it.
* Adds a new possible city; removes conflicting possible settlements (ours or other players).
* On the large Sea board, if this is a coastal settlement adds newly possible ships, and if
* we've just settled a new island, newly possible roads, because the coastal settlement is
* a roads {@literal <->} ships transition.
*<P>
* Newly possible roads or ships next to the settlement are expanded by calling
* {@link #expandRoadOrShip(SOCPossibleRoad, SOCPlayer, SOCPlayer, HashMap, int)}.
* {@link #EXPAND_LEVEL} is the basic expansion length, and ships add
* {@link #EXPAND_LEVEL_SHIP_EXTRA} to that for crossing the sea to nearby islands.
*<P>
* Called in 2 different conditions:
*<UL>
* <LI> To track an actual (not possible) settlement that's just been placed
* <LI> To see the effects of trying to placing a possible settlement, in a copy of the PlayerTracker
* ({@link #tryPutPiece(SOCPlayingPiece, SOCGame, HashMap)})
*</UL>
*
* @param settlement the new settlement
* @param trackers player trackers for all of the players
*/
public synchronized void addOurNewSettlement(SOCSettlement settlement, HashMap<Integer, SOCPlayerTracker> trackers) {
// D.ebugPrintln();
D.ebugPrintln("$$$ addOurNewSettlement : " + settlement);
SOCBoard board = game.getBoard();
final Integer settlementCoords = Integer.valueOf(settlement.getCoordinates());
/**
* add a new possible city
*/
possibleCities.put(settlementCoords, new SOCPossibleCity(player, settlement.getCoordinates()));
/**
* see if the new settlement was a possible settlement in
* the list. if so, remove it.
*/
SOCPossibleSettlement ps = possibleSettlements.get(settlementCoords);
if (ps != null) {
D.ebugPrintln("$$$ was a possible settlement");
/**
* copy a list of all the conflicting settlements
*/
List<SOCPossibleSettlement> conflicts = new ArrayList<SOCPossibleSettlement>(ps.getConflicts());
/**
* remove the possible settlement that is now a real settlement
*/
D.ebugPrintln("$$$ removing " + Integer.toHexString(settlement.getCoordinates()));
possibleSettlements.remove(settlementCoords);
removeFromNecessaryRoads(ps);
/**
* remove possible settlements that this one cancels out
*/
for (SOCPossibleSettlement conflict : conflicts) {
D.ebugPrintln("$$$ checking conflict with " + conflict.getPlayer().getPlayerNumber() + ":" + Integer.toHexString(conflict.getCoordinates()));
SOCPlayerTracker tracker = trackers.get(Integer.valueOf(conflict.getPlayer().getPlayerNumber()));
if (tracker != null) {
D.ebugPrintln("$$$ removing " + Integer.toHexString(conflict.getCoordinates()));
tracker.getPossibleSettlements().remove(Integer.valueOf(conflict.getCoordinates()));
removeFromNecessaryRoads(conflict);
/**
* remove the conflicts that this settlement made
*/
for (SOCPossibleSettlement otherConflict : conflict.getConflicts()) {
D.ebugPrintln("$$$ removing conflict " + Integer.toHexString(conflict.getCoordinates()) + " from " + Integer.toHexString(otherConflict.getCoordinates()));
otherConflict.removeConflict(conflict);
}
}
}
} else {
/**
* if the new settlement wasn't a possible settlement,
* we still need to cancel out other players possible settlements
*/
D.ebugPrintln("$$$ wasn't possible settlement");
ArrayList<SOCPossibleSettlement> trash = new ArrayList<SOCPossibleSettlement>();
List<Integer> adjNodes = board.getAdjacentNodesToNode(settlement.getCoordinates());
Iterator<SOCPlayerTracker> trackersIter = trackers.values().iterator();
while (trackersIter.hasNext()) {
SOCPlayerTracker tracker = trackersIter.next();
SOCPossibleSettlement posSet = tracker.getPossibleSettlements().get(settlementCoords);
D.ebugPrintln("$$$ tracker for player " + tracker.getPlayer().getPlayerNumber());
/**
* check the node that the settlement is on
*/
D.ebugPrintln("$$$ checking node " + Integer.toHexString(settlement.getCoordinates()));
if (posSet != null) {
D.ebugPrintln("$$$ trashing " + Integer.toHexString(posSet.getCoordinates()));
trash.add(posSet);
/**
* remove the conflicts that this settlement made
*/
for (SOCPossibleSettlement conflict : posSet.getConflicts()) {
D.ebugPrintln("$$$ removing conflict " + Integer.toHexString(posSet.getCoordinates()) + " from " + Integer.toHexString(conflict.getCoordinates()));
conflict.removeConflict(posSet);
}
}
/**
* check adjacent nodes
*/
for (Integer adjNode : adjNodes) {
D.ebugPrintln("$$$ checking node " + Integer.toHexString(adjNode.intValue()));
posSet = tracker.getPossibleSettlements().get(adjNode);
if (posSet != null) {
D.ebugPrintln("$$$ trashing " + Integer.toHexString(posSet.getCoordinates()));
trash.add(posSet);
/**
* remove the conflicts that this settlement made
*/
for (SOCPossibleSettlement conflict : posSet.getConflicts()) {
D.ebugPrintln("$$$ removing conflict " + Integer.toHexString(posSet.getCoordinates()) + " from " + Integer.toHexString(conflict.getCoordinates()));
conflict.removeConflict(posSet);
}
}
}
/**
* take out the trash
* (no-longer-possible settlements, roads that support it)
*/
D.ebugPrintln("$$$ removing trash for " + tracker.getPlayer().getPlayerNumber());
for (SOCPossibleSettlement pset : trash) {
D.ebugPrintln("$$$ removing " + Integer.toHexString(pset.getCoordinates()) + " owned by " + pset.getPlayer().getPlayerNumber());
tracker.getPossibleSettlements().remove(Integer.valueOf(pset.getCoordinates()));
removeFromNecessaryRoads(pset);
}
trash.clear();
}
}
/**
* Add possible road-ship transitions made possible by the new settlement.
* Normally a new settlement placement doesn't need to add possible roads or ships,
* because each road/ship placement adds possibles past the new far end of the route
* in addOurNewRoadOrShip.
*/
if (board instanceof SOCBoardLarge) {
ArrayList<SOCPossibleRoad> roadsToExpand = null;
/**
* Only add new possible roads if we're on a new island
* (that is, the newly placed settlement has no adjacent roads already).
* Coastal ships/roads may still be added even if settleAlreadyHasRoad.
*/
boolean settleAlreadyHasRoad = false;
ArrayList<SOCPossibleRoad> possibleNewIslandRoads = null;
final List<Integer> adjacEdges = board.getAdjacentEdgesToNode(settlementCoords);
// First, loop to check for settleAlreadyHasRoad
for (Integer edge : adjacEdges) {
if (possibleRoads.get(edge) != null)
// already a possible road or ship here
continue;
SOCRoad road = board.roadAtEdge(edge);
if ((road != null) && road.isRoadNotShip()) {
settleAlreadyHasRoad = true;
break;
}
}
// Now, possibly add new roads/ships/coastals
for (Integer edge : adjacEdges) {
// TODO remove these debug prints soon
// System.err.println("L1348: examine edge 0x"
// + Integer.toHexString(edge) + " for placed settle 0x"
// + Integer.toHexString(settlementCoords));
SOCPossibleRoad pRoad = possibleRoads.get(edge);
if (pRoad != null) {
// already a possible road or ship
continue;
}
if (board.roadAtEdge(edge) != null) {
// not new, something's already there
continue;
}
if (player.isPotentialRoad(edge)) {
// Add newly possible roads from settlement placement.
// Probably won't need to happen (usually added in addOurNewRoadOrShip, see newPossibleRoads)
// but could on a new island's first settlement
final boolean isCoastline = player.isPotentialShip(edge);
if (settleAlreadyHasRoad && !isCoastline)
continue;
if (possibleNewIslandRoads == null)
possibleNewIslandRoads = new ArrayList<SOCPossibleRoad>();
possibleNewIslandRoads.add((isCoastline) ? new SOCPossibleShip(player, edge, true, null) : new SOCPossibleRoad(player, edge, null));
if (isCoastline)
System.err.println("L1675: " + toString() + ": new PossibleShip(true) at 0x" + Integer.toHexString(edge));
} else if (player.isPotentialShip(edge)) {
// A way out to a new island
SOCPossibleShip newPS = new SOCPossibleShip(player, edge, false, null);
possibleRoads.put(edge, newPS);
System.err.println("L1685: " + toString() + ": new PossibleShip(false) at 0x" + Integer.toHexString(edge) + " from coastal settle 0x" + Integer.toHexString(settlementCoords));
if (roadsToExpand == null)
roadsToExpand = new ArrayList<SOCPossibleRoad>();
roadsToExpand.add(newPS);
newPS.setExpandedFlag();
}
}
if ((possibleNewIslandRoads != null) && !game.isInitialPlacement()) {
// (Make sure this isn't initial placement, where nothing has adjacent roads)
for (SOCPossibleRoad pr : possibleNewIslandRoads) {
possibleRoads.put(Integer.valueOf(pr.getCoordinates()), pr);
System.err.println("L1396: new possible road at edge 0x" + Integer.toHexString(pr.getCoordinates()) + " from coastal settle 0x" + Integer.toHexString(settlementCoords));
if (roadsToExpand == null)
roadsToExpand = new ArrayList<SOCPossibleRoad>();
roadsToExpand.add(pr);
pr.setExpandedFlag();
}
}
if (roadsToExpand != null) {
//
// expand possible ships/roads that we've added
//
SOCPlayer dummy = new SOCPlayer(player);
for (SOCPossibleRoad expandPR : roadsToExpand) {
final int expand = EXPAND_LEVEL + (expandPR.isRoadNotShip() ? 0 : EXPAND_LEVEL_SHIP_EXTRA);
expandRoadOrShip(expandPR, player, dummy, trackers, expand);
}
dummy.destroyPlayer();
}
}
}
use of soc.game.SOCRoad 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);
}
}
use of soc.game.SOCRoad 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);
}
}
use of soc.game.SOCRoad 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();
}
}
}
}
Aggregations