|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object soc.robot.SOCPlayerTracker
public class SOCPlayerTracker
This class is used by the SOCRobotBrain to track strategic planning information such as possible building spots for itself and other players. Also used for prediction of other players' possible upcoming moves.
Some users of this class are: SOCRobotDM.planStuff(int)
,
and many callers of getWinGameETA()
(Dissertation excerpt)
"When a player places a road, that player's PlayerTracker will look ahead by pretending to place new roads attached to that road and then recording new potential settlements [and their roads]...The PlayerTracker only needs to be updated when players put pieces on the board... not only when that player builds a road but when any player builds a road or settlement. This is because another player's road or settlement may cut off a path to a future settlement. This update can be done by keeping track of which pieces support the building of others."
To output a legible overview of the data in a SOCPlayerTracker, use playerTrackersDebug(HashMap)
.
Field Summary | |
---|---|
protected SOCRobotBrain |
brain
The robot brain using this tracker |
protected static int |
EXPAND_LEVEL
Road expansion level for addOurNewRoadOrShip(SOCRoad, HashMap, int) ;
how far away to look for possible future settlements
(level of recursion). |
protected static int |
EXPAND_LEVEL_SHIP_EXTRA
Ship route length expansion level to add to EXPAND_LEVEL for
expandRoadOrShip(SOCPossibleRoad, SOCPlayer, SOCPlayer, HashMap, int) . |
(package private) boolean |
inUse
monitor for synchronization |
protected int |
knightsToBuy
|
protected int |
largestArmyETA
|
protected int |
longestRoadETA
|
protected static int |
LR_CALC_LEVEL
Road expansion level for updateLRPotential(SOCPossibleRoad, SOCPlayer, SOCRoad, int, int) ;
how far away to look for possible future roads
(level of recursion). |
protected boolean |
needLA
|
protected boolean |
needLR
|
protected SOCSettlement |
pendingInitSettlement
Player's settlement during initial placement; delay processing until the road is placed, and thus the settlement placement can't be moved around. |
private SOCPlayer |
player
The player being tracked |
private int |
playerNumber
Seat number of the player being tracked; player .getPlayerNumber() |
protected java.util.TreeMap<java.lang.Integer,SOCPossibleCity> |
possibleCities
Key = Integer node coordinate, value = SOCPossibleCity |
protected java.util.TreeMap<java.lang.Integer,SOCPossibleRoad> |
possibleRoads
Includes both roads and ships. |
protected java.util.TreeMap<java.lang.Integer,SOCPossibleSettlement> |
possibleSettlements
Possible near-future settlements for this player. |
protected int |
roadsToGo
|
private SOCShip |
scen_SC_PIRI_closestShipToFortress
For scenario _SC_PIRI , the player's ship closest to the Fortress (the ship farthest west). |
protected int |
winGameETA
|
Constructor Summary | |
---|---|
SOCPlayerTracker(SOCPlayer pl,
SOCRobotBrain br)
Constructor. |
|
SOCPlayerTracker(SOCPlayerTracker pt)
Copy constructor. |
Method Summary | |
---|---|
void |
addNewRoadOrShip(SOCRoad road,
java.util.HashMap<java.lang.Integer,SOCPlayerTracker> trackers)
add a road or ship that has just been built |
void |
addNewSettlement(SOCSettlement settlement,
java.util.HashMap<java.lang.Integer,SOCPlayerTracker> trackers)
Add a settlement that has just been built. |
void |
addOurNewCity(SOCCity city)
add one of our cities, by removing it from the possible-cities list if it's there. |
private void |
addOurNewRoadOrShip(SOCRoad road,
java.util.HashMap<java.lang.Integer,SOCPlayerTracker> trackers,
int expandLevel)
Add one of our roads or ships that has just been built. |
void |
addOurNewSettlement(SOCSettlement settlement,
java.util.HashMap<java.lang.Integer,SOCPlayerTracker> trackers)
Add one of our settlements, and newly possible pieces from it. |
private void |
addTheirNewRoadOrShip(SOCRoad road,
boolean isCancel)
add another player's new road or ship, or cancel our own bad road by acting as if another player has placed there. |
void |
addTheirNewSettlement(SOCSettlement settlement,
boolean isCancel)
add another player's new settlement, or cancel our own bad settlement by acting as if another player has placed there. |
void |
cancelWrongCity(SOCCity city)
Remove our incorrect city placement, it's been rejected by the server. |
void |
cancelWrongRoadOrShip(SOCRoad road)
Remove our incorrect road or ship placement, it's been rejected by the server. |
void |
cancelWrongSettlement(SOCSettlement settlement)
Remove our incorrect settlement placement, it's been rejected by the server. |
static java.util.HashMap<java.lang.Integer,SOCPlayerTracker> |
copyPlayerTrackers(java.util.HashMap<java.lang.Integer,SOCPlayerTracker> trackers)
make copies of player trackers and then make connections between copied pieces |
void |
expandRoadOrShip(SOCPossibleRoad targetRoad,
SOCPlayer player,
SOCPlayer dummy,
java.util.HashMap<java.lang.Integer,SOCPlayerTracker> trackers,
int level)
Expand a possible road or ship, to see what placements it makes possible. |
SOCRobotBrain |
getBrain()
|
int |
getKnightsToBuy()
Get the number of knights needed to take Largest Army. |
int |
getLargestArmyETA()
Get the ETA to take Largest Army. |
int |
getLongestRoadETA()
Get the ETA to take Longest Road. |
SOCSettlement |
getPendingInitSettlement()
|
SOCPlayer |
getPlayer()
|
java.util.TreeMap<java.lang.Integer,SOCPossibleCity> |
getPossibleCities()
|
java.util.TreeMap<java.lang.Integer,SOCPossibleRoad> |
getPossibleRoads()
Get the possible roads and ships ( SOCPossibleRoad , SOCPossibleShip ). |
java.util.TreeMap<java.lang.Integer,SOCPossibleSettlement> |
getPossibleSettlements()
|
int |
getRoadsToGo()
Get how many roads must be built to take Longest Road. |
SOCShip |
getScenario_SC_PIRI_closestShipToFortress()
For scenario _SC_PIRI , get the player's ship closest to their Fortress (the ship farthest west). |
int |
getScenario_SC_PIRI_shipDistanceToFortress(SOCShip ship)
For scenario _SC_PIRI , get the distance of this player's closest ship from their
SOCFortress . |
int |
getWinGameETA()
Get the calculated Winning the Game ETA (WGETA), based on the most recent call to recalcWinGameETA() . |
boolean |
needsLA()
Does this player need Largest Army to win? Updated by recalcWinGameETA() . |
boolean |
needsLR()
Does this player need Longest Road to win? Updated by recalcWinGameETA() . |
static void |
playerTrackersDebug(java.util.HashMap<java.lang.Integer,SOCPlayerTracker> playerTrackers)
Print debug output for a set of player trackers. |
void |
recalcLargestArmyETA()
calculate the largest army ETA |
void |
recalcLongestRoadETA()
Calculate the longest road ETA. |
private int |
recalcLongestRoadETAAux(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. |
(package private) SOCPossibleShip |
recalcScenario_SC_PIRI_nextPotentialShip()
For scenario _SC_PIRI , get the player's next potential ship towards their Fortress. |
void |
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 SOCPlayer.getTotalVP() to SOCGame.vp_winner . |
void |
releaseMonitor()
release the monitor for this tracker |
protected void |
removeDependents(SOCPossibleRoad road)
remove everything that depends on this road being built |
protected void |
removeFromNecessaryRoads(SOCPossibleRoad pr)
remove this piece from the pieces that support it |
protected void |
removeFromNecessaryRoads(SOCPossibleSettlement ps)
remove this piece from the pieces that support it |
void |
setPendingInitSettlement(SOCSettlement s)
set this player's pending initial settlement, to be placed/calculated by this tracker after their road. |
void |
takeMonitor()
take the monitor for this tracker |
java.lang.String |
toString()
SOCPlayerTracker key fields (brain player name, tracked player name) to aid debugging. |
static java.util.HashMap<java.lang.Integer,SOCPlayerTracker> |
tryPutPiece(SOCPlayingPiece piece,
SOCGame game,
java.util.HashMap<java.lang.Integer,SOCPlayerTracker> trackers)
See how building a piece impacts the game. |
static void |
tryPutPieceNoCopy(SOCPlayingPiece piece,
SOCGame game,
java.util.HashMap<java.lang.Integer,SOCPlayerTracker> trackers)
Same as tryPutPiece ,
but we don't make a copy of the player trackers. |
void |
undoAddOurNewCity(SOCPossibleCity city)
undo adding one of our cities |
static void |
undoTryPutPiece(SOCPlayingPiece piece,
SOCGame game)
Reset the game back to before we put the temp piece |
void |
updateLRPotential(SOCPossibleRoad posRoad,
SOCPlayer dummy,
SOCRoad dummyRoad,
int lrLength,
int level)
update the potential LR value of a possible road or ship by placing dummy roads/ships and calculating LR (longest road). |
void |
updateLRValues()
update the longest road values for all possible roads/ships. |
(package private) void |
updateScenario_SC_PIRI_closestShipToFortress(SOCShip ship,
boolean shipAdded)
For scenario _SC_PIRI , update the player's ship closest to their Fortress. |
protected void |
updateSettlementConflicts(SOCPossibleSettlement ps,
java.util.HashMap<java.lang.Integer,SOCPlayerTracker> trackers)
update settlement conflicts |
void |
updateThreats(java.util.HashMap<java.lang.Integer,SOCPlayerTracker> trackers)
update threats for pieces that need to be updated |
static void |
updateWinGameETAs(java.util.HashMap<java.lang.Integer,SOCPlayerTracker> playerTrackers)
Update winGameETAs for player trackers. |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait |
Field Detail |
---|
protected static int EXPAND_LEVEL
addOurNewRoadOrShip(SOCRoad, HashMap, int)
;
how far away to look for possible future settlements
(level of recursion).
protected static int EXPAND_LEVEL_SHIP_EXTRA
EXPAND_LEVEL
for
expandRoadOrShip(SOCPossibleRoad, SOCPlayer, SOCPlayer, HashMap, int)
.
protected static int LR_CALC_LEVEL
updateLRPotential(SOCPossibleRoad, SOCPlayer, SOCRoad, int, int)
;
how far away to look for possible future roads
(level of recursion).
protected final SOCRobotBrain brain
private final SOCPlayer player
private final int playerNumber
player
.getPlayerNumber()
protected java.util.TreeMap<java.lang.Integer,SOCPossibleSettlement> possibleSettlements
Integer
node coordinate, value = SOCPossibleSettlement
.
Expanded in addOurNewRoadOrShip(SOCRoad, HashMap, int)
via expandRoadOrShip(SOCPossibleRoad, SOCPlayer, SOCPlayer, HashMap, int)
.
Also updated in addNewSettlement(SOCSettlement, HashMap)
,
cancelWrongSettlement(SOCSettlement)
, a few other places.
protected java.util.TreeMap<java.lang.Integer,SOCPossibleRoad> possibleRoads
Integer
edge coordinate, value = SOCPossibleRoad
or SOCPossibleShip
Expanded in addOurNewRoadOrShip(SOCRoad, HashMap, int)
via expandRoadOrShip(SOCPossibleRoad, SOCPlayer, SOCPlayer, HashMap, int)
.
protected java.util.TreeMap<java.lang.Integer,SOCPossibleCity> possibleCities
Integer
node coordinate, value = SOCPossibleCity
protected int longestRoadETA
protected int roadsToGo
protected int largestArmyETA
protected int winGameETA
protected int knightsToBuy
protected boolean needLR
protected boolean needLA
protected SOCSettlement pendingInitSettlement
private SOCShip scen_SC_PIRI_closestShipToFortress
_SC_PIRI
, the player's ship closest to the Fortress (the ship farthest west).
null
otherwise. Updated by updateScenario_SC_PIRI_closestShipToFortress(SOCShip, boolean)
.
boolean inUse
Constructor Detail |
---|
public SOCPlayerTracker(SOCPlayer pl, SOCRobotBrain br)
pl
- the player being trackedbr
- the robot brain using this trackerpublic SOCPlayerTracker(SOCPlayerTracker pt)
Note: Does NOT copy connections between possible pieces
pt
- the player trackerMethod Detail |
---|
public static java.util.HashMap<java.lang.Integer,SOCPlayerTracker> copyPlayerTrackers(java.util.HashMap<java.lang.Integer,SOCPlayerTracker> trackers)
Note: not copying threats param trackers player trackers for each player
public void takeMonitor()
public void releaseMonitor()
public SOCRobotBrain getBrain()
public SOCPlayer getPlayer()
public java.util.TreeMap<java.lang.Integer,SOCPossibleRoad> getPossibleRoads()
SOCPossibleRoad
, SOCPossibleShip
).
Treat the structure of the returned map as read-only, don't add or remove anything.
public java.util.TreeMap<java.lang.Integer,SOCPossibleSettlement> getPossibleSettlements()
public java.util.TreeMap<java.lang.Integer,SOCPossibleCity> getPossibleCities()
public int getLongestRoadETA()
updateWinGameETAs(HashMap)
or recalcLongestRoadETA()
.
needsLR()
,
getRoadsToGo()
public int getRoadsToGo()
updateWinGameETAs(HashMap)
and recalcLongestRoadETA()
.
needsLR()
,
getLongestRoadETA()
public int getLargestArmyETA()
updateWinGameETAs(HashMap)
and recalcLargestArmyETA()
.
needsLA()
,
getKnightsToBuy()
public int getKnightsToBuy()
updateWinGameETAs(HashMap)
and recalcLargestArmyETA()
.
needsLA()
,
getLargestArmyETA()
public SOCSettlement getPendingInitSettlement()
public void setPendingInitSettlement(SOCSettlement s)
You must call addNewSettlement and then addNewRoadOrShip: This is just a place to store the settlement data.
s
- Settlement, or nullpublic void addNewRoadOrShip(SOCRoad road, java.util.HashMap<java.lang.Integer,SOCPlayerTracker> trackers)
road
- the road or shiptrackers
- player trackers for the playerspublic void cancelWrongRoadOrShip(SOCRoad road)
road
- Location of our bad road or shipSOCRobotBrain.cancelWrongPiecePlacement(SOCCancelBuildRequest)
private void addOurNewRoadOrShip(SOCRoad road, java.util.HashMap<java.lang.Integer,SOCPlayerTracker> trackers, int expandLevel)
expandRoadOrShip(SOCPossibleRoad, SOCPlayer, SOCPlayer, HashMap, int)
on newly possible adjacent roads or ships.
road
- the road or shiptrackers
- player trackers for the playersexpandLevel
- how far out we should expand roads/ships;
passed to expandRoadOrShip(SOCPossibleRoad, SOCPlayer, SOCPlayer, HashMap, int)
public void expandRoadOrShip(SOCPossibleRoad targetRoad, SOCPlayer player, SOCPlayer dummy, java.util.HashMap<java.lang.Integer,SOCPlayerTracker> trackers, int level)
possibleSettlements
at targetRoad's nodes, if potential.
If level > 0, calls itself recursively to go more levels out from the current pieces,
adding/updating possibleRoads
and possibleSettlements
.
Scenario _SC_PIRI
: Ships in this scenario never expand east (never away from the
pirate fortress). Scenario rules require the route to be as short as possible. Even if a human
player might want to do so, it couldn't interfere with the bot's own route, so we don't track
that possibility.
targetRoad
- the possible roadplayer
- the player who owns the original roaddummy
- the dummy player used to see what's legaltrackers
- player trackerslevel
- how many levels (additional pieces) to expand;
0 to only check targetRoad for potential settlements
and not expand past it for new roads, ships, or further settlementsprivate void addTheirNewRoadOrShip(SOCRoad road, boolean isCancel)
road
- the new road or shipisCancel
- Is this our own robot's road placement, rejected by the server?
If so, this method call will cancel its placement within the tracker data.public SOCShip getScenario_SC_PIRI_closestShipToFortress()
_SC_PIRI
, get the player's ship closest to their Fortress (the ship farthest west).
Updated by updateScenario_SC_PIRI_closestShipToFortress(SOCShip, boolean)
.
_SC_PIRI
; null
otherwise.getScenario_SC_PIRI_shipDistanceToFortress(SOCShip)
void updateScenario_SC_PIRI_closestShipToFortress(SOCShip ship, boolean shipAdded) throws java.lang.IllegalArgumentException
_SC_PIRI
, update the player's ship closest to their Fortress.
Assumes no ship will ever be west of the fortress (smaller column number).
Must be called after adding or removing a ship from our player's SOCPlayer.getRoads()
.
ship
- Ship that was added or removed, or null
to check all ships after removalshipAdded
- True if ship
was added; false if ship
or any other ship was removed
or if we're updating Closest Ship without adding or removing a ship
java.lang.IllegalArgumentException
- if shipAdded
is true, but null ship
public int getScenario_SC_PIRI_shipDistanceToFortress(SOCShip ship)
_SC_PIRI
, get the distance of this player's closest ship from their
SOCFortress
. Since ships aren't placed diagonally, this is the distance along rows + columns.
The edge (r,c) has node (r,c) as its left end, at distance 0.
ship
- Any ship, including getScenario_SC_PIRI_closestShipToFortress()
SOCPossibleShip recalcScenario_SC_PIRI_nextPotentialShip()
_SC_PIRI
, get the player's next potential ship towards their Fortress.
If fortress was already defeated, or they have no boats, returns null
.
This is calculated every time, not cached, because potential-ships list may change often.
Calls updateScenario_SC_PIRI_closestShipToFortress(SOCShip, boolean)
if closest ship not known.
null
protected void updateSettlementConflicts(SOCPossibleSettlement ps, java.util.HashMap<java.lang.Integer,SOCPlayerTracker> trackers)
ps
- a possible settlementtrackers
- player trackers for all playerspublic void addNewSettlement(SOCSettlement settlement, java.util.HashMap<java.lang.Integer,SOCPlayerTracker> trackers)
SOCGame.putPiece(SOCPlayingPiece)
or SOCGame.putTempPiece(SOCPlayingPiece)
.
settlement
- the settlementtrackers
- player trackers for the playerspublic void cancelWrongSettlement(SOCSettlement settlement)
settlement
- Location of our bad settlementSOCRobotBrain.cancelWrongPiecePlacement(SOCCancelBuildRequest)
public void addOurNewSettlement(SOCSettlement settlement, java.util.HashMap<java.lang.Integer,SOCPlayerTracker> trackers)
Newly possible roads or ships next to the settlement are expanded by calling
expandRoadOrShip(SOCPossibleRoad, SOCPlayer, SOCPlayer, HashMap, int)
.
EXPAND_LEVEL
is the basic expansion length, and ships add
EXPAND_LEVEL_SHIP_EXTRA
to that for crossing the sea to nearby islands.
Called in 2 different conditions:
tryPutPiece(SOCPlayingPiece, SOCGame, HashMap)
)
settlement
- the new settlementtrackers
- player trackers for all of the playerspublic void addTheirNewSettlement(SOCSettlement settlement, boolean isCancel)
settlement
- the new settlementisCancel
- Is this our own robot's settlement placement, rejected by the server?
If so, this method call will cancel its placement within the tracker data.protected void removeDependents(SOCPossibleRoad road)
road
- the roadprotected void removeFromNecessaryRoads(SOCPossibleRoad pr)
pr
- the possible roadprotected void removeFromNecessaryRoads(SOCPossibleSettlement ps)
ps
- the possible settlementpublic void cancelWrongCity(SOCCity city)
Note, there is no addNewCity or addTheirNewCity method.
city
- Location of our bad citySOCRobotBrain.cancelWrongPiecePlacement(SOCCancelBuildRequest)
public void addOurNewCity(SOCCity city)
city
- the new citypublic void undoAddOurNewCity(SOCPossibleCity city)
city
- the now possible citypublic void updateThreats(java.util.HashMap<java.lang.Integer,SOCPlayerTracker> trackers)
trackers
- all of the player trackerspublic void recalcLongestRoadETA()
SOCGameOption.K_SC_0RVP
is set.
Updates fields for getLongestRoadETA()
and getRoadsToGo()
.
private int recalcLongestRoadETAAux(int startNode, int pathLength, int lrLength, int searchDepth)
Do not call if SOCGameOption.K_SC_0RVP
is set.
startNode
- the path endpointpathLength
- the length of that pathlrLength
- length of longest road in the gamesearchDepth
- how many roads out to search
public void recalcLargestArmyETA()
public void updateLRValues()
longest road value is how much this road/ship would increase our longest road if it were built.
the longest road potential is how much this road/ship would increase our LR value if other roads supported by this one were built.
public void updateLRPotential(SOCPossibleRoad posRoad, SOCPlayer dummy, SOCRoad dummyRoad, int lrLength, int level)
posRoad
- the possible road or shipdummy
- the dummy playerlrLength
- the current LR lengthlevel
- how many levels of recursion, or 0 to not recursepublic int getWinGameETA()
recalcWinGameETA()
.
public boolean needsLR()
recalcWinGameETA()
.
getLongestRoadETA()
,
getRoadsToGo()
public boolean needsLA()
recalcWinGameETA()
.
getLargestArmyETA()
,
getKnightsToBuy()
public void recalcWinGameETA()
SOCPlayer.getTotalVP()
to SOCGame.vp_winner
.
Calculates the fields for getWinGameETA()
, needsLA()
, needsLR()
.
Each time through the loop, given potential locations and available pieces, pick the fastest ETA among each of these 2-VP combinations:
expandRoadOrShip(SOCPossibleRoad, SOCPlayer, SOCPlayer, HashMap, int)
, so it may run out
of potential locations before 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.
If the loop reaches 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 static java.util.HashMap<java.lang.Integer,SOCPlayerTracker> tryPutPiece(SOCPlayingPiece piece, SOCGame game, java.util.HashMap<java.lang.Integer,SOCPlayerTracker> trackers)
SOCGame.putTempPiece(SOCPlayingPiece)
and copyPlayerTrackers(HashMap)
,
then adds piece to the tracker copies.
piece
- the piece to buildgame
- the gametrackers
- the player trackers
tryPutPieceNoCopy(SOCPlayingPiece, SOCGame, HashMap)
public static void tryPutPieceNoCopy(SOCPlayingPiece piece, SOCGame game, java.util.HashMap<java.lang.Integer,SOCPlayerTracker> trackers)
tryPutPiece
,
but we don't make a copy of the player trackers. Instead caller supplies the copy.
piece
- the piece to buildgame
- the gametrackers
- the already-copied player trackerspublic static void undoTryPutPiece(SOCPlayingPiece piece, SOCGame game)
piece
- the piece to removegame
- the gamepublic static void playerTrackersDebug(java.util.HashMap<java.lang.Integer,SOCPlayerTracker> playerTrackers)
Calls D.ebugPrintln; no output will appear if this class imports soc.disableDebug.D instead of soc.debug.D.
playerTrackers
- the player trackerspublic static void updateWinGameETAs(java.util.HashMap<java.lang.Integer,SOCPlayerTracker> playerTrackers)
recalcLongestRoadETA()
,
recalcLargestArmyETA()
, recalcWinGameETA()
.
playerTrackers
- the player trackerspublic java.lang.String toString()
super.
hashCode()
.
toString
in class java.lang.Object
|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |