use of soc.game.SOCPlayer in project JSettlers2 by jdmonin.
the class SOCRobotBrain method handlePUTPIECE_updateTrackers.
/**
* Handle a PUTPIECE for this game, by updating {@link SOCPlayerTracker}s.
* Also handles the "move piece to here" part of MOVEPIECE.
*<P>
* For initial placement of our own pieces, this method also checks
* and clears expectPUTPIECE_FROM_START1A, and sets expectSTART1B, etc.
* The final initial putpiece clears expectPUTPIECE_FROM_START2B and sets expectROLL_OR_CARD.
* As part of the PUTPIECE request, brain set those expectPUTPIECE flags in {@link #placeIfExpectPlacing()}.
*<P>
* For initial settlements, won't track here:
* Delay tracking until the corresponding road is placed,
* in {@link #handlePUTPIECE_updateGameData(SOCPutPiece)}.
* This prevents the need for tracker "undo" work if a human
* player changes their mind on where to place the settlement.
*
* @param pn Piece's player number
* @param coord Piece coordinate
* @param pieceType Piece type, as in {@link SOCPlayingPiece#SETTLEMENT}
* @since 1.1.08
*/
private void handlePUTPIECE_updateTrackers(final int pn, final int coord, final int pieceType) {
switch(pieceType) {
case SOCPlayingPiece.ROAD:
SOCRoad newRoad = new SOCRoad(game.getPlayer(pn), coord, null);
trackNewRoadOrShip(newRoad, false);
break;
case SOCPlayingPiece.SETTLEMENT:
SOCPlayer newSettlementPl = game.getPlayer(pn);
SOCSettlement newSettlement = new SOCSettlement(newSettlementPl, coord, null);
if ((game.getGameState() == SOCGame.START1B) || (game.getGameState() == SOCGame.START2B) || (game.getGameState() == SOCGame.START3B)) {
// Track it soon, after the road is placed
// (in handlePUTPIECE_updateGameData)
// but not yet, in case player cancels placement.
SOCPlayerTracker tr = playerTrackers.get(Integer.valueOf(newSettlementPl.getPlayerNumber()));
tr.setPendingInitSettlement(newSettlement);
} else {
// Track it now
trackNewSettlement(newSettlement, false);
}
break;
case SOCPlayingPiece.CITY:
SOCCity newCity = new SOCCity(game.getPlayer(pn), coord, null);
trackNewCity(newCity, false);
break;
case SOCPlayingPiece.SHIP:
SOCShip newShip = new SOCShip(game.getPlayer(pn), coord, null);
trackNewRoadOrShip(newShip, false);
break;
case SOCPlayingPiece.VILLAGE:
// <--- Early return: Piece is part of board initial layout, not tracked player info ---
return;
}
if (D.ebugOn) {
SOCPlayerTracker.playerTrackersDebug(playerTrackers);
}
if (pn != ourPlayerNumber) {
// <---- Not our piece ----
return;
}
if (expectPUTPIECE_FROM_START1A && (pieceType == SOCPlayingPiece.SETTLEMENT) && (coord == ourPlayerData.getLastSettlementCoord())) {
expectPUTPIECE_FROM_START1A = false;
expectSTART1B = true;
}
if (expectPUTPIECE_FROM_START1B && ((pieceType == SOCPlayingPiece.ROAD) || (pieceType == SOCPlayingPiece.SHIP)) && (coord == ourPlayerData.getLastRoadCoord())) {
expectPUTPIECE_FROM_START1B = false;
expectSTART2A = true;
}
if (expectPUTPIECE_FROM_START2A && (pieceType == SOCPlayingPiece.SETTLEMENT) && (coord == ourPlayerData.getLastSettlementCoord())) {
expectPUTPIECE_FROM_START2A = false;
expectSTART2B = true;
}
if (expectPUTPIECE_FROM_START2B && ((pieceType == SOCPlayingPiece.ROAD) || (pieceType == SOCPlayingPiece.SHIP)) && (coord == ourPlayerData.getLastRoadCoord())) {
expectPUTPIECE_FROM_START2B = false;
if (!game.isGameOptionSet(SOCGameOption.K_SC_3IP))
// wait for regular game play to start; other players might still place first
expectROLL_OR_CARD = true;
else
expectSTART3A = true;
}
if (expectPUTPIECE_FROM_START3A && (pieceType == SOCPlayingPiece.SETTLEMENT) && (coord == ourPlayerData.getLastSettlementCoord())) {
expectPUTPIECE_FROM_START3A = false;
expectSTART3B = true;
}
if (expectPUTPIECE_FROM_START3B && ((pieceType == SOCPlayingPiece.ROAD) || (pieceType == SOCPlayingPiece.SHIP)) && (coord == ourPlayerData.getLastRoadCoord())) {
expectPUTPIECE_FROM_START3B = false;
expectROLL_OR_CARD = true;
}
}
use of soc.game.SOCPlayer in project JSettlers2 by jdmonin.
the class SOCRobotBrain method handleCANCELBUILDREQUEST.
/**
* Handle a CANCELBUILDREQUEST for this game.
*<P>
*<b> During game startup</b> (START1B, START2B, or START3B): <BR>
* When sent from server to client, CANCELBUILDREQUEST means the current
* player wants to undo the placement of their initial settlement.
* This handler method calls {@link SOCGame#undoPutInitSettlement(SOCPlayingPiece)}
* and {@link SOCPlayerTracker#setPendingInitSettlement(SOCSettlement) tracker.setPendingInitSettlement(null)}.
*<P>
*<b> During piece placement</b> (PLACING_ROAD, PLACING_CITY, PLACING_SETTLEMENT,
* PLACING_FREE_ROAD1, or PLACING_FREE_ROAD2): <BR>
* When sent from server to client, CANCELBUILDREQUEST means the player
* has sent an illegal PUTPIECE (bad building location).
* Humans can probably decide a better place to put their road,
* but robots must cancel the build request and decide on a new plan.
*
* @since 1.1.08
*/
private void handleCANCELBUILDREQUEST(SOCCancelBuildRequest mes) {
final int gstate = game.getGameState();
switch(gstate) {
case SOCGame.START1A:
case SOCGame.START2A:
case SOCGame.START3A:
if (ourTurn) {
cancelWrongPiecePlacement(mes);
}
break;
case SOCGame.START1B:
case SOCGame.START2B:
case SOCGame.START3B:
if (ourTurn) {
cancelWrongPiecePlacement(mes);
} else {
//
// Human player placed, then cancelled placement
// (assume mes.getPieceType() == SOCPlayingPiece.SETTLEMENT).
// Our robot wouldn't do that, and if it's ourTurn,
// the cancel happens only if we try an illegal placement.
//
final int pnum = game.getCurrentPlayerNumber();
SOCPlayer pl = game.getPlayer(pnum);
SOCSettlement pp = new SOCSettlement(pl, pl.getLastSettlementCoord(), null);
game.undoPutInitSettlement(pp);
//
// "forget" to track this cancelled initial settlement.
// Wait for human player to place a new one.
//
SOCPlayerTracker tr = playerTrackers.get(Integer.valueOf(pnum));
tr.setPendingInitSettlement(null);
}
break;
// asked to build, hasn't given location yet -> resources
case SOCGame.PLAY1:
// has given location -> is bad location
case SOCGame.PLACING_ROAD:
case SOCGame.PLACING_SETTLEMENT:
case SOCGame.PLACING_CITY:
case SOCGame.PLACING_SHIP:
// JM TODO how to break out?
case SOCGame.PLACING_FREE_ROAD1:
// JM TODO how to break out?
case SOCGame.PLACING_FREE_ROAD2:
case SOCGame.SPECIAL_BUILDING:
//
// We've asked for an illegal piece placement.
// (Must be a bug.) Cancel and invalidate this
// planned piece, make a new plan.
//
// Can also happen in special building, if another
// player has placed since we requested special building.
// If our PUTPIECE request is denied, server sends us
// CANCELBUILDREQUEST. We need to ask to cancel the
// placement, and also set variables to end our SBP turn.
//
cancelWrongPiecePlacement(mes);
break;
default:
if (game.isSpecialBuilding()) {
cancelWrongPiecePlacement(mes);
} else {
// Should not occur
System.err.println("L2521 SOCRobotBrain: " + client.getNickname() + ": Unhandled CANCELBUILDREQUEST at state " + gstate);
}
}
// switch (gameState)
}
use of soc.game.SOCPlayer in project JSettlers2 by jdmonin.
the class SOCRobotClient method treat.
/**
* Treat the incoming messages.
* Messages of unknown type are ignored. All {@link SOCGameServerText} are ignored.
* ({@code mes} will be null from {@link SOCMessage#toMsg(String)}).
*<P>
*<B>Note:</B> Currently, does not call {@link SOCDisplaylessPlayerClient#treat(SOCMessage)}.
* New message types should be added to both methods if both displayless and robot should handle them.
* The robot treat's switch case can call super.treat before or after any robot-specific handling.
*
* @param mes the message
*/
@Override
public void treat(SOCMessage mes) {
if (mes == null)
// Message syntax error or unknown type
return;
// Using debugRandomPause?
if (debugRandomPause && (!robotBrains.isEmpty()) && (mes instanceof SOCMessageForGame) && !(mes instanceof SOCGameTextMsg) && !(mes instanceof SOCGameServerText) && !(mes instanceof SOCTurn)) {
final String ga = ((SOCMessageForGame) mes).getGame();
if (ga != null) {
SOCRobotBrain brain = robotBrains.get(ga);
if (brain != null) {
if (!debugRandomPauseActive) {
// random chance of doing so
if ((Math.random() < DEBUGRANDOMPAUSE_FREQ) && ((debugRandomPauseQueue == null) || (debugRandomPauseQueue.isEmpty()))) {
SOCGame gm = games.get(ga);
final int cpn = gm.getCurrentPlayerNumber();
SOCPlayer rpl = gm.getPlayer(nickname);
if ((rpl != null) && (cpn == rpl.getPlayerNumber()) && (gm.getGameState() >= SOCGame.ROLL_OR_CARD)) {
// we're current player, pause us
debugRandomPauseActive = true;
debugRandomPauseUntil = System.currentTimeMillis() + (1000L * DEBUGRANDOMPAUSE_SECONDS);
if (debugRandomPauseQueue == null)
debugRandomPauseQueue = new Vector<SOCMessage>();
System.err.println("L379 -> do random pause: " + nickname);
sendText(gm, "debugRandomPauseActive for " + DEBUGRANDOMPAUSE_SECONDS + " seconds");
}
}
}
}
}
}
if (debugRandomPause && debugRandomPauseActive) {
if ((System.currentTimeMillis() < debugRandomPauseUntil) && !(mes instanceof SOCTurn)) {
// time hasn't arrived yet, and still our turn:
// Add message to queue (even non-game and SOCGameTextMsg)
debugRandomPauseQueue.addElement(mes);
// <--- Early return: debugRandomPauseActive ---
return;
}
// time to resume the queue
debugRandomPauseActive = false;
while (!debugRandomPauseQueue.isEmpty()) {
// calling ourself is safe, because
// ! queue.isEmpty; thus won't decide
// to set debugRandomPauseActive=true again.
treat(debugRandomPauseQueue.firstElement());
debugRandomPauseQueue.removeElementAt(0);
}
// Don't return from this method yet,
// we still need to process mes.
}
if ((debugTraffic || D.ebugIsEnabled()) && !((mes instanceof SOCServerPing) && (nextServerPingExpectedAt != 0) && (Math.abs(System.currentTimeMillis() - nextServerPingExpectedAt) <= 66000))) // within 66 seconds of the expected time; see displaylesscli.handleSERVERPING
{
soc.debug.D.ebugPrintln("IN - " + nickname + " - " + mes);
}
try {
switch(mes.getType()) {
/**
* status message
*/
case SOCMessage.STATUSMESSAGE:
handleSTATUSMESSAGE((SOCStatusMessage) mes);
break;
/**
* admin ping
*/
case SOCMessage.ADMINPING:
handleADMINPING((SOCAdminPing) mes);
break;
/**
* admin reset
*/
case SOCMessage.ADMINRESET:
handleADMINRESET((SOCAdminReset) mes);
break;
/**
* update the current robot parameters
*/
case SOCMessage.UPDATEROBOTPARAMS:
handleUPDATEROBOTPARAMS((SOCUpdateRobotParams) mes);
break;
/**
* join game authorization
*/
case SOCMessage.JOINGAMEAUTH:
handleJOINGAMEAUTH((SOCJoinGameAuth) mes, (sLocal != null));
break;
/**
* game has been destroyed
*/
case SOCMessage.DELETEGAME:
handleDELETEGAME((SOCDeleteGame) mes);
break;
/**
* list of game members
*/
case SOCMessage.GAMEMEMBERS:
handleGAMEMEMBERS((SOCGameMembers) mes);
break;
/**
* game text message (bot debug commands)
*/
case SOCMessage.GAMETEXTMSG:
handleGAMETEXTMSG((SOCGameTextMsg) mes);
break;
/**
* someone is sitting down
*/
case SOCMessage.SITDOWN:
handleSITDOWN((SOCSitDown) mes);
break;
/**
* update the state of the game
*/
case SOCMessage.GAMESTATE:
handleGAMESTATE((SOCGameState) mes);
break;
/**
* a player built something
*/
case SOCMessage.PUTPIECE:
handlePUTPIECE((SOCPutPiece) mes);
break;
/**
* the server is requesting that we join a game
*/
case SOCMessage.BOTJOINGAMEREQUEST:
handleBOTJOINGAMEREQUEST((SOCBotJoinGameRequest) mes);
break;
/**
* message that means the server wants us to leave the game
*/
case SOCMessage.ROBOTDISMISS:
handleROBOTDISMISS((SOCRobotDismiss) mes);
break;
/**
* handle board reset (new game with same players, same game name, new layout).
*/
case SOCMessage.RESETBOARDAUTH:
handleRESETBOARDAUTH((SOCResetBoardAuth) mes);
break;
/**
* generic "simple request" responses or announcements from the server.
* Message type added 2013-02-17 for v1.1.18,
* bot ignored these until 2015-10-10 for v2.0.00 SC_PIRI
* and for PROMPT_PICK_RESOURCES from gold hex.
*/
case SOCMessage.SIMPLEREQUEST:
super.handleSIMPLEREQUEST(games, (SOCSimpleRequest) mes);
handlePutBrainQ((SOCSimpleRequest) mes);
break;
/**
* generic "simple action" announcements from the server.
* Added 2013-09-04 for v1.1.19.
*/
case SOCMessage.SIMPLEACTION:
super.handleSIMPLEACTION(games, (SOCSimpleAction) mes);
handlePutBrainQ((SOCSimpleAction) mes);
break;
/**
* a special inventory item action: either add or remove,
* or we cannot play our requested item.
* Added 2013-11-26 for v2.0.00.
*/
case SOCMessage.INVENTORYITEMACTION:
{
final boolean isReject = super.handleINVENTORYITEMACTION(games, (SOCInventoryItemAction) mes);
if (isReject)
handlePutBrainQ((SOCInventoryItemAction) mes);
}
break;
/**
* Special Item change announcements.
* Added 2014-04-16 for v2.0.00.
*/
case SOCMessage.SETSPECIALITEM:
super.handleSETSPECIALITEM(games, (SOCSetSpecialItem) mes);
handlePutBrainQ((SOCSetSpecialItem) mes);
break;
case SOCMessage.ACCEPTOFFER:
// current player has cancelled an initial settlement
case SOCMessage.CANCELBUILDREQUEST:
// server wants our player to choose to rob cloth or rob resources from victim
case SOCMessage.CHOOSEPLAYER:
case SOCMessage.CHOOSEPLAYERREQUEST:
case SOCMessage.CLEAROFFER:
// either draw, play, or add to hand, or cannot play our requested dev card
case SOCMessage.DEVCARDACTION:
case SOCMessage.DICERESULT:
case SOCMessage.DISCARDREQUEST:
case SOCMessage.BANKTRADE:
case SOCMessage.MAKEOFFER:
// move a previously placed ship; will update game data and player trackers
case SOCMessage.MOVEPIECE:
case SOCMessage.MOVEROBBER:
case SOCMessage.PLAYERELEMENT:
// apply multiple PLAYERELEMENT updates; added 2017-12-10 for v2.0.00
case SOCMessage.PLAYERELEMENTS:
case SOCMessage.REJECTOFFER:
case SOCMessage.RESOURCECOUNT:
// added 2017-12-18 for v2.0.00 when gameState became a field of this message
case SOCMessage.STARTGAME:
// server's 1x/second timing ping
case SOCMessage.TIMINGPING:
case SOCMessage.TURN:
handlePutBrainQ((SOCMessageForGame) mes);
break;
case SOCMessage.BCASTTEXTMSG:
case SOCMessage.CHANGEFACE:
case SOCMessage.CHANNELMEMBERS:
// If bot ever uses CHANNELS, update SOCChannels class javadoc
case SOCMessage.CHANNELS:
case SOCMessage.CHANNELTEXTMSG:
case SOCMessage.DELETECHANNEL:
case SOCMessage.GAMES:
// SOCGameServerText contents are ignored by bots
case SOCMessage.GAMESERVERTEXT:
// (but not SOCGameTextMsg, which is used solely for debug commands)
case SOCMessage.GAMESTATS:
case SOCMessage.JOINCHANNEL:
case SOCMessage.JOINCHANNELAUTH:
case SOCMessage.LEAVECHANNEL:
case SOCMessage.NEWCHANNEL:
case SOCMessage.NEWGAME:
case SOCMessage.SETSEATLOCK:
// ignore this message type
break;
/**
* Call SOCDisplaylessClient.treat for all other message types.
* For types relevant to robots, it will update data from the message contents.
* Other message types will be ignored.
*/
default:
super.treat(mes, true);
}
} catch (Throwable e) {
System.err.println("SOCRobotClient treat ERROR - " + e + " " + e.getMessage());
e.printStackTrace();
while (e.getCause() != null) {
e = e.getCause();
System.err.println(" -> nested: " + e.getClass());
e.printStackTrace();
}
System.err.println("-- end stacktrace --");
System.out.println(" For message: " + mes);
}
}
use of soc.game.SOCPlayer in project JSettlers2 by jdmonin.
the class SOCBoardAtServer method startGame_putInitPieces.
/**
* For scenario game option {@link SOCGameOption#K_SC_PIRI _SC_PIRI},
* place each player's initial pieces. For {@link SOCGameOption#K_SC_FTRI _SC_FTRI},
* set aside some dev cards to be claimed later at Special Edges.
* Otherwise do nothing.
*<P>
* For {@code _SC_PIRI}, also calls each player's {@link SOCPlayer#addLegalSettlement(int, boolean)}
* for their Lone Settlement location (adds layout part "LS").
* Vacant player numbers get 0 for their {@code "LS"} element.
*<P>
* Called only at server. For a method called during game start
* at server and clients, see {@link SOCGame#updateAtBoardLayout()}.
*<P>
* Called from {@link SOCGameHandler#startGame(SOCGame)} for those
* scenario game options; if you need it called for your game, add
* a check there for your scenario's {@link SOCGameOption}.
*<P>
* This is called after {@link #makeNewBoard(Map)} and before
* {@link SOCGameHandler#getBoardLayoutMessage}. So if needed,
* it can call {@link SOCBoardLarge#setAddedLayoutPart(String, int[])}.
*<P>
* If ship placement is restricted by the scenario, please call each player's
* {@link SOCPlayer#setRestrictedLegalShips(int[])} before calling this method,
* so the legal and potential arrays will be initialized.
*
* @see #getLegalSeaEdges(SOCGame, int)
*/
public void startGame_putInitPieces(SOCGame ga) {
if (ga.isGameOptionSet(SOCGameOption.K_SC_FTRI)) {
// Set aside dev cards for players to be given when reaching "CE" Special Edges.
final int cpn = ga.getCurrentPlayerNumber();
// to call buyDevCard without giving it to a player
ga.setCurrentPlayerNumber(-1);
drawStack = new Stack<Integer>();
final int n = FOR_TRI_DEV_CARD_EDGES[(ga.maxPlayers > 4) ? 1 : 0].length;
for (int i = 0; i < n; ++i) drawStack.push(ga.buyDevCard());
ga.setCurrentPlayerNumber(cpn);
return;
}
if (!ga.isGameOptionSet(SOCGameOption.K_SC_PIRI))
return;
final int gstate = ga.getGameState();
// prevent ga.putPiece from advancing turn
ga.setGameState(SOCGame.READY);
final int[] inits = PIR_ISL_INIT_PIECES[(ga.maxPlayers > 4) ? 1 : 0];
// lone possible-settlement node on the way to the island.
int[] possiLoneSettles = new int[ga.maxPlayers];
// vacant players will get 0 here, will not get free settlement, ship, or pirate fortress.
// iterate i only when player present, to avoid spacing gaps from vacant players
int i = 0;
for (int pn = 0; pn < ga.maxPlayers; ++pn) {
if (ga.isSeatVacant(pn))
continue;
SOCPlayer pl = ga.getPlayer(pn);
ga.putPiece(new SOCSettlement(pl, inits[i], this));
++i;
ga.putPiece(new SOCShip(pl, inits[i], this));
++i;
ga.putPiece(new SOCFortress(pl, inits[i], this));
++i;
possiLoneSettles[pn] = inits[i];
ga.getPlayer(pn).addLegalSettlement(inits[i], false);
++i;
}
setAddedLayoutPart("LS", possiLoneSettles);
ga.setGameState(gstate);
}
use of soc.game.SOCPlayer 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();
}
Aggregations