|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object soc.robot.SOCRobotDM
public class SOCRobotDM
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 SOCPlayerTracker
s.
One important method here is planStuff(int)
,
which updates buildingPlan
and related fields.
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 |
---|
protected static final java.text.DecimalFormat df1
protected int maxGameLength
protected int maxETA
protected float etaBonusFactor
protected float adversarialFactor
protected float leaderAdversarialFactor
protected float devCardMultiplier
protected float threatMultiplier
protected static final int LA_CHOICE
protected static final int LR_CHOICE
protected static final int CITY_CHOICE
protected static final int SETTLEMENT_CHOICE
protected static final int TWO_SETTLEMENTS
protected static final int TWO_CITIES
protected static final int ONE_OF_EACH
protected static final int WIN_LA
protected static final int WIN_LR
public static final int SMART_STRATEGY
public static final int FAST_STRATEGY
protected SOCRobotBrain brain
protected java.util.HashMap<java.lang.Integer,SOCPlayerTracker> playerTrackers
protected SOCPlayerTracker ourPlayerTracker
protected final SOCPlayer ourPlayerData
private final int ourPlayerNumber
ourPlayerData
's player number.
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
.
protected final SOCGame game
protected java.util.Vector<SOCPossibleRoad> threatenedRoads
protected java.util.Vector<SOCPossibleRoad> goodRoads
SOCPossibleRoad
and/or subclass SOCPossibleShip
)
we could build this turn; its SOCPossibleRoad.getNecessaryRoads()
is empty.
Built in smartGameStrategy(int[])
.
protected SOCPossibleRoad favoriteRoad
threatenedRoads
or goodRoads
in smartGameStrategy(int[])
.
If we want to build this soon, it will be added to buildingPlan
.
protected java.util.Vector<SOCPossibleSettlement> threatenedSettlements
scorePossibleSettlements(int, int)
protected java.util.Vector<SOCPossibleSettlement> goodSettlements
scorePossibleSettlements(int, int)
protected SOCPossibleSettlement favoriteSettlement
goodSettlements
or threatenedSettlements
.
If we want to build this soon, it will be added to buildingPlan
.
protected SOCPossibleCity favoriteCity
protected SOCPossibleCard possibleCard
Constructor Detail |
---|
public SOCRobotDM(SOCRobotBrain br)
br
- the robot brainpublic SOCRobotDM(SOCRobotParameters params, java.util.HashMap<java.lang.Integer,SOCPlayerTracker> pt, SOCPlayerTracker opt, SOCPlayer opd, java.util.Stack<SOCPossiblePiece> bp)
params
- the robot parameterspt
- the player trackersopt
- our player trackeropd
- our player databp
- our building planMethod Detail |
---|
public SOCPossibleSettlement getFavoriteSettlement()
public SOCPossibleCity getFavoriteCity()
public SOCPossibleRoad getFavoriteRoad()
public SOCPossibleCard getPossibleCard()
public void planStuff(int strategy)
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:
SOCBuildingSpeedEstimate
based on our current dice numbers
SOCBuildingSpeedEstimate.getEstimatesFromNowFast(SOCResourceSet, boolean[])
with our current resources and ports
SMART_STRATEGY
, update all SOCPlayerTracker.updateWinGameETAs(HashMap)
resetScore()
and clearBiggestThreats()
SMART_STRATEGY
and we have a Road Building card, plan and push 2 roads onto buildingPlan
strategy
- an integer that determines which strategy is used
(SMART_STRATEGY
or FAST_STRATEGY
)protected void dumbFastGameStrategy(int[] buildingETAs)
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()
.
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.
buildingETAs
- the ETAs for building each piece typesmartGameStrategy(int[])
protected void scoreSettlementsForDumb(int settlementETA, SOCBuildingSpeedEstimate ourBSE)
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.
settlementETA
- ETA for building a settlement from now if it doesn't require any roads or shipsourBSE
- Current building speed estimate, from our SOCPlayer#getNumbers()
scorePossibleSettlements(int, int)
private final void planRoadBuildingTwoRoads()
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
:
SOCDevCardConstants.ROADS
card to play
hasPlayedDevCard()
static java.lang.Object recalcLongestRoadETAAux(SOCPlayer pl, boolean wantsStack, int startNode, int pathLength, int lrLength, int searchDepth)
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
.
pl
- Calculate this player's longest road;
typically SOCRobotDM.ourPlayerData or SOCPlayerTracker.playerwantsStack
- If true, return the Stack; otherwise, return numRoads.startNode
- the path endpointpathLength
- the length of that pathlrLength
- length of longest road in the gamesearchDepth
- how many roads out to search
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 doneprotected void smartGameStrategy(int[] buildingETAs)
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.
scorePossibleSettlements(BuildETAs, leaderWGETA)
:
For each settlement we can build now (no roads/ships needed), add its ETA bonus to its score
goodRoads
from possibleRoads' roads & ships we can build now
favoriteSettlement
from threatened/good settlements, with the highest
getScore()
(ETA bonus)
favoriteRoad
from threatened/good, with highest getWinGameETABonusForRoad
favoriteCity
from our possibleCities, with highest score (ETA bonus)
favoriteCity
has the best score (best ETA if tied), choose to build the city
favoriteRoad
or favoriteSettlement
based on their scores
buildingPlan
buildingETAs
- the ETAs for building each piece typedumbFastGameStrategy(int[])
private final boolean scenarioGameStrategyPlan(float bestScoreOrETA, float cardScoreOrETA, boolean isScoreNotETA, boolean bestPlanIsDevCard, SOCBuildingSpeedEstimate ourBSE, int leadersCurrentWGETA, boolean forSpecialBuildingPhase) throws java.lang.IllegalArgumentException
_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.
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 betterbestPlanIsDevCard
- True if the current best plan is to buy a dev cardourBSE
- 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
java.lang.IllegalArgumentException
- if smartGameStrategy
didn't calculate cardScoreOrETA
and it's -1private 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.
java.lang.IllegalArgumentException
private final boolean scenarioGameStrategyPlan_SC_PIRI_buildNextShip()
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.
buildingPlan
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.
java.lang.IllegalArgumentException
protected void scorePossibleSettlements(int settlementETA, int leadersCurrentWGETA)
SMART_STRATEGY
),
from ourPlayerTracker
.getPossibleSettlements()
into threatenedSettlements
and goodSettlements
;
calculate those settlements' SOCPossiblePiece.getScore()
s.
Ignores possible settlements that require roads or ships.
scoreSettlementsForDumb(int, SOCBuildingSpeedEstimate)
protected float getWinGameETABonus(SOCPossiblePiece posPiece)
posPiece
- the possible piece that we're scoringprotected float getWinGameETABonusForRoad(SOCPossibleRoad posRoad, int roadETA, int leadersCurrentWGETA, java.util.HashMap<java.lang.Integer,SOCPlayerTracker> playerTrackers)
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).
SOCPlayerTracker.tryPutPiece(SOCPlayingPiece, SOCGame, HashMap)
which makes a copy of the player trackers and puts the piece there.
This also updates our player's VP total, including any special VP from placement.
SOCPlayerTracker.updateWinGameETAs(HashMap)
on that copy
calcWGETABonus(HashMap, HashMap)
to compare WGETA before and after placement
getETABonus(int, int, float)
to weigh that bonus
posRoad
's SOCPossiblePiece.getScore()
SOCPlayerTracker.undoTryPutPiece(SOCPlayingPiece, SOCGame)
posRoad
- the possible piece that we're scoringroadETA
- the ETA for a road or ship, from building speed estimatesleadersCurrentWGETA
- the leaders current WGETAplayerTrackers
- the player trackers (for figuring out road building plan and bonus/ETA)protected float calcWGETABonus(java.util.HashMap<java.lang.Integer,SOCPlayerTracker> trackersBefore, java.util.HashMap<java.lang.Integer,SOCPlayerTracker> trackersAfter)
SOCPlayerTracker.getWinGameETA()
.
The bonus is based on lowering your bot's WGETA and increasing the leaders' WGETA.
trackersBefore
- list of player trackers before movetrackersAfter
- list of player trackers after move;
call SOCPlayerTracker.updateWinGameETAs(trackersAfter)
before calling this methodprivate float calcWGETABonusAux(int[] originalWGETAs, java.util.HashMap<java.lang.Integer,SOCPlayerTracker> trackersAfter, java.util.Vector<SOCPlayerTracker> leaders)
originalWGETAs
- the original WGETAs; each player's SOCPlayerTracker.getWinGameETA()
before the changetrackersAfter
- the playerTrackers after the change;
call SOCPlayerTracker.updateWinGameETAs(trackersAfter)
before calling this methodleaders
- a list of leaders (players winning soonest);
the player(s) with lowest SOCPlayerTracker.getWinGameETA()
.
Contains only one element, unless there is an ETA tie.public SOCPossibleCard getDevCardScore(int cardETA, int leadersCurrentWGETA)
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.
float getETABonus(int eta, int leadWGETA, float bonus)
bonus
for eta
and our etaBonusFactor
.
eta
- the current building ETA for a building type.
From SOCBuildingSpeedEstimate.getEstimatesFromNowFast(SOCResourceSet, boolean[])
.leadWGETA
- the WGETA (Win Game ETA) of the leaderbonus
- Base WGETA bonus, before weight adjustment.
From calcWGETABonus(HashMap, HashMap)
, calcWGETABonusAux(int[], HashMap, Vector)
, etc.
|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |