soc.robot
Class SOCRobotDM

java.lang.Object
  extended by soc.robot.SOCRobotDM

public class SOCRobotDM
extends java.lang.Object

Moved the routines that pick what to build or buy next out of SOCRobotBrain. Didn't want to call this SOCRobotPlanner because it doesn't really plan, but you could think of it that way. DM = Decision Maker

Uses the info in the SOCPlayerTrackers. One important method here is planStuff(int), which updates buildingPlan and related fields.

Author:
Robert S. Thomas

Field Summary
protected  float adversarialFactor
           
protected  SOCRobotBrain brain
           
protected  java.util.Stack<SOCPossiblePiece> buildingPlan
          ourPlayerData's building plan; a stack of SOCPossiblePiece.
protected static int CITY_CHOICE
           
protected  float devCardMultiplier
           
protected static java.text.DecimalFormat df1
           
protected  float etaBonusFactor
           
static int FAST_STRATEGY
           
protected  SOCPossibleCity favoriteCity
           
protected  SOCPossibleRoad favoriteRoad
          A road or ship we could build this turn, chosen from threatenedRoads or goodRoads in smartGameStrategy(int[]).
protected  SOCPossibleSettlement favoriteSettlement
          A settlement to build, chosen from goodSettlements or threatenedSettlements.
protected  SOCGame game
          The game we're playing in
protected  java.util.Vector<SOCPossibleRoad> goodRoads
          A road or ship (SOCPossibleRoad and/or subclass SOCPossibleShip) we could build this turn; its SOCPossibleRoad.getNecessaryRoads() is empty.
protected  java.util.Vector<SOCPossibleSettlement> goodSettlements
          Good settlements, as calculated by scorePossibleSettlements(int, int)
protected static int LA_CHOICE
           
protected  float leaderAdversarialFactor
           
protected static int LR_CHOICE
           
protected  int maxETA
           
protected  int maxGameLength
           
protected static int ONE_OF_EACH
           
protected  SOCPlayer ourPlayerData
           
private  int ourPlayerNumber
          ourPlayerData's player number.
protected  SOCPlayerTracker ourPlayerTracker
           
protected  java.util.HashMap<java.lang.Integer,SOCPlayerTracker> playerTrackers
           
protected  SOCPossibleCard possibleCard
           
protected static int SETTLEMENT_CHOICE
           
static int SMART_STRATEGY
          used for describing strategies
protected  java.util.Vector<SOCPossibleRoad> threatenedRoads
          Roads threatened by other players; currently unused.
protected  java.util.Vector<SOCPossibleSettlement> threatenedSettlements
          Threatened settlements, as calculated by scorePossibleSettlements(int, int)
protected  float threatMultiplier
           
protected static int TWO_CITIES
           
protected static int TWO_SETTLEMENTS
          used in planStuff
protected static int WIN_LA
           
protected static int WIN_LR
           
 
Constructor Summary
SOCRobotDM(SOCRobotBrain br)
          constructor
SOCRobotDM(SOCRobotParameters params, java.util.HashMap<java.lang.Integer,SOCPlayerTracker> pt, SOCPlayerTracker opt, SOCPlayer opd, java.util.Stack<SOCPossiblePiece> bp)
          Constructor to use if you don't want to use a brain.
 
Method Summary
protected  float calcWGETABonus(java.util.HashMap<java.lang.Integer,SOCPlayerTracker> trackersBefore, java.util.HashMap<java.lang.Integer,SOCPlayerTracker> trackersAfter)
          Calc the win game ETA bonus for a move, based on SOCPlayerTracker.getWinGameETA().
private  float calcWGETABonusAux(int[] originalWGETAs, java.util.HashMap<java.lang.Integer,SOCPlayerTracker> trackersAfter, java.util.Vector<SOCPlayerTracker> leaders)
          Helps calculate WGETA bonus for making a move or other change in the game.
protected  void dumbFastGameStrategy(int[] buildingETAs)
          Plan building for the dumbFastGameStrategy (FAST_STRATEGY).
 SOCPossibleCard getDevCardScore(int cardETA, int leadersCurrentWGETA)
          Calc dev card score bonus for SMART_STRATEGY based on improvements to Win Game ETA (WGETA) from buying knights or +1 VP cards, weighted by their distribution, tunable devCardMultiplier, and effects on the leading opponent players' WGETAs.
