use of soc.game.SOCBoard in project JSettlers2 by jdmonin.
the class SOCRobotBrain method trackNewSettlement.
/**
* Run a newly placed settlement through the playerTrackers.
* Called only after {@link SOCGame#putPiece(SOCPlayingPiece)}
* or {@link SOCGame#putTempPiece(SOCPlayingPiece)}.
*<P>
* During initial board setup, settlements aren't tracked when placed.
* They are deferred until their corresponding road placement, in case
* a human player decides to cancel their settlement and place it elsewhere.
*
* During normal play, the settlements are tracked immediately when placed.
*
* (Code previously in body of the run method.)
* Placing the code in its own method allows tracking that settlement when the
* road's putPiece message arrives.
*
* @param newSettlement The newly placed settlement for the playerTrackers
* @param isCancel Is this our own robot's settlement placement, rejected by the server?
* If so, this method call will cancel its placement within the game data / robot data.
*/
protected void trackNewSettlement(SOCSettlement newSettlement, final boolean isCancel) {
Iterator<SOCPlayerTracker> trackersIter = playerTrackers.values().iterator();
while (trackersIter.hasNext()) {
SOCPlayerTracker tracker = trackersIter.next();
if (!isCancel)
tracker.addNewSettlement(newSettlement, playerTrackers);
else
tracker.cancelWrongSettlement(newSettlement);
}
trackersIter = playerTrackers.values().iterator();
while (trackersIter.hasNext()) {
SOCPlayerTracker tracker = trackersIter.next();
Iterator<SOCPossibleRoad> posRoadsIter = tracker.getPossibleRoads().values().iterator();
while (posRoadsIter.hasNext()) {
posRoadsIter.next().clearThreats();
}
Iterator<SOCPossibleSettlement> posSetsIter = tracker.getPossibleSettlements().values().iterator();
while (posSetsIter.hasNext()) {
posSetsIter.next().clearThreats();
}
}
trackersIter = playerTrackers.values().iterator();
while (trackersIter.hasNext()) {
SOCPlayerTracker tracker = trackersIter.next();
tracker.updateThreats(playerTrackers);
}
if (isCancel) {
// <--- Early return, nothing else to do ---
return;
}
// /
// / see if this settlement bisected someone else's road
// /
// Length should be SOCGame.MAXPLAYERS
int[] roadCount = { 0, 0, 0, 0, 0, 0 };
SOCBoard board = game.getBoard();
Enumeration<Integer> adjEdgeEnum = board.getAdjacentEdgesToNode(newSettlement.getCoordinates()).elements();
while (adjEdgeEnum.hasMoreElements()) {
final int adjEdge = adjEdgeEnum.nextElement().intValue();
Enumeration<SOCRoad> roadEnum = board.getRoads().elements();
while (roadEnum.hasMoreElements()) {
SOCRoad road = roadEnum.nextElement();
if (road.getCoordinates() == adjEdge) {
final int roadPN = road.getPlayerNumber();
roadCount[roadPN]++;
if (roadCount[roadPN] == 2) {
if (roadPN != ourPlayerNumber) {
// /
// / this settlement bisects another players road
// /
trackersIter = playerTrackers.values().iterator();
while (trackersIter.hasNext()) {
SOCPlayerTracker tracker = trackersIter.next();
if (tracker.getPlayer().getPlayerNumber() == roadPN) {
// D.ebugPrintln("$$ updating LR Value for player "+tracker.getPlayer().getPlayerNumber());
// tracker.updateLRValues();
}
// tracker.recalcLongestRoadETA();
}
}
break;
}
}
}
}
final int pNum = newSettlement.getPlayerNumber();
// /
// / update the speedups from possible settlements
// /
trackersIter = playerTrackers.values().iterator();
while (trackersIter.hasNext()) {
SOCPlayerTracker tracker = trackersIter.next();
if (tracker.getPlayer().getPlayerNumber() == pNum) {
Iterator<SOCPossibleSettlement> posSetsIter = tracker.getPossibleSettlements().values().iterator();
while (posSetsIter.hasNext()) {
posSetsIter.next().updateSpeedup();
}
break;
}
}
// /
// / update the speedups from possible cities
// /
trackersIter = playerTrackers.values().iterator();
while (trackersIter.hasNext()) {
SOCPlayerTracker tracker = trackersIter.next();
if (tracker.getPlayer().getPlayerNumber() == pNum) {
Iterator<SOCPossibleCity> posCitiesIter = tracker.getPossibleCities().values().iterator();
while (posCitiesIter.hasNext()) {
posCitiesIter.next().updateSpeedup();
}
break;
}
}
}
use of soc.game.SOCBoard 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;
}
}
use of soc.game.SOCBoard in project JSettlers2 by jdmonin.
the class SOCPlayerTracker method updateSettlementConflicts.
/**
* update settlement conflicts
*
* @param ps a possible settlement
* @param trackers player trackers for all players
*/
protected void updateSettlementConflicts(SOCPossibleSettlement ps, HashMap<Integer, SOCPlayerTracker> trackers) {
// D.ebugPrintln("$$$ updateSettlementConflicts : "+Integer.toHexString(ps.getCoordinates()));
/**
* look at all adjacent nodes and update possible settlements on nodes
*/
Iterator<SOCPlayerTracker> trackersIter = trackers.values().iterator();
SOCBoard board = game.getBoard();
while (trackersIter.hasNext()) {
SOCPlayerTracker tracker = trackersIter.next();
/**
* if it's not our tracker...
*/
if (tracker.getPlayer().getPlayerNumber() != ps.getPlayer().getPlayerNumber()) {
SOCPossibleSettlement posSet = tracker.getPossibleSettlements().get(Integer.valueOf(ps.getCoordinates()));
if (posSet != null) {
// D.ebugPrintln("$$$ add conflict "+Integer.toHexString(posSet.getCoordinates()));
ps.addConflict(posSet);
posSet.addConflict(ps);
}
}
/**
* now look at adjacent settlements
*/
for (Integer adjNode : board.getAdjacentNodesToNode(ps.getCoordinates())) {
SOCPossibleSettlement posSet = tracker.getPossibleSettlements().get(adjNode);
if (posSet != null) {
// D.ebugPrintln("$$$ add conflict "+Integer.toHexString(posSet.getCoordinates()));
ps.addConflict(posSet);
posSet.addConflict(ps);
}
}
}
}
use of soc.game.SOCBoard in project JSettlers2 by jdmonin.
the class SOCPlayerTracker method recalcWinGameETA.
/**
* Recalculate the tracked player's ETA for winning the game (WGETA) by making and simulating with a copy
* of our current potential settlement/city locations, building speed estimates (BSEs), and dice numbers,
* looping from player's current {@link SOCPlayer#getTotalVP()} to {@link SOCGame#vp_winner}.
*<P>
* Calculates the fields for {@link #getWinGameETA()}, {@link #needsLA()}, {@link #needsLR()}.
*<P>
* Each time through the loop, given potential locations and available pieces, pick the fastest ETA
* among each of these 2-VP combinations:
*<UL>
* <LI> 2 settlements (including necessary roads' ETA)
* <LI> 2 cities
* <LI> 1 city, 1 settlement (+ roads)
* <LI> 1 settlement (+ roads), 1 city
* <LI> Buy enough cards for Largest Army
* <LI> Build enough roads for Longest Road
*</UL>
* The temporary potential sets, port trade flags, BSEs and dice numbers are updated with the picked pieces.
* The loop body doesn't add new potential roads/ships or potential settlements to its copy of those sets,
* or call {@link #expandRoadOrShip(SOCPossibleRoad, SOCPlayer, SOCPlayer, HashMap, int)}, so it may run out
* of potential locations before {@code vp_winner} is reached. If the loop doesn't have the locations or
* pieces to do anything, 500 ETA and 2 VP are added to the totals to keep things moving.
*<P>
* If the loop reaches {@link SOCGame#vp_winner} - 1, it calculates ETAs for 1 city or settlement (+ roads)
* instead of 2, and Largest Army and Longest Road, to make its choice.
*/
public void recalcWinGameETA() {
int oldWGETA = winGameETA;
try {
needLR = false;
needLA = false;
winGameETA = 0;
SOCPlayerNumbers tempPlayerNumbers = new SOCPlayerNumbers(player.getNumbers());
boolean[] tempPortFlags = new boolean[SOCBoard.WOOD_PORT + 1];
for (int portType = SOCBoard.MISC_PORT; portType <= SOCBoard.WOOD_PORT; portType++) {
tempPortFlags[portType] = player.getPortFlag(portType);
}
SOCBuildingSpeedEstimate[] tempSetBSE = new SOCBuildingSpeedEstimate[2];
SOCBuildingSpeedEstimate[] tempCityBSE = new SOCBuildingSpeedEstimate[2];
tempCityBSE[0] = new SOCBuildingSpeedEstimate();
tempCityBSE[1] = new SOCBuildingSpeedEstimate();
tempSetBSE[0] = new SOCBuildingSpeedEstimate();
tempSetBSE[1] = new SOCBuildingSpeedEstimate();
int[][] chosenSetBuildingSpeed = new int[2][SOCBuildingSpeedEstimate.MAXPLUSONE];
int[][] chosenCityBuildingSpeed = new int[2][SOCBuildingSpeedEstimate.MAXPLUSONE];
SOCBuildingSpeedEstimate tempBSE = new SOCBuildingSpeedEstimate();
SOCBuildingSpeedEstimate ourBSE = new SOCBuildingSpeedEstimate(player.getNumbers());
int[] ourBuildingSpeed = ourBSE.getEstimatesFromNothingFast(tempPortFlags);
int cityETA = ourBuildingSpeed[SOCBuildingSpeedEstimate.CITY];
int settlementETA = ourBuildingSpeed[SOCBuildingSpeedEstimate.SETTLEMENT];
int roadETA = ourBuildingSpeed[SOCBuildingSpeedEstimate.ROAD];
int cardETA = ourBuildingSpeed[SOCBuildingSpeedEstimate.CARD];
// TODO shipETA, when ready
int settlementPiecesLeft = player.getNumPieces(SOCPlayingPiece.SETTLEMENT);
int cityPiecesLeft = player.getNumPieces(SOCPlayingPiece.CITY);
int citySpotsLeft = possibleCities.size();
boolean haveLA = false;
boolean haveLR = false;
int tempLargestArmyETA = largestArmyETA;
int tempLongestRoadETA = longestRoadETA;
SOCPlayer laPlayer = game.getPlayerWithLargestArmy();
SOCPlayer lrPlayer = game.getPlayerWithLongestRoad();
final SOCBoard board = game.getBoard();
if (D.ebugOn) {
if (laPlayer != null) {
D.ebugPrintln("laPlayer # = " + laPlayer.getPlayerNumber());
} else {
D.ebugPrintln("laPlayer = null");
}
if (lrPlayer != null) {
D.ebugPrintln("lrPlayer # = " + lrPlayer.getPlayerNumber());
} else {
D.ebugPrintln("lrPlayer = null");
}
}
if ((laPlayer != null) && (playerNumber == laPlayer.getPlayerNumber())) {
haveLA = true;
}
if ((lrPlayer != null) && (playerNumber == lrPlayer.getPlayerNumber())) {
haveLR = true;
}
TreeMap<Integer, SOCPossibleSettlement> posSetsCopy = new TreeMap<Integer, SOCPossibleSettlement>(possibleSettlements);
TreeMap<Integer, SOCPossibleCity> posCitiesCopy = new TreeMap<Integer, SOCPossibleCity>(possibleCities);
int points = player.getTotalVP();
int fastestETA;
final int vp_winner = game.vp_winner;
while (points < vp_winner) {
D.ebugPrintln("WWW points = " + points);
D.ebugPrintln("WWW settlementPiecesLeft = " + settlementPiecesLeft);
D.ebugPrintln("WWW cityPiecesLeft = " + cityPiecesLeft);
D.ebugPrintln("WWW settlementSpotsLeft = " + posSetsCopy.size());
D.ebugPrintln("WWW citySpotsLeft = " + posCitiesCopy.size());
if (D.ebugOn) {
D.ebugPrint("WWW tempPortFlags: ");
for (int portType = SOCBoard.MISC_PORT; portType <= SOCBoard.WOOD_PORT; portType++) {
D.ebugPrint(tempPortFlags[portType] + " ");
}
D.ebugPrintln();
}
D.ebugPrintln("WWW settlementETA = " + settlementETA);
D.ebugPrintln("WWW cityETA = " + cityETA);
D.ebugPrintln("WWW roadETA = " + roadETA);
D.ebugPrintln("WWW cardETA = " + cardETA);
if (points == (vp_winner - 1)) {
fastestETA = 500;
SOCPossibleSettlement chosenSet = null;
if ((settlementPiecesLeft > 0) && (!posSetsCopy.isEmpty())) {
Iterator<SOCPossibleSettlement> posSetsIter = posSetsCopy.values().iterator();
while (posSetsIter.hasNext()) {
SOCPossibleSettlement posSet = posSetsIter.next();
int posSetETA = settlementETA + (posSet.getNumberOfNecessaryRoads() * roadETA);
if (posSetETA < fastestETA) {
fastestETA = posSetETA;
chosenSet = posSet;
}
}
// /
if (chosenSet != null) {
final int totalNecRoads = calcTotalNecessaryRoads(chosenSet);
fastestETA = (settlementETA + (totalNecRoads * roadETA));
D.ebugPrintln("WWW # necesesary roads = " + totalNecRoads);
D.ebugPrintln("WWW this settlement eta = " + (settlementETA + (totalNecRoads * roadETA)));
D.ebugPrintln("WWW settlement is " + chosenSet);
D.ebugPrintln("WWW settlement eta = " + fastestETA);
} else {
fastestETA = 500;
}
}
if ((cityPiecesLeft > 0) && (citySpotsLeft > 0) && (cityETA <= fastestETA)) {
D.ebugPrintln("WWW city eta = " + cityETA);
fastestETA = cityETA;
}
if (!haveLA && !needLA && (tempLargestArmyETA < fastestETA)) {
D.ebugPrintln("WWW LA eta = " + tempLargestArmyETA);
fastestETA = tempLargestArmyETA;
}
if (!haveLR && !needLR && (tempLongestRoadETA < fastestETA)) {
D.ebugPrintln("WWW LR eta = " + tempLongestRoadETA);
fastestETA = tempLongestRoadETA;
}
if (!haveLR && !needLR && (fastestETA == tempLongestRoadETA)) {
needLR = true;
if (brain.getDRecorder().isOn()) {
brain.getDRecorder().record(fastestETA + ": Longest Road");
}
} else if (!haveLA && !needLA && (fastestETA == tempLargestArmyETA)) {
needLA = true;
if (brain.getDRecorder().isOn()) {
brain.getDRecorder().record(fastestETA + ": Largest Army");
}
} else if ((cityPiecesLeft > 0) && (citySpotsLeft > 0) && (cityETA == fastestETA)) {
if (brain.getDRecorder().isOn()) {
brain.getDRecorder().record(fastestETA + ": City");
}
} else if (chosenSet != null) {
if (brain.getDRecorder().isOn()) {
brain.getDRecorder().record(fastestETA + ": Stlmt at " + board.nodeCoordToString(chosenSet.getCoordinates()));
}
}
D.ebugPrintln("WWW Adding " + fastestETA + " to win eta");
winGameETA += fastestETA;
points += 2;
} else {
//
// This is for < 9 vp (not about to win with VP_WINNER points)
//
// System.out.println("Old Player Numbers = "+tempPlayerNumbers);
// System.out.print("Old Ports = ");
// for (int i = 0; i <= SOCBoard.WOOD_PORT; i++) {
// System.out.print(tempPortFlags[i]+",");
// }
// System.out.println();
fastestETA = 500;
SOCPossibleSettlement[] chosenSet = new SOCPossibleSettlement[2];
boolean[][] tempPortFlagsSet = new boolean[2][SOCBoard.WOOD_PORT + 1];
SOCPossibleCity[] chosenCity = new SOCPossibleCity[2];
chosenSet[0] = null;
chosenSet[1] = null;
chosenCity[0] = null;
chosenCity[1] = null;
int twoSettlements = 0;
int twoCities = 500;
int oneOfEach = 0;
int cityBeforeSettlement = 500;
int settlementBeforeCity = 500;
// /
if ((cityPiecesLeft > 1) && (citySpotsLeft > 1)) {
//
// get a more accurate estimate by taking the
// effect on building speed into account
//
twoCities = 500;
Iterator<SOCPossibleCity> posCities0Iter = posCitiesCopy.values().iterator();
while (posCities0Iter.hasNext()) {
SOCPossibleCity posCity0 = posCities0Iter.next();
//
// update our building speed estimate
//
tempPlayerNumbers.updateNumbers(posCity0.getCoordinates(), board);
tempCityBSE[0].recalculateEstimates(tempPlayerNumbers);
chosenCityBuildingSpeed[0] = tempCityBSE[0].getEstimatesFromNothingFast(tempPortFlags);
int tempCityETA = chosenCityBuildingSpeed[0][SOCBuildingSpeedEstimate.CITY];
//
if ((cityETA + tempCityETA) < twoCities) {
chosenCity[0] = posCity0;
twoCities = (cityETA + tempCityETA);
}
tempPlayerNumbers.undoUpdateNumbers(posCity0.getCoordinates(), board);
}
if (twoCities <= fastestETA) {
D.ebugPrintln("WWW twoCities = " + twoCities);
fastestETA = twoCities;
}
}
// /
// / two settlements
// /
boolean canBuild2Settlements = false;
if ((settlementPiecesLeft > 1) && (posSetsCopy.size() > 1)) {
canBuild2Settlements = true;
ArrayList<SOCPossibleSettlement> posSetsToPutBack = new ArrayList<SOCPossibleSettlement>();
for (int i = 0; i < 2; i++) {
int fastestSetETA = 500;
int bestSpeedupTotal = 0;
if (posSetsCopy.isEmpty()) {
canBuild2Settlements = false;
} else {
Iterator<SOCPossibleSettlement> posSetsIter = posSetsCopy.values().iterator();
while (posSetsIter.hasNext()) {
SOCPossibleSettlement posSet = posSetsIter.next();
int posSetETA = settlementETA + (posSet.getNumberOfNecessaryRoads() * roadETA);
final int posSetCoord = posSet.getCoordinates();
if (posSetETA < fastestSetETA) {
fastestSetETA = posSetETA;
tempPlayerNumbers.updateNumbers(posSetCoord, board);
for (int portType = SOCBoard.MISC_PORT; portType <= SOCBoard.WOOD_PORT; portType++) {
tempPortFlagsSet[i][portType] = tempPortFlags[portType];
}
int portType = board.getPortTypeFromNodeCoord(posSetCoord);
if (portType != -1)
tempPortFlagsSet[i][portType] = true;
tempSetBSE[i].recalculateEstimates(tempPlayerNumbers);
chosenSetBuildingSpeed[i] = tempSetBSE[i].getEstimatesFromNothingFast(tempPortFlagsSet[i]);
for (int buildingType = SOCBuildingSpeedEstimate.MIN; buildingType < SOCBuildingSpeedEstimate.MAXPLUSONE; buildingType++) {
if ((ourBuildingSpeed[buildingType] - chosenSetBuildingSpeed[i][buildingType]) > 0) {
bestSpeedupTotal += (ourBuildingSpeed[buildingType] - chosenSetBuildingSpeed[i][buildingType]);
}
}
tempPlayerNumbers.undoUpdateNumbers(posSetCoord, board);
chosenSet[i] = posSet;
} else if (posSetETA == fastestSetETA) {
boolean[] veryTempPortFlags = new boolean[SOCBoard.WOOD_PORT + 1];
tempPlayerNumbers.updateNumbers(posSetCoord, board);
for (int portType = SOCBoard.MISC_PORT; portType <= SOCBoard.WOOD_PORT; portType++) {
veryTempPortFlags[portType] = tempPortFlags[portType];
}
int portType = board.getPortTypeFromNodeCoord(posSetCoord);
if (portType != -1)
veryTempPortFlags[portType] = true;
tempBSE.recalculateEstimates(tempPlayerNumbers);
int[] tempBuildingSpeed = tempBSE.getEstimatesFromNothingFast(veryTempPortFlags);
int tempSpeedupTotal = 0;
// boolean ok = true;
for (int buildingType = SOCBuildingSpeedEstimate.MIN; buildingType < SOCBuildingSpeedEstimate.MAXPLUSONE; buildingType++) {
if ((ourBuildingSpeed[buildingType] - tempBuildingSpeed[buildingType]) >= 0) {
tempSpeedupTotal += (ourBuildingSpeed[buildingType] - tempBuildingSpeed[buildingType]);
} else {
// ok = false;
}
}
// if (ok) {
// good++;
// } else {
// bad++;
// //
// // output the player number data
// //
// System.out.println("New Player Numbers = "+tempPlayerNumbers);
// System.out.print("New Ports = ");
// for (int k = 0; k <= SOCBoard.WOOD_PORT; k++) {
// System.out.print(veryTempPortFlags[k]+",");
// }
// System.out.println();
// }
tempPlayerNumbers.undoUpdateNumbers(posSetCoord, board);
if (tempSpeedupTotal > bestSpeedupTotal) {
fastestSetETA = posSetETA;
bestSpeedupTotal = tempSpeedupTotal;
for (int buildingType = SOCBuildingSpeedEstimate.MIN; buildingType < SOCBuildingSpeedEstimate.MAXPLUSONE; buildingType++) {
chosenSetBuildingSpeed[i][buildingType] = tempBuildingSpeed[buildingType];
}
for (portType = SOCBoard.MISC_PORT; portType <= SOCBoard.WOOD_PORT; portType++) {
tempPortFlagsSet[i][portType] = veryTempPortFlags[portType];
}
chosenSet[i] = posSet;
}
}
}
// /
// / estimate setETA using building speed
// / for settlements and roads from nothing
// /
// / as long as this settlement needs roads
// / add a roadETA to the ETA for this settlement
// /
int totalNecRoads = calcTotalNecessaryRoads(chosenSet[i]);
D.ebugPrintln("WWW # necesesary roads = " + totalNecRoads);
D.ebugPrintln("WWW this settlement eta = " + (settlementETA + (totalNecRoads * roadETA)));
if ((i == 0) && (chosenSet[0] != null)) {
posSetsCopy.remove(Integer.valueOf(chosenSet[0].getCoordinates()));
for (SOCPossibleSettlement conflict : chosenSet[0].getConflicts()) {
Integer conflictInt = Integer.valueOf(conflict.getCoordinates());
SOCPossibleSettlement possibleConflict = posSetsCopy.get(conflictInt);
if (possibleConflict != null) {
posSetsToPutBack.add(possibleConflict);
posSetsCopy.remove(conflictInt);
}
}
twoSettlements += (settlementETA + (totalNecRoads * roadETA));
}
if ((i == 1) && (chosenSet[1] != null)) {
//
// get a more accurate estimate by taking the
// effect on building speed into account
//
int tempSettlementETA = chosenSetBuildingSpeed[0][SOCBuildingSpeedEstimate.SETTLEMENT];
int tempRoadETA = chosenSetBuildingSpeed[0][SOCBuildingSpeedEstimate.ROAD];
twoSettlements += (tempSettlementETA + (totalNecRoads * tempRoadETA));
}
}
}
posSetsCopy.put(Integer.valueOf(chosenSet[0].getCoordinates()), chosenSet[0]);
for (SOCPossibleSettlement tmpPosSet : posSetsToPutBack) {
posSetsCopy.put(Integer.valueOf(tmpPosSet.getCoordinates()), tmpPosSet);
}
if (canBuild2Settlements && (twoSettlements <= fastestETA)) {
D.ebugPrintln("WWW 2 * settlement = " + twoSettlements);
fastestETA = twoSettlements;
}
}
// /
if ((cityPiecesLeft > 0) && (((settlementPiecesLeft > 0) && (citySpotsLeft >= 0)) || ((settlementPiecesLeft >= 0) && (citySpotsLeft > 0))) && !posSetsCopy.isEmpty()) {
//
if ((chosenCity[0] == null) && (citySpotsLeft > 0)) {
int bestCitySpeedupTotal = 0;
Iterator<SOCPossibleCity> posCities0Iter = posCitiesCopy.values().iterator();
while (posCities0Iter.hasNext()) {
SOCPossibleCity posCity0 = posCities0Iter.next();
tempPlayerNumbers.updateNumbers(posCity0.getCoordinates(), board);
tempBSE.recalculateEstimates(tempPlayerNumbers);
int[] tempBuildingSpeed = tempBSE.getEstimatesFromNothingFast(tempPortFlags);
int tempSpeedupTotal = 0;
// boolean ok = true;
for (int buildingType = SOCBuildingSpeedEstimate.MIN; buildingType < SOCBuildingSpeedEstimate.MAXPLUSONE; buildingType++) {
if ((ourBuildingSpeed[buildingType] - tempBuildingSpeed[buildingType]) >= 0) {
tempSpeedupTotal += (ourBuildingSpeed[buildingType] - tempBuildingSpeed[buildingType]);
} else {
// ok = false;
}
}
// if (ok) {
// good++;
// } else {
// bad++;
// //
// // output the player number data
// //
// System.out.println("New Player Numbers = "+tempPlayerNumbers);
// System.out.print("New Ports = ");
// for (int i = 0; i <= SOCBoard.WOOD_PORT; i++) {
// System.out.print(tempPortFlags[i]+",");
// }
// System.out.println();
// }
tempPlayerNumbers.undoUpdateNumbers(posCity0.getCoordinates(), board);
if (tempSpeedupTotal >= bestCitySpeedupTotal) {
bestCitySpeedupTotal = tempSpeedupTotal;
for (int buildingType = SOCBuildingSpeedEstimate.MIN; buildingType < SOCBuildingSpeedEstimate.MAXPLUSONE; buildingType++) {
chosenCityBuildingSpeed[0][buildingType] = tempBuildingSpeed[buildingType];
}
chosenCity[0] = posCity0;
}
}
}
//
if (chosenSet[0] == null) {
int fastestSetETA = 500;
int bestSpeedupTotal = 0;
Iterator<SOCPossibleSettlement> posSetsIter = posSetsCopy.values().iterator();
while (posSetsIter.hasNext()) {
SOCPossibleSettlement posSet = posSetsIter.next();
int posSetETA = settlementETA + (posSet.getNumberOfNecessaryRoads() * roadETA);
if (posSetETA < fastestSetETA) {
fastestSetETA = posSetETA;
tempPlayerNumbers.updateNumbers(posSet.getCoordinates(), board);
for (int portType = SOCBoard.MISC_PORT; portType <= SOCBoard.WOOD_PORT; portType++) {
tempPortFlagsSet[0][portType] = tempPortFlags[portType];
}
int portType = board.getPortTypeFromNodeCoord(posSet.getCoordinates());
if (portType != -1)
tempPortFlagsSet[0][portType] = true;
tempSetBSE[0].recalculateEstimates(tempPlayerNumbers);
chosenSetBuildingSpeed[0] = tempSetBSE[0].getEstimatesFromNothingFast(tempPortFlagsSet[0]);
for (int buildingType = SOCBuildingSpeedEstimate.MIN; buildingType < SOCBuildingSpeedEstimate.MAXPLUSONE; buildingType++) {
if ((ourBuildingSpeed[buildingType] - chosenSetBuildingSpeed[0][buildingType]) > 0) {
bestSpeedupTotal += (ourBuildingSpeed[buildingType] - chosenSetBuildingSpeed[0][buildingType]);
}
}
tempPlayerNumbers.undoUpdateNumbers(posSet.getCoordinates(), board);
chosenSet[0] = posSet;
} else if (posSetETA == fastestSetETA) {
boolean[] veryTempPortFlags = new boolean[SOCBoard.WOOD_PORT + 1];
tempPlayerNumbers.updateNumbers(posSet.getCoordinates(), board);
for (int portType = SOCBoard.MISC_PORT; portType <= SOCBoard.WOOD_PORT; portType++) {
veryTempPortFlags[portType] = tempPortFlags[portType];
}
int portType = board.getPortTypeFromNodeCoord(posSet.getCoordinates());
if (portType != -1)
veryTempPortFlags[portType] = true;
tempBSE.recalculateEstimates(tempPlayerNumbers);
int[] tempBuildingSpeed = tempBSE.getEstimatesFromNothingFast(veryTempPortFlags);
int tempSpeedupTotal = 0;
// boolean ok = true;
for (int buildingType = SOCBuildingSpeedEstimate.MIN; buildingType < SOCBuildingSpeedEstimate.MAXPLUSONE; buildingType++) {
if ((ourBuildingSpeed[buildingType] - tempBuildingSpeed[buildingType]) >= 0) {
tempSpeedupTotal += (ourBuildingSpeed[buildingType] - tempBuildingSpeed[buildingType]);
} else {
// ok = false;
}
}
// if (ok) {
// good++;
// } else {
// bad++;
// //
// // output the player number data
// //
// System.out.println("New Player Numbers = "+tempPlayerNumbers);
// System.out.print("New Ports = ");
// for (int i = 0; i <= SOCBoard.WOOD_PORT; i++) {
// System.out.print(tempPortFlags[i]+",");
// }
// System.out.println();
// }
tempPlayerNumbers.undoUpdateNumbers(posSet.getCoordinates(), board);
if (tempSpeedupTotal > bestSpeedupTotal) {
fastestSetETA = posSetETA;
bestSpeedupTotal = tempSpeedupTotal;
for (int buildingType = SOCBuildingSpeedEstimate.MIN; buildingType < SOCBuildingSpeedEstimate.MAXPLUSONE; buildingType++) {
chosenSetBuildingSpeed[0][buildingType] = tempBuildingSpeed[buildingType];
}
for (portType = SOCBoard.MISC_PORT; portType <= SOCBoard.WOOD_PORT; portType++) {
tempPortFlagsSet[0][portType] = veryTempPortFlags[portType];
}
chosenSet[0] = posSet;
}
}
}
}
if (citySpotsLeft == 0) {
chosenCity[0] = new SOCPossibleCity(player, chosenSet[0].getCoordinates());
}
// /
// / estimate setETA using building speed
// / for settlements and roads from nothing
// /
// / as long as this settlement needs roads
// / add a roadETA to the ETA for this settlement
// /
int totalNecRoads = calcTotalNecessaryRoads(chosenSet[0]);
D.ebugPrintln("WWW # necesesary roads = " + totalNecRoads);
D.ebugPrintln("WWW this settlement eta = " + (settlementETA + (totalNecRoads * roadETA)));
//
if ((settlementPiecesLeft > 0) && (citySpotsLeft >= 0)) {
int tempCityETA = chosenSetBuildingSpeed[0][SOCBuildingSpeedEstimate.CITY];
settlementBeforeCity = tempCityETA + (settlementETA + (totalNecRoads * roadETA));
}
if ((settlementPiecesLeft >= 0) && (citySpotsLeft > 0)) {
int tempSettlementETA = chosenCityBuildingSpeed[0][SOCBuildingSpeedEstimate.SETTLEMENT];
int tempRoadETA = chosenCityBuildingSpeed[0][SOCBuildingSpeedEstimate.ROAD];
cityBeforeSettlement = cityETA + (tempSettlementETA + (totalNecRoads * tempRoadETA));
}
if (settlementBeforeCity < cityBeforeSettlement) {
oneOfEach = settlementBeforeCity;
} else {
oneOfEach = cityBeforeSettlement;
}
if (oneOfEach <= fastestETA) {
D.ebugPrintln("WWW one of each = " + oneOfEach);
fastestETA = oneOfEach;
}
}
// /
if (!haveLA && !needLA && (points > 5)) {
//
// recalc LA eta given our new building speed
//
int laSize = 0;
if (laPlayer == null) {
// /
// / no one has largest army
// /
laSize = 3;
} else if (laPlayer.getPlayerNumber() == playerNumber) {
// /
// / we have largest army
// /
D.ebugPrintln("WWW ERROR CALCULATING LA ETA");
} else {
laSize = laPlayer.getNumKnights() + 1;
}
// /
// / figure out how many knights we need to buy
// /
knightsToBuy = 0;
if ((player.getNumKnights() + player.getInventory().getAmount(SOCDevCardConstants.KNIGHT)) < // OLD + NEW knights
laSize) {
knightsToBuy = laSize - (player.getNumKnights() + player.getInventory().getAmount(SOCInventory.OLD, SOCDevCardConstants.KNIGHT));
}
// /
if (game.getNumDevCards() >= knightsToBuy) {
tempLargestArmyETA = (cardETA + 1) * knightsToBuy;
} else {
tempLargestArmyETA = 500;
}
D.ebugPrintln("WWW LA eta = " + tempLargestArmyETA);
if (tempLargestArmyETA < fastestETA) {
fastestETA = tempLargestArmyETA;
}
}
//
if (!haveLR && !needLR && (points > 5)) {
tempLongestRoadETA = roadETA * roadsToGo;
D.ebugPrintln("WWW LR eta = " + tempLongestRoadETA);
if (tempLongestRoadETA < fastestETA) {
fastestETA = tempLongestRoadETA;
}
}
// /
// / implement the fastest scenario
// /
D.ebugPrintln("WWW Adding " + fastestETA + " to win eta");
points += 2;
winGameETA += fastestETA;
D.ebugPrintln("WWW WGETA SO FAR FOR PLAYER " + playerNumber + " = " + winGameETA);
if ((settlementPiecesLeft > 1) && (posSetsCopy.size() > 1) && canBuild2Settlements && (fastestETA == twoSettlements)) {
Integer chosenSet0Int = Integer.valueOf(chosenSet[0].getCoordinates());
Integer chosenSet1Int = Integer.valueOf(chosenSet[1].getCoordinates());
posSetsCopy.remove(chosenSet0Int);
posSetsCopy.remove(chosenSet1Int);
posCitiesCopy.put(chosenSet0Int, new SOCPossibleCity(player, chosenSet[0].getCoordinates()));
posCitiesCopy.put(chosenSet1Int, new SOCPossibleCity(player, chosenSet[1].getCoordinates()));
//
for (SOCPossibleSettlement conflict : chosenSet[0].getConflicts()) {
Integer conflictInt = Integer.valueOf(conflict.getCoordinates());
posSetsCopy.remove(conflictInt);
}
for (SOCPossibleSettlement conflict : chosenSet[1].getConflicts()) {
Integer conflictInt = Integer.valueOf(conflict.getCoordinates());
posSetsCopy.remove(conflictInt);
}
settlementPiecesLeft -= 2;
citySpotsLeft += 2;
//
// update our building speed estimate
//
tempPlayerNumbers.updateNumbers(chosenSet[0].getCoordinates(), board);
tempPlayerNumbers.updateNumbers(chosenSet[1].getCoordinates(), board);
int portType = board.getPortTypeFromNodeCoord(chosenSet[0].getCoordinates());
if (portType != -1)
tempPortFlags[portType] = true;
portType = board.getPortTypeFromNodeCoord(chosenSet[1].getCoordinates());
if (portType != -1)
tempPortFlags[portType] = true;
ourBSE.recalculateEstimates(tempPlayerNumbers);
ourBuildingSpeed = ourBSE.getEstimatesFromNothingFast(tempPortFlags);
settlementETA = ourBuildingSpeed[SOCBuildingSpeedEstimate.SETTLEMENT];
roadETA = ourBuildingSpeed[SOCBuildingSpeedEstimate.ROAD];
cityETA = ourBuildingSpeed[SOCBuildingSpeedEstimate.CITY];
cardETA = ourBuildingSpeed[SOCBuildingSpeedEstimate.CARD];
D.ebugPrintln("WWW * build two settlements");
D.ebugPrintln("WWW settlement 1: " + board.nodeCoordToString(chosenSet[0].getCoordinates()));
D.ebugPrintln("WWW settlement 2: " + board.nodeCoordToString(chosenSet[1].getCoordinates()));
if (brain.getDRecorder().isOn()) {
brain.getDRecorder().record(fastestETA + ": Stlmt at " + board.nodeCoordToString(chosenSet[0].getCoordinates()) + "; Stlmt at " + board.nodeCoordToString(chosenSet[1].getCoordinates()));
}
} else if (((cityPiecesLeft > 0) && (((settlementPiecesLeft > 0) && (citySpotsLeft >= 0)) || ((settlementPiecesLeft >= 0) && (citySpotsLeft > 0))) && !posSetsCopy.isEmpty()) && (fastestETA == oneOfEach)) {
Integer chosenSet0Int = Integer.valueOf(chosenSet[0].getCoordinates());
posSetsCopy.remove(chosenSet0Int);
if (chosenSet[0].getCoordinates() != chosenCity[0].getCoordinates()) {
posCitiesCopy.put(chosenSet0Int, new SOCPossibleCity(player, chosenSet[0].getCoordinates()));
}
posCitiesCopy.remove(Integer.valueOf(chosenCity[0].getCoordinates()));
cityPiecesLeft -= 1;
//
for (SOCPossibleSettlement conflict : chosenSet[0].getConflicts()) {
Integer conflictInt = Integer.valueOf(conflict.getCoordinates());
posSetsCopy.remove(conflictInt);
}
//
// update our building speed estimate
//
tempPlayerNumbers.updateNumbers(chosenSet[0].getCoordinates(), board);
int portType = board.getPortTypeFromNodeCoord(chosenSet[0].getCoordinates());
if (portType != -1)
tempPortFlags[portType] = true;
tempPlayerNumbers.updateNumbers(chosenCity[0].getCoordinates(), board);
ourBSE.recalculateEstimates(tempPlayerNumbers);
ourBuildingSpeed = ourBSE.getEstimatesFromNothingFast(tempPortFlags);
settlementETA = ourBuildingSpeed[SOCBuildingSpeedEstimate.SETTLEMENT];
roadETA = ourBuildingSpeed[SOCBuildingSpeedEstimate.ROAD];
cityETA = ourBuildingSpeed[SOCBuildingSpeedEstimate.CITY];
cardETA = ourBuildingSpeed[SOCBuildingSpeedEstimate.CARD];
D.ebugPrintln("WWW * build a settlement and a city");
D.ebugPrintln("WWW settlement at " + board.nodeCoordToString(chosenSet[0].getCoordinates()));
D.ebugPrintln("WWW city at " + board.nodeCoordToString(chosenCity[0].getCoordinates()));
if (brain.getDRecorder().isOn()) {
if (fastestETA == settlementBeforeCity) {
brain.getDRecorder().record(fastestETA + ": Stlmt at " + board.nodeCoordToString(chosenSet[0].getCoordinates()) + "; City at " + board.nodeCoordToString(chosenCity[0].getCoordinates()));
} else {
brain.getDRecorder().record(fastestETA + ": City at " + board.nodeCoordToString(chosenCity[0].getCoordinates()) + "; Stlmt at " + board.nodeCoordToString(chosenSet[0].getCoordinates()));
}
}
} else if ((cityPiecesLeft > 1) && (citySpotsLeft > 1) && (fastestETA == twoCities)) {
posCitiesCopy.remove(Integer.valueOf(chosenCity[0].getCoordinates()));
//
// update our building speed estimate
//
tempPlayerNumbers.updateNumbers(chosenCity[0].getCoordinates(), board);
//
// pick the second city to build
//
int bestCitySpeedupTotal = 0;
Iterator<SOCPossibleCity> posCities1Iter = posCitiesCopy.values().iterator();
while (posCities1Iter.hasNext()) {
SOCPossibleCity posCity1 = posCities1Iter.next();
tempPlayerNumbers.updateNumbers(posCity1.getCoordinates(), board);
D.ebugPrintln("tempPlayerNumbers = " + tempPlayerNumbers);
tempBSE.recalculateEstimates(tempPlayerNumbers);
int[] tempBuildingSpeed = tempBSE.getEstimatesFromNothingFast(tempPortFlags);
int tempSpeedupTotal = 0;
// boolean ok = true;
for (int buildingType = SOCBuildingSpeedEstimate.MIN; buildingType < SOCBuildingSpeedEstimate.MAXPLUSONE; buildingType++) {
D.ebugPrintln("ourBuildingSpeed[" + buildingType + "] = " + ourBuildingSpeed[buildingType]);
D.ebugPrintln("tempBuildingSpeed[" + buildingType + "] = " + tempBuildingSpeed[buildingType]);
if ((ourBuildingSpeed[buildingType] - tempBuildingSpeed[buildingType]) >= 0) {
tempSpeedupTotal += (ourBuildingSpeed[buildingType] - tempBuildingSpeed[buildingType]);
} else {
// ok = false;
}
}
// if (ok) {
// good++;
// } else {
// bad++;
// //
// // output the player number data
// //
// System.out.println("New Player Numbers = "+tempPlayerNumbers);
// System.out.print("New Ports = ");
// for (int i = 0; i <= SOCBoard.WOOD_PORT; i++) {
// System.out.print(tempPortFlags[i]+",");
// }
// System.out.println();
// }
tempPlayerNumbers.undoUpdateNumbers(posCity1.getCoordinates(), board);
D.ebugPrintln("tempPlayerNumbers = " + tempPlayerNumbers);
D.ebugPrintln("WWW City at " + board.nodeCoordToString(posCity1.getCoordinates()) + " has tempSpeedupTotal = " + tempSpeedupTotal);
if (tempSpeedupTotal >= bestCitySpeedupTotal) {
bestCitySpeedupTotal = tempSpeedupTotal;
chosenCity[1] = posCity1;
}
}
if (chosenCity[1] == null) {
System.out.println("OOPS!!!");
} else {
posCitiesCopy.remove(Integer.valueOf(chosenCity[1].getCoordinates()));
}
settlementPiecesLeft += 2;
cityPiecesLeft -= 2;
citySpotsLeft -= 2;
tempPlayerNumbers.updateNumbers(chosenCity[1].getCoordinates(), board);
ourBSE.recalculateEstimates(tempPlayerNumbers);
ourBuildingSpeed = ourBSE.getEstimatesFromNothingFast(tempPortFlags);
settlementETA = ourBuildingSpeed[SOCBuildingSpeedEstimate.SETTLEMENT];
roadETA = ourBuildingSpeed[SOCBuildingSpeedEstimate.ROAD];
cityETA = ourBuildingSpeed[SOCBuildingSpeedEstimate.CITY];
cardETA = ourBuildingSpeed[SOCBuildingSpeedEstimate.CARD];
D.ebugPrintln("WWW * build 2 cities");
D.ebugPrintln("WWW city 1: " + board.nodeCoordToString(chosenCity[0].getCoordinates()));
D.ebugPrintln("WWW city 2: " + board.nodeCoordToString(chosenCity[1].getCoordinates()));
if (brain.getDRecorder().isOn()) {
brain.getDRecorder().record(fastestETA + ": City at " + board.nodeCoordToString(chosenCity[0].getCoordinates()) + "; City at " + board.nodeCoordToString(chosenCity[1].getCoordinates()));
}
} else if (!haveLR && !needLR && (points > 5) && (fastestETA == tempLongestRoadETA)) {
needLR = true;
D.ebugPrintln("WWW * take longest road");
if (brain.getDRecorder().isOn()) {
brain.getDRecorder().record(fastestETA + ": Longest Road");
}
} else if (!haveLA && !needLA && (points > 5) && (fastestETA == tempLargestArmyETA)) {
needLA = true;
D.ebugPrintln("WWW * take largest army");
if (brain.getDRecorder().isOn()) {
brain.getDRecorder().record(fastestETA + ": Largest Army");
}
}
}
}
D.ebugPrintln("WWW TOTAL WGETA FOR PLAYER " + playerNumber + " = " + winGameETA);
if (brain.getDRecorder().isOn()) {
brain.getDRecorder().record("Total WGETA for " + player.getName() + " = " + winGameETA);
brain.getDRecorder().record("--------------------");
}
} catch (Exception e) {
winGameETA = oldWGETA;
System.out.println("Exception in recalcWinGameETA - " + e);
e.printStackTrace();
}
// System.out.println("good = "+good+" bad = "+bad);
// System.out.println();
}
use of soc.game.SOCBoard 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();
}
}
}
Aggregations