use of soc.game.SOCPlayerNumbers 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.SOCPlayerNumbers in project JSettlers2 by jdmonin.
the class SOCPossibleCity method updateSpeedup.
/**
* calculate the speedup that this city gives.
* Call when any player's new city or settlement is added to the board.
* @see #getSpeedup()
*/
public void updateSpeedup() {
// D.ebugPrintln("****************************** (CITY) updateSpeedup at "+Integer.toHexString(coord));
SOCBuildingSpeedEstimate bse1 = new SOCBuildingSpeedEstimate(player.getNumbers());
int[] ourBuildingSpeed = bse1.getEstimatesFromNothingFast(player.getPortFlags());
SOCPlayerNumbers newNumbers = new SOCPlayerNumbers(player.getNumbers());
newNumbers.updateNumbers(new SOCCity(player, coord, null), player.getGame().getBoard());
SOCBuildingSpeedEstimate bse2 = new SOCBuildingSpeedEstimate(newNumbers);
int[] speed = bse2.getEstimatesFromNothingFast(player.getPortFlags());
for (int buildingType = SOCBuildingSpeedEstimate.MIN; buildingType < SOCBuildingSpeedEstimate.MAXPLUSONE; buildingType++) {
// D.ebugPrintln("!@#$% ourBuildingSpeed[buildingType]="+ourBuildingSpeed[buildingType]+" speed[buildingType]="+speed[buildingType]);
speedup[buildingType] = ourBuildingSpeed[buildingType] - speed[buildingType];
}
}