(package private)  float getETABonus(int eta, int leadWGETA, float bonus)
          Calc the weighted ETA bonus for a move, adjusting bonus for eta and our etaBonusFactor.
 SOCPossibleCity getFavoriteCity()
           
 SOCPossibleRoad getFavoriteRoad()
           
 SOCPossibleSettlement getFavoriteSettlement()
           
 SOCPossibleCard getPossibleCard()
           
protected  float getWinGameETABonus(SOCPossiblePiece posPiece)
          add a bonus to the possible piece score based on the change in win game ETA
protected  float getWinGameETABonusForRoad(SOCPossibleRoad posRoad, int roadETA, int leadersCurrentWGETA, java.util.HashMap<java.lang.Integer,SOCPlayerTracker> playerTrackers)
          For SMART_STRATEGY, add a bonus to the road or ship score based on the change in win game ETA for this one road or ship (possible settlements are 1 road closer, longest road bonus, etc).
private  void planRoadBuildingTwoRoads()
          For planStuff(int), if we have a road building card, make sure we build two roads first.
 void planStuff(int strategy)
          make some building plans.
(package private) static java.lang.Object recalcLongestRoadETAAux(SOCPlayer pl, boolean wantsStack, int startNode, int pathLength, int lrLength, int searchDepth)
          Does a depth first search from the end point of the longest path in a graph of nodes and returns how many roads would need to be built to take longest road.
private  boolean scenarioGameStrategyPlan_SC_PIRI_buildNextShip()
          If possible, calculate where our next ship would be placed, and add it to buildingPlan.
private  boolean scenarioGameStrategyPlan_SC_PIRI(float bestScoreOrETA, float cardScoreOrETA, boolean isScoreNotETA, boolean bestPlanIsDevCard, SOCBuildingSpeedEstimate ourBSE, int leadersCurrentWGETA, boolean forSpecialBuildingPhase)
          scenarioGameStrategyPlan(..) for _SC_PIRI.
private  boolean scenarioGameStrategyPlan_SC_WOND(float bestScoreOrETA, float cardScoreOrETA, boolean isScoreNotETA, boolean bestPlanIsDevCard, SOCBuildingSpeedEstimate ourBSE, int leadersCurrentWGETA, boolean forSpecialBuildingPhase)
          scenarioGameStrategyPlan(..) for _SC_WOND.
private  boolean scenarioGameStrategyPlan(float bestScoreOrETA, float cardScoreOrETA, boolean isScoreNotETA, boolean bestPlanIsDevCard, SOCBuildingSpeedEstimate ourBSE, int leadersCurrentWGETA, boolean forSpecialBuildingPhase)
          For some game scenarios (currently _SC_PIRI and _SC_WOND), evaluate and plan any special move.
protected  void scorePossibleSettlements(int settlementETA, int leadersCurrentWGETA)
          Score possible settlements for for the smart game strategy (SMART_STRATEGY), from ourPlayerTracker.getPossibleSettlements() into threatenedSettlements and goodSettlements; calculate those settlements' SOCPossiblePiece.getScore()s.
protected  void scoreSettlementsForDumb(int settlementETA, SOCBuildingSpeedEstimate ourBSE)
          For each possible settlement in our SOCPlayerTracker, update its getETA() and its getRoadPath().
protected  void smartGameStrategy(int[] buildingETAs)
          Plan building for the smart game strategy (SMART_STRATEGY).
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

df1

protected static final java.text.DecimalFormat df1

maxGameLength

protected int maxGameLength

maxETA

protected int maxETA

etaBonusFactor

protected float etaBonusFactor

adversarialFactor

protected float adversarialFactor

leaderAdversarialFactor

protected float leaderAdversarialFactor

devCardMultiplier

protected float devCardMultiplier

threatMultiplier

protected float threatMultiplier

LA_CHOICE

protected static final int LA_CHOICE
See Also:
Constant Field Values

LR_CHOICE

protected static final int LR_CHOICE
See Also:
Constant Field Values

CITY_CHOICE

protected static final int CITY_CHOICE
See Also:
Constant Field Values

SETTLEMENT_CHOICE

protected static final int SETTLEMENT_CHOICE
See Also:
Constant Field Values

TWO_SETTLEMENTS

protected static final int TWO_SETTLEMENTS
used in planStuff

See Also:
Constant Field Values

TWO_CITIES

protected static final int TWO_CITIES
See Also:
Constant Field Values

ONE_OF_EACH

protected static final int ONE_OF_EACH
See Also:
Constant Field Values

WIN_LA

protected static final int WIN_LA
See Also:
Constant Field Values

WIN_LR

protected static final int WIN_LR
See Also:
Constant Field Values

SMART_STRATEGY

public static final int SMART_STRATEGY
used for describing strategies

See Also:
Constant Field Values

FAST_STRATEGY

public static final int FAST_STRATEGY
See Also:
Constant Field Values

brain

protected SOCRobotBrain brain

playerTrackers

protected java.util.HashMap<java.lang.Integer,SOCPlayerTracker> playerTrackers

ourPlayerTracker

protected SOCPlayerTracker ourPlayerTracker

ourPlayerData

protected final SOCPlayer ourPlayerData

ourPlayerNumber

private final int ourPlayerNumber
ourPlayerData's player number.

Since:
2.0.00

buildingPlan

protected java.util.Stack<SOCPossiblePiece> buildingPlan
ourPlayerData's building plan; a stack of SOCPossiblePiece. Same Stack as SOCRobotBrain.getBuildingPlan(). May include SOCPossibleCard to be bought. Filled each turn by planStuff(int). Emptied by SOCRobotBrain.


game

protected final SOCGame game
The game we're playing in


threatenedRoads

protected java.util.Vector<SOCPossibleRoad> threatenedRoads
Roads threatened by other players; currently unused.


goodRoads

protected java.util.Vector<SOCPossibleRoad> goodRoads
A road or ship (SOCPossibleRoad and/or subclass SOCPossibleShip) we could build this turn; its SOCPossibleRoad.getNecessaryRoads() is empty. Built in smartGameStrategy(int[]).


favoriteRoad

protected SOCPossibleRoad favoriteRoad
A road or ship we could build this turn, chosen from threatenedRoads or goodRoads in smartGameStrategy(int[]). If we want to build this soon, it will be added to buildingPlan.


threatenedSettlements

protected java.util.Vector<SOCPossibleSettlement> threatenedSettlements
Threatened settlements, as calculated by scorePossibleSettlements(int, int)


goodSettlements

protected java.util.Vector<SOCPossibleSettlement> goodSettlements
Good settlements, as calculated by scorePossibleSettlements(int, int)


favoriteSettlement

protected SOCPossibleSettlement favoriteSettlement
A settlement to build, chosen from goodSettlements or threatenedSettlements. If we want to build this soon, it will be added to buildingPlan.


favoriteCity

protected SOCPossibleCity favoriteCity

possibleCard

protected SOCPossibleCard possibleCard
Constructor Detail

SOCRobotDM

public SOCRobotDM(SOCRobotBrain br)
constructor

Parameters:
br - the robot brain

SOCRobotDM

public SOCRobotDM(SOCRobotParameters params,
                  java.util.HashMap<java.lang.Integer,SOCPlayerTracker> pt,
                  SOCPlayerTracker opt,
                  SOCPlayer opd,
                  java.util.Stack<SOCPossiblePiece> bp)
Constructor to use if you don't want to use a brain.

Parameters:
params - the robot parameters
pt - the player trackers
opt - our player tracker
opd - our player data
bp - our building plan
Method Detail

getFavoriteSettlement

public SOCPossibleSettlement getFavoriteSettlement()
Returns:
favorite settlement

getFavoriteCity

public SOCPossibleCity getFavoriteCity()
Returns:
favorite city

getFavoriteRoad

public SOCPossibleRoad getFavoriteRoad()
Returns:
favorite road or ship

getPossibleCard

public SOCPossibleCard getPossibleCard()
Returns:
possible card

planStuff

public void planStuff(int strategy)
make some building plans. Called as needed by SOCRobotBrain and related strategy classes. Sets buildingPlan, favoriteSettlement, etc. Calls either smartGameStrategy(int[]) or dumbFastGameStrategy(int[]). Both of those will check whether this is our normal turn, or if it's the 6-player board's Special Building Phase. Both strategies also call scenarioGameStrategyPlan(..) if the game has an applicable scenario such as _SC_PIRI.

Some details:

Parameters:
strategy - an integer that determines which strategy is used (SMART_STRATEGY or FAST_STRATEGY)

dumbFastGameStrategy

protected void dumbFastGameStrategy(int[] buildingETAs)
Plan building for the dumbFastGameStrategy (FAST_STRATEGY). uses rules to determine what to build next and update buildingPlan.

For example, if favoriteSettlement is chosen, it's chosen from ourPlayerTracker.getPossibleSettlements().

Outline:

Possible cities and settlements are looked at first. Find the city with best SOCPossibleCity.getSpeedupTotal(), then check each possible settlement's SOCPossiblePiece.getETA() against the city's ETA to possibly choose one to build. (If one is chosen, its SOCPossibleSettlement.getNecessaryRoads() will also be chosen here.) Then, Knights or Dev Cards. Only then would roads or ships be looked at, for Longest Route (and only if we're at 5 VP or more).

This method never directly checks ourPlayerTracker.getPossibleRoads(), instead it adds the roads or ships from SOCPossibleSettlement.getNecessaryRoads() to buildingPlan when a possible settlement is picked to build.

Some scenarios require special moves or certain actions to win the game. If we're playing in such a scenario, after calculating favoriteSettlement, favoriteCity, etc, calls scenarioGameStrategyPlan(float, float, boolean, boolean, SOCBuildingSpeedEstimate, int, boolean). See that method for the list of scenarios which need such planning.

Parameters:
buildingETAs - the ETAs for building each piece type
See Also:
smartGameStrategy(int[])

scoreSettlementsForDumb

protected void scoreSettlementsForDumb(int settlementETA,
                                       SOCBuildingSpeedEstimate ourBSE)
For each possible settlement in our SOCPlayerTracker, update its getETA() and its getRoadPath().

Each SOCPossibleSettlement.getRoadPath() is calculated here by finding the shortest path among its SOCPossibleSettlement.getNecessaryRoads().

Calculates ETA by using our current SOCBuildingSpeedEstimate on the resources needed to buy the settlement plus roads/ships for its shortest path's length.

Parameters:
settlementETA - ETA for building a settlement from now if it doesn't require any roads or ships
ourBSE - Current building speed estimate, from our SOCPlayer#getNumbers()
See Also:
scorePossibleSettlements(int, int)

planRoadBuildingTwoRoads

private final void planRoadBuildingTwoRoads()
For planStuff(int), if we have a road building card, make sure we build two roads first. Pick 2 good potential roads, and push them onto buildingPlan.

Call only when our SOCPlayer:

Since:
2.0.00

recalcLongestRoadETAAux

static java.lang.Object recalcLongestRoadETAAux(SOCPlayer pl,
                                                boolean wantsStack,
                                                int startNode,
                                                int pathLength,
                                                int lrLength,
                                                int searchDepth)
Does a depth first search from the end point of the longest path in a graph of nodes and returns how many roads would need to be built to take longest road.

Do not call if SOCGameOption.K_SC_0RVP is set, because this method needs SOCPlayer.getLRPaths() which will be empty.

Combined implementation for use by SOCRobotDM and SOCPlayerTracker.

Parameters:
pl - Calculate this player's longest road; typically SOCRobotDM.ourPlayerData or SOCPlayerTracker.player
wantsStack - If true, return the Stack; otherwise, return numRoads.
startNode - the path endpoint
pathLength - the length of that path
lrLength - length of longest road in the game
searchDepth - how many roads out to search
Returns:
if wantsStack: a Stack containing the path of roads with the last one on top, or null if it can't be done. If ! wantsStack: Integer: the number of roads needed, or 500 if it can't be done

smartGameStrategy

protected void smartGameStrategy(int[] buildingETAs)
Plan building for the smart game strategy (SMART_STRATEGY). use player trackers' Win Game ETAs (WGETA) to determine best move and update buildingPlan.

For example, if favoriteSettlement is chosen, it's chosen from goodSettlements or {threatenedSettlements.

Some scenarios require special moves or certain actions to win the game. If we're playing in such a scenario, after calculating favoriteSettlement, favoriteCity, etc, calls scenarioGameStrategyPlan(float, float, boolean, boolean, SOCBuildingSpeedEstimate, int, boolean). See that method for the list of scenarios which need such planning.

Outline:

Parameters:
buildingETAs - the ETAs for building each piece type
See Also:
dumbFastGameStrategy(int[])

scenarioGameStrategyPlan

private final boolean scenarioGameStrategyPlan(float bestScoreOrETA,
                                               float cardScoreOrETA,
                                               boolean isScoreNotETA,
                                               boolean bestPlanIsDevCard,
                                               SOCBuildingSpeedEstimate ourBSE,
                                               int leadersCurrentWGETA,
                                               boolean forSpecialBuildingPhase)
                                        throws java.lang.IllegalArgumentException
For some game scenarios (currently _SC_PIRI and _SC_WOND), evaluate and plan any special move. If the scenario-specific move would score higher than the currently picked building plan from smartGameStrategy(int[]) or dumbFastGameStrategy(int[]), push those scenario-specific moves onto buildingPlan.

Example of such a move: For _SC_PIRI, each player must build ships out west to their pirate fortress, upgrading them to warships to defend against the pirate fleet and build strength to attack and defeat the fortress.

Parameters:
bestScoreOrETA - Current plan's score for SMART_STRATEGY or ETA for FAST_STRATEGY.
cardScoreOrETA - Score or ETA to buy a card if known, or -1. smartGameStrategy should always calculate this if the move makes sense, dumbFastGameStrategy skips it and calculates the ETA for several cards.
isScoreNotETA - True if bestScoreOrETA is a score and not a building ETA; higher scores are better, lower ETAs are better
bestPlanIsDevCard - True if the current best plan is to buy a dev card
ourBSE - Our player's current SOCBuildingSpeedEstimate with our SOCPlayer.getNumbers()
leadersCurrentWGETA - For SMART_STRATEGY, the game leader's Win Game ETA from SOCPlayerTracker.getWinGameETA(). Unused here (0) for FAST_STRATEGY.
forSpecialBuildingPhase - True if we're in the SOCGame.SPECIAL_BUILDING Phase, not our full turn
Returns:
True if a Scenario-specific buildingPlan was pushed
Throws:
java.lang.IllegalArgumentException - if smartGameStrategy didn't calculate cardScoreOrETA and it's -1
Since:
2.0.00

scenarioGameStrategyPlan_SC_PIRI

private final boolean scenarioGameStrategyPlan_SC_PIRI(float bestScoreOrETA,
                                                       float cardScoreOrETA,
                                                       boolean isScoreNotETA,
                                                       boolean bestPlanIsDevCard,
                                                       SOCBuildingSpeedEstimate ourBSE,
                                                       int leadersCurrentWGETA,
                                                       boolean forSpecialBuildingPhase)
                                                throws java.lang.IllegalArgumentException
scenarioGameStrategyPlan(..) for _SC_PIRI. See that method for parameter meanings and other info.

Throws:
java.lang.IllegalArgumentException
Since:
2.0.00

scenarioGameStrategyPlan_SC_PIRI_buildNextShip

private final boolean scenarioGameStrategyPlan_SC_PIRI_buildNextShip()
If possible, calculate where our next ship would be placed, and add it to buildingPlan. Assumes our player's SOCPlayer.getFortress() is west of all boats we've already placed. If our line of ships has reached the fortress per SOCPlayer.getMostRecentShip(), nothing to do: That goal is complete.

Returns:
True if next ship is possible and was added to buildingPlan
Since:
2.0.00

scenarioGameStrategyPlan_SC_WOND

private final boolean scenarioGameStrategyPlan_SC_WOND(float bestScoreOrETA,
                                                       float cardScoreOrETA,
                                                       boolean isScoreNotETA,
                                                       boolean bestPlanIsDevCard,
                                                       SOCBuildingSpeedEstimate ourBSE,
                                                       int leadersCurrentWGETA,
                                                       boolean forSpecialBuildingPhase)
                                                throws java.lang.IllegalArgumentException
scenarioGameStrategyPlan(..) for _SC_WOND. See that method for parameter meanings and other info.

Throws:
java.lang.IllegalArgumentException
Since:
2.0.00

scorePossibleSettlements

protected void scorePossibleSettlements(int settlementETA,
                                        int leadersCurrentWGETA)
Score possible settlements for for the smart game strategy (SMART_STRATEGY), from ourPlayerTracker.getPossibleSettlements() into threatenedSettlements and goodSettlements; calculate those settlements' SOCPossiblePiece.getScore()s. Ignores possible settlements that require roads or ships.

See Also:
scoreSettlementsForDumb(int, SOCBuildingSpeedEstimate)

getWinGameETABonus

protected float getWinGameETABonus(SOCPossiblePiece posPiece)
add a bonus to the possible piece score based on the change in win game ETA

Parameters:
posPiece - the possible piece that we're scoring

getWinGameETABonusForRoad

protected float getWinGameETABonusForRoad(SOCPossibleRoad posRoad,
                                          int roadETA,
                                          int leadersCurrentWGETA,
                                          java.util.HashMap<java.lang.Integer,SOCPlayerTracker> playerTrackers)
For SMART_STRATEGY, add a bonus to the road or ship score based on the change in win game ETA for this one road or ship (possible settlements are 1 road closer, longest road bonus, etc).

Parameters:
posRoad - the possible piece that we're scoring
roadETA - the ETA for a road or ship, from building speed estimates
leadersCurrentWGETA - the leaders current WGETA
playerTrackers - the player trackers (for figuring out road building plan and bonus/ETA)

calcWGETABonus

protected float calcWGETABonus(java.util.HashMap<java.lang.Integer,SOCPlayerTracker> trackersBefore,
                               java.util.HashMap<java.lang.Integer,SOCPlayerTracker> trackersAfter)
Calc the win game ETA bonus for a move, based on SOCPlayerTracker.getWinGameETA(). The bonus is based on lowering your bot's WGETA and increasing the leaders' WGETA.

Parameters:
trackersBefore - list of player trackers before move
trackersAfter - list of player trackers after move; call SOCPlayerTracker.updateWinGameETAs(trackersAfter) before calling this method

calcWGETABonusAux

private float calcWGETABonusAux(int[] originalWGETAs,
                                java.util.HashMap<java.lang.Integer,SOCPlayerTracker> trackersAfter,
                                java.util.Vector<SOCPlayerTracker> leaders)
Helps calculate WGETA bonus for making a move or other change in the game. The bonus is based on lowering your bot's WGETA and increasing the leaders' WGETA.

Parameters:
originalWGETAs - the original WGETAs; each player's SOCPlayerTracker.getWinGameETA() before the change
trackersAfter - the playerTrackers after the change; call SOCPlayerTracker.updateWinGameETAs(trackersAfter) before calling this method
leaders - a list of leaders (players winning soonest); the player(s) with lowest SOCPlayerTracker.getWinGameETA(). Contains only one element, unless there is an ETA tie.

getDevCardScore

public SOCPossibleCard getDevCardScore(int cardETA,
                                       int leadersCurrentWGETA)
Calc dev card score bonus for SMART_STRATEGY based on improvements to Win Game ETA (WGETA) from buying knights or +1 VP cards, weighted by their distribution, tunable devCardMultiplier, and effects on the leading opponent players' WGETAs.

Assumes SOCPlayerTracker.getWinGameETA() is accurate at time of call. Calls SOCPlayerTracker.updateWinGameETAs(HashMap) after temporarily adding a knight or +1VP card, but doesn't call it after cleaning up from the temporary add, so SOCPlayerTracker.getWinGameETA() will be inaccurate afterwards.


getETABonus

float getETABonus(int eta,
                  int leadWGETA,
                  float bonus)
Calc the weighted ETA bonus for a move, adjusting bonus for eta and our etaBonusFactor.

Parameters:
eta - the current building ETA for a building type. From SOCBuildingSpeedEstimate.getEstimatesFromNowFast(SOCResourceSet, boolean[]).
leadWGETA - the WGETA (Win Game ETA) of the leader
bonus - Base WGETA bonus, before weight adjustment. From calcWGETABonus(HashMap, HashMap), calcWGETABonusAux(int[], HashMap, Vector), etc.
Returns:
the weighted ETA bonus