|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object java.lang.Thread soc.robot.SOCRobotBrain
public class SOCRobotBrain
AI for playing Settlers of Catan.
Represents a robot player within 1 game.
The bot is a separate thread, so everything happens in run()
or a method called from there.
Some robot behaviors are altered by the SOCRobotParameters
passed into our constructor.
Some decision-making code is in the OpeningBuildStrategy
,
RobberStrategy
, MonopolyStrategy
, etc classes.
Data and predictions about the other players in the game is in
SOCPlayerTracker
. If we're trading with other players for
resources, some details of that are in SOCRobotNegotiator
.
All these, and data on the game and players, are initialized in
setOurPlayerData()
.
At the start of each player's turn, buildingPlan
and most other state fields are cleared
(search run()
for mesType == SOCMessage.TURN).
The plan for what to build next is decided in SOCRobotDM.planStuff(int)
(called from planBuilding()
and some other places) which updates buildingPlan
.
That plan is executed in buildOrGetResourceByTradeOrCard()
.
Current status and the next expected action are tracked by the "waitingFor" and "expect" flag fields.
If we've sent the server an action and we're waiting for the result, waitingForGameState
is true
along with one other "expect" flag, such as expectPLACING_ROBBER
.
All these fields can be output for inspection by calling debugPrintBrainStatus()
.
See run()
for more details of how the bot waits for and reacts to incoming messages.
Some robot actions wait for other players or other timeouts; the brain counts SOCTimingPing
messages
(1 per second) for timing. For robustness testing, the SOCRobotClient.debugRandomPause
flag can
be used to inject random delays in incoming messages.
To keep the game moving, the server may force an inactive bot to end its turn;
see SOCForceEndTurnThread
.
Nested Class Summary |
---|
Nested classes/interfaces inherited from class java.lang.Thread |
---|
java.lang.Thread.State, java.lang.Thread.UncaughtExceptionHandler |
Field Summary | |
---|---|
protected boolean |
alive
Flag for whether or not we're alive |
protected java.util.Stack<SOCPossiblePiece> |
buildingPlan
This is our current building plan, a stack of SOCPossiblePiece . |
protected SOCRobotClient |
client
The client we are hooked up to |
protected int |
counter
A counter used to measure passage of time. |
protected int |
currentDRecorder
keeps track of which dRecorder is current |
protected int |
curState
Our current state |
private boolean |
decidedIfSpecialBuild
During this turn, which is another player's turn, have we yet decided whether to do the Special Building phase (for the 6-player board)? |
protected SOCRobotDM |
decisionMaker
the thing that determines what we want to build next |
protected boolean |
doneTrading
true if we're done trading |
protected DebugRecorder[] |
dRecorder
an object for recording debug information that can be accessed interactively |
protected SOCPlayer |
dummyCancelPlayerData
Dummy player for cancelling bad placements |
protected boolean |
expectDICERESULT
true if we're expecting a DICERESULT message |
protected boolean |
expectDISCARD
true if we're expecting a DISCARDREQUEST message |
protected boolean |
expectMOVEROBBER
true if we're expecting to have to move the robber |
protected boolean |
expectPLACING_CITY
true if we're expecting the PLACING_CITY state |
protected boolean |
expectPLACING_FREE_ROAD1
true if we're expecting the PLACING_FREE_ROAD1 state |
protected boolean |
expectPLACING_FREE_ROAD2
true if we're expecting the PLACING_FREE_ROAD2 state |
protected boolean |
expectPLACING_ROAD
true if we're expecting the PLACING_ROAD state |
protected boolean |
expectPLACING_ROBBER
True if we're expecting the PLACING_ROBBER state. |
protected boolean |
expectPLACING_SETTLEMENT
true if we're expecting the PLACING_SETTLEMENT state |
protected boolean |
expectPLACING_SHIP
true if we're expecting the PLACING_SHIP game state |
protected boolean |
expectPLAY
true if we're expecting the PLAY state |
protected boolean |
expectPLAY1
true if we're expecting the PLAY1 state |
protected boolean |
expectPUTPIECE_FROM_START1A
true if were expecting a PUTPIECE message after a START1A game state |
protected boolean |
expectPUTPIECE_FROM_START1B
true if were expecting a PUTPIECE message after a START1B game state |
protected boolean |
expectPUTPIECE_FROM_START2A
true if were expecting a PUTPIECE message after a START1A game state |
protected boolean |
expectPUTPIECE_FROM_START2B
true if were expecting a PUTPIECE message after a START1A game state |
protected boolean |
expectPUTPIECE_FROM_START3A
true if were expecting a PUTPIECE message after a START3A game state. |
protected boolean |
expectPUTPIECE_FROM_START3B
true if were expecting a PUTPIECE message after a START3B game state. |
protected boolean |
expectSTART1A
true if we're expecting the START1A state |
protected boolean |
expectSTART1B
true if we're expecting the START1B state |
protected boolean |
expectSTART2A
true if we're expecting the START2A state |
protected boolean |
expectSTART2B
true if we're expecting the START2B state |
protected boolean |
expectSTART3A
true if we're expecting the START3A state. |
protected boolean |
expectSTART3B
true if we're expecting the START3B state. |
protected boolean |
expectWAITING_FOR_DISCOVERY
true if we're expecting to pick two resources |
protected boolean |
expectWAITING_FOR_MONOPOLY
true if we're expecting to pick a monopoly |
protected int |
failedBuildingAttempts
Track how many illegal placement requests we've made this turn. |
protected SOCGame |
game
The game we are playing |
protected CappedQueue<SOCMessage> |
gameEventQ
The queue of game messages; contents are SOCMessage . |
private boolean |
gameIs6Player
The game we're playing is on the 6-player board. |
protected SOCPossiblePiece |
lastMove
keeps track of the last thing we bought, for debugging purposes |
private int |
lastStartingPieceCoord
During START states, coordinate of our most recently placed road or settlement. |
private int |
lastStartingRoadTowardsNode
During START1B and START2B states, coordinate of the potential settlement node towards which we're building, as calculated by OpeningBuildStrategy.planInitRoad() . |
protected SOCPossiblePiece |
lastTarget
keeps track of the last thing we wanted, for debugging purposes |
static int |
MAX_DENIED_BUILDING_PER_TURN
If, during a turn, we make this many illegal build requests that the server denies, stop trying. |
private MonopolyStrategy |
monopolyStrategy
Strategy to choose whether to monopolize, and which resource. |
protected boolean |
moveRobberOnSeven
True when the robber will move because a seven was rolled. |
protected SOCRobotNegotiator |
negotiator
The data and code that determines how we negotiate. |
protected boolean[] |
offerRejections
true if the player with that player number has rejected our offer |
protected int |
oldGameState
the game state before the current one |
private OpeningBuildStrategy |
openingBuildStrategy
Strategy to plan and build initial settlements and roads. |
protected SOCPlayer |
ourPlayerData
Our player data Set in setOurPlayerData() |
private int |
ourPlayerNumber
Our player number; set in setOurPlayerData() . |
protected SOCPlayerTracker |
ourPlayerTracker
our player tracker |
protected boolean |
ourTurn
Flag for whether or not it is our turn |
private boolean |
pauseFaster
Pause for less time;
speeds up response in 6-player games. |
protected SOCRobotPinger |
pinger
a thread that sends ping messages to this one |
protected java.util.HashMap<java.lang.Integer,SOCPlayerTracker> |
playerTrackers
trackers for all players (one per player, including this robot) |
protected java.util.Random |
rand
Random number generator |
private int |
rejectedPlayDevCardType
If set, the server rejected our play of this dev card type this turn (such as SOCDevCardConstants.KNIGHT ) because of a bug in our
robot; should not attempt to play the same type again this turn. |
protected SOCResourceSet |
resourceChoices
these are the two resources that we want when we play a discovery dev card |
(package private) SOCRobotParameters |
robotParameters
The robot parameters |
private java.util.Vector<SOCMessage> |
turnEventsCurrent
The game messages received this turn / previous turn, for debugging. |
private java.util.Vector<SOCMessage> |
turnEventsPrev
The game messages received this turn / previous turn, for debugging. |
private int |
turnExceptionCount
Number of exceptions caught this turn, if any. |
protected int |
turnTime
Timer for turn taking |
protected boolean |
waitingForDevCard
true when we're waiting to receive a dev card |
protected boolean |
waitingForGameState
true if we're waiting for a GAMESTATE message from the server. |
protected boolean |
waitingForOurTurn
true if we're waiting for a TURN message from the server
when it's our turn |
protected java.lang.String |
waitingForPickSpecialItem
Non- null if we're waiting for server response to picking
a SOCSpecialItem , for certain scenarios; contains the typeKey
of the special item we're waiting on. |
protected boolean |
waitingForSC_PIRI_FortressRequest
True if we're in a _SC_PIRI game
and waiting for server response to a SOCSimpleRequest
to attack a pirate fortress. |
private boolean |
waitingForSpecialBuild
true when we're waiting for our requested Special Building phase (for the 6-player board). |
protected boolean |
waitingForTradeMsg
true when we're waiting for the results of a trade |
protected boolean |
waitingForTradeResponse
true if we're waiting for a response to our trade message |
protected SOCPlayingPiece |
whatWeFailedToBuild
This is what we tried building this turn, but the server said it was an illegal move (due to a bug in our robot). |
protected SOCPlayingPiece |
whatWeWantToBuild
This is the piece we want to build now. |
Fields inherited from class java.lang.Thread |
---|
MAX_PRIORITY, MIN_PRIORITY, NORM_PRIORITY |
Constructor Summary | |
---|---|
SOCRobotBrain(SOCRobotClient rc,
SOCRobotParameters params,
SOCGame ga,
CappedQueue<SOCMessage> mq)
Create a robot brain to play a game. |
Method Summary | |
---|---|
void |
addPlayerTracker(int pn)
A player has sat down and been added to the game, during game formation. |
private void |
buildOrGetResourceByTradeOrCard()
Either ask to build a planned piece, or use trading or development cards to get resources to build it. |
private void |
buildRequestPlannedPiece()
Have the client ask to build our top planned piece buildingPlan .pop() ,
unless we've already been told by the server to not build it. |
protected void |
cancelWrongPiecePlacement(SOCCancelBuildRequest mes)
We've asked for an illegal piece placement. |
protected void |
cancelWrongPiecePlacementLocal(SOCPlayingPiece cancelPiece)
Remove our incorrect piece placement, it's been rejected by the server. |
protected boolean |
chooseFreeResources(SOCResourceSet targetResources,
int numChoose,
boolean clearResChoices)
Choose the resources we need most, for playing a Discovery development card or when a Gold Hex number is rolled. |
private boolean |
chooseFreeResourcesIfNeeded(SOCResourceSet targetResources,
int numChoose,
boolean chooseIfNotNeeded)
Do we need to acquire at least numChoose resources to build our next piece? Choose the resources we need most; used when we want to play a discovery development card or when a Gold Hex number is rolled. |
protected int |
considerOffer(SOCTradeOffer offer)
Consider a trade offer made by another player. |
private void |
considerPlayKnightCard()
If we haven't played a dev card yet this turn, and we have a knight, and we can get largest army, play the knight. |
private boolean |
considerScenarioTurnFinalActions()
Look for and take any scenario-specific final actions before ending the turn. |
private void |
debugInfo()
this is for debugging |
java.util.List<java.lang.String> |
debugPrintBrainStatus()
Print brain variables and status for this game to a list of String s. |
private static void |
debugPrintTurnMessages(java.util.Vector<?> msgV,
java.lang.String msgDesc,
java.util.List<java.lang.String> toList)
Add the contents of this Vector as Strings to the provided list. |
protected void |
expandTradeTreeNode(SOCTradeTree currentTreeNode,
java.util.Hashtable<SOCResourceSet,SOCTradeTree> table)
expand a trade tree node |
java.util.Stack<SOCPossiblePiece> |
getBuildingPlan()
|
SOCRobotClient |
getClient()
|
SOCRobotDM |
getDecisionMaker()
|
DebugRecorder |
getDRecorder()
|
SOCGame |
getGame()
|
SOCPossiblePiece |
getLastMove()
|
SOCPossiblePiece |
getLastTarget()
|
DebugRecorder |
getOldDRecorder()
|
SOCPlayer |
getOurPlayerData()
|
SOCPlayerTracker |
getOurPlayerTracker()
|
java.util.HashMap<java.lang.Integer,SOCPlayerTracker> |
getPlayerTrackers()
|
SOCRobotParameters |
getRobotParameters()
|
private void |
handleCANCELBUILDREQUEST(SOCCancelBuildRequest mes)
Handle a CANCELBUILDREQUEST for this game. |
private void |
handleDEVCARDACTION(SOCDevCardAction mes)
Handle a DEVCARDACTION for this game. |
private void |
handleMAKEOFFER(SOCMakeOffer mes)
Handle a MAKEOFFER for this game. |
protected void |
handlePLAYERELEMENT_numRsrc(SOCPlayerElement mes,
SOCPlayer pl,
int rtype,
java.lang.String rtypeStr)
Update a player's amount of a resource. |
private void |
handlePLAYERELEMENT(SOCPlayerElement mes)
Handle a PLAYERELEMENT for this game. |
private void |
handlePUTPIECE_updateGameData(SOCPutPiece mes)
Handle a PUTPIECE for this game, by updating game data. |
private void |
handlePUTPIECE_updateTrackers(int pn,
int coord,
int pieceType)
Handle a PUTPIECE for this game, by updating SOCPlayerTracker s. |
private void |
handleREJECTOFFER(SOCRejectOffer mes)
Handle a REJECTOFFER for this game. |
void |
kill()
kill this brain |
protected boolean |
makeCounterOffer(SOCTradeOffer offer)
make a counter offer to another player |
protected boolean |
makeOffer(SOCPossiblePiece target)
Make a trade offer to another player, or decide to make no offer. |
protected void |
moveRobber()
move the robber |
void |
pause(int msec)
pause for a bit. |
protected void |
pickFreeResources(int numChoose)
Respond to server's request to pick resources to gain from the Gold Hex. |
protected void |
placeFirstSettlement(int firstSettlement)
place planned first settlement |
private void |
placeIfExpectPlacing()
If it's our turn and we have an expect flag set (such as expectPLACING_SETTLEMENT ), then
call client.putPiece
(game , whatWeWantToBuild ). |
protected void |
placeInitSettlement(int initSettlement)
Place planned initial settlement after first one. |
protected void |
planAndPlaceInitRoad()
Plan and place a road attached to our most recently placed initial settlement, in game states START1B , START2B , START3B . |
private void |
planBuilding()
Plan the next building plan and target. |
private void |
playKnightCard()
Play a Knight card. |
private void |
printResources()
For each player in game: client.sendText, and debug-print to console, game.getPlayer(i).getResources() |
private void |
resetFieldsAtEndTurn()
Bot is ending its turn; reset state control fields to act during other players' turns. |
private void |
rollOrPlayKnightOrExpectDice()
On our turn, ask client to roll dice or play a knight; on other turns, update flags to expect dice result. |
void |
run()
Here is the run method. |
protected int |
scoreTradeOutcome(SOCResourceSet tradeOutcome)
evaluate a trade outcome by calculating how much you could build with it |
void |
setOurPlayerData()
When we join a game and sit down to begin play, find our player data using our nickname. |
private void |
trackNewCity(SOCCity newCity,
boolean isCancel)
Run a newly placed city through the PlayerTrackers. |
protected void |
trackNewRoadOrShip(SOCRoad newRoad,
boolean isCancel)
Run a newly placed road or ship through the playerTrackers. |
protected void |
trackNewSettlement(SOCSettlement newSettlement,
boolean isCancel)
Run a newly placed settlement through the playerTrackers. |
private void |
tradeStopWaitingClearOffer()
Stop waiting for responses to a trade offer. |
protected void |
tradeStuff()
do some trading -- this method is obsolete and not called. |
protected boolean |
tradeToTarget2(SOCResourceSet targetResources)
Make bank trades or port trades to get the target resources, if possible. |
void |
turnOffDRecorder()
turns the debug recorders off |
void |
turnOnDRecorder()
turns the debug recorders on |
Methods inherited from class java.lang.Thread |
---|
activeCount, checkAccess, clone, countStackFrames, currentThread, destroy, dumpStack, enumerate, getAllStackTraces, getContextClassLoader, getDefaultUncaughtExceptionHandler, getId, getName, getPriority, getStackTrace, getState, getThreadGroup, getUncaughtExceptionHandler, holdsLock, interrupt, interrupted, isAlive, isDaemon, isInterrupted, join, join, join, resume, setContextClassLoader, setDaemon, setDefaultUncaughtExceptionHandler, setName, setPriority, setUncaughtExceptionHandler, sleep, sleep, start, stop, stop, suspend, toString, yield |
Methods inherited from class java.lang.Object |
---|
equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait |
Field Detail |
---|
SOCRobotParameters robotParameters
protected boolean alive
protected boolean ourTurn
protected int turnTime
private boolean pauseFaster
Pause
for less time;
speeds up response in 6-player games.
Ignored if SOCGame.isBotsOnly
, which pauses for even less time.
protected int curState
protected java.util.Random rand
protected SOCRobotClient client
protected SOCGame game
private final boolean gameIs6Player
game
we're playing is on the 6-player board.
protected SOCPlayer ourPlayerData
setOurPlayerData()
private int ourPlayerNumber
setOurPlayerData()
.
protected SOCPlayer dummyCancelPlayerData
protected CappedQueue<SOCMessage> gameEventQ
SOCMessage
.
private java.util.Vector<SOCMessage> turnEventsCurrent
private java.util.Vector<SOCMessage> turnEventsPrev
private int turnExceptionCount
TURN
message.
protected int counter
SOCTimingPing
.
When we decide to take an action, resets to 0.
If counter gets too high, we assume a bug and leave the game (alive
= false).
private boolean decidedIfSpecialBuild
private boolean waitingForSpecialBuild
protected SOCPlayingPiece whatWeWantToBuild
buildOrGetResourceByTradeOrCard()
from buildingPlan
,
used in placeIfExpectPlacing()
.
whatWeFailedToBuild
protected java.util.Stack<SOCPossiblePiece> buildingPlan
SOCPossiblePiece
.
Cleared at the start of each player's turn, and a few other places
if certain conditions arise. Set in planBuilding()
.
When making a buildingPlan
, be sure to also set
negotiator
's target piece.
SOCRobotDM.buildingPlan
is the same Stack.
whatWeWantToBuild
protected SOCPlayingPiece whatWeFailedToBuild
whatWeWantToBuild
,
failedBuildingAttempts
protected int failedBuildingAttempts
whatWeFailedToBuild
,
MAX_DENIED_BUILDING_PER_TURN
public static int MAX_DENIED_BUILDING_PER_TURN
failedBuildingAttempts
protected SOCResourceSet resourceChoices
protected SOCPlayerTracker ourPlayerTracker
protected java.util.HashMap<java.lang.Integer,SOCPlayerTracker> playerTrackers
protected SOCRobotDM decisionMaker
protected SOCRobotNegotiator negotiator
SOCRobotNegotiator.setTargetPiece(int, SOCPossiblePiece)
is set when buildingPlan
is updated.
tradeToTarget2(SOCResourceSet)
,
makeOffer(SOCPossiblePiece)
,
considerOffer(SOCTradeOffer)
,
tradeStopWaitingClearOffer()
protected boolean expectSTART1A
protected boolean expectSTART1B
protected boolean expectSTART2A
protected boolean expectSTART2B
protected boolean expectSTART3A
START3A
state.
protected boolean expectSTART3B
START3B
state.
protected boolean expectPLAY
protected boolean expectPLAY1
protected boolean expectPLACING_ROAD
protected boolean expectPLACING_SETTLEMENT
protected boolean expectPLACING_CITY
protected boolean expectPLACING_SHIP
protected boolean expectPLACING_ROBBER
playKnightCard()
sets this field and waitingForGameState
.
In scenario SC_PIRI
, this flag is also used when we've just played
a "Convert to Warship" card (Knight/Soldier card) and we're waiting for the
server response. The response won't be a GAMESTATE(PLACING_SOLDIER) message,
it will either be PLAYERLEMENT(GAIN, SCENARIO_WARSHIP_COUNT) or DEVCARDACTION(CANNOT_PLAY).
Since this situation is otherwise the same as playing a Knight/Soldier, we use
this same waiting flags.
protected boolean expectPLACING_FREE_ROAD1
protected boolean expectPLACING_FREE_ROAD2
protected boolean expectPUTPIECE_FROM_START1A
protected boolean expectPUTPIECE_FROM_START1B
protected boolean expectPUTPIECE_FROM_START2A
protected boolean expectPUTPIECE_FROM_START2B
protected boolean expectPUTPIECE_FROM_START3A
START3A
game state.
protected boolean expectPUTPIECE_FROM_START3B
START3B
game state.
protected boolean expectDICERESULT
protected boolean expectDISCARD
protected boolean expectMOVEROBBER
protected boolean expectWAITING_FOR_DISCOVERY
protected boolean expectWAITING_FOR_MONOPOLY
protected boolean waitingForGameState
waitingForOurTurn
== true).
For example, when playing a SOCDevCardAction
, set true and also set
an "expect" flag (expectPLACING_ROBBER
, expectWAITING_FOR_DISCOVERY
, etc).
Special case:
In scenario SC_PIRI
, this flag is also set when we've just played
a "Convert to Warship" card (Knight/Soldier card), although the server won't
respond with a GAMESTATE message; see expectPLACING_ROBBER
javadoc.
rejectedPlayDevCardType
protected boolean waitingForOurTurn
TURN
message from the server
when it's our turn
protected boolean waitingForTradeMsg
protected boolean waitingForDevCard
protected boolean moveRobberOnSeven
SOCMessage.DICERESULT
received.
Read in gamestate PLACING_ROBBER
.
protected boolean waitingForTradeResponse
protected java.lang.String waitingForPickSpecialItem
null
if we're waiting for server response to picking
a SOCSpecialItem
, for certain scenarios; contains the typeKey
of the special item we're waiting on.
protected boolean waitingForSC_PIRI_FortressRequest
_SC_PIRI
game
and waiting for server response to a SOCSimpleRequest
to attack a pirate fortress.
protected boolean doneTrading
protected boolean[] offerRejections
private int rejectedPlayDevCardType
SOCDevCardConstants.KNIGHT
) because of a bug in our
robot; should not attempt to play the same type again this turn.
Otherwise -1.
protected int oldGameState
private int lastStartingPieceCoord
cancelWrongPiecePlacement(SOCCancelBuildRequest)
.
private int lastStartingRoadTowardsNode
OpeningBuildStrategy.planInitRoad()
.
Used to avoid repeats in cancelWrongPiecePlacementLocal(SOCPlayingPiece)
.
private OpeningBuildStrategy openingBuildStrategy
setOurPlayerData()
.
private MonopolyStrategy monopolyStrategy
setOurPlayerData()
.
protected SOCRobotPinger pinger
protected DebugRecorder[] dRecorder
protected int currentDRecorder
protected SOCPossiblePiece lastMove
protected SOCPossiblePiece lastTarget
Constructor Detail |
---|
public SOCRobotBrain(SOCRobotClient rc, SOCRobotParameters params, SOCGame ga, CappedQueue<SOCMessage> mq)
Depending on game options
,
constructor might copy and alter the robot parameters
(for example, to clear SOCRobotParameters.getTradeFlag()
).
Please call setOurPlayerData()
before using this brain or starting its thread.
rc
- the robot clientparams
- the robot parametersga
- the game we're playingmq
- the message queueMethod Detail |
---|
public SOCRobotParameters getRobotParameters()
public SOCRobotClient getClient()
public java.util.HashMap<java.lang.Integer,SOCPlayerTracker> getPlayerTrackers()
public SOCPlayerTracker getOurPlayerTracker()
public void addPlayerTracker(int pn)
Called when SITDOWN received from server; one SITDOWN is sent for every player, and our robot player might not be the first or last SITDOWN.
Since our playerTrackers are initialized when our robot's
SITDOWN is received (robotclient calls setOurPlayerData()
),
and seats may be vacant at that time (because SITDOWN not yet
received for those seats), we must add a PlayerTracker for
each SITDOWN received after our player's.
pn
- Player numberpublic SOCGame getGame()
public SOCPlayer getOurPlayerData()
public java.util.Stack<SOCPossiblePiece> getBuildingPlan()
SOCPossiblePiece
public SOCRobotDM getDecisionMaker()
public void turnOnDRecorder()
public void turnOffDRecorder()
public DebugRecorder getDRecorder()
public DebugRecorder getOldDRecorder()
public SOCPossiblePiece getLastMove()
public SOCPossiblePiece getLastTarget()
public void setOurPlayerData()
SOCRobotClient
when the
server sends a SOCSitDown
message.
Initializes our game and player data,
SOCRobotDM
, SOCRobotNegotiator
,
strategy fields, SOCPlayerTracker
s, etc.
public java.util.List<java.lang.String> debugPrintBrainStatus()
String
s.
Includes all of the expect and waitingFor fields (expectPLAY,
waitingForGameState, etc.)
Also prints the game state, and the messages received by this brain
during the previous and current turns.
Before v1.1.20, this printed to System.err
instead of returning the status as Strings.
private static void debugPrintTurnMessages(java.util.Vector<?> msgV, java.lang.String msgDesc, java.util.List<java.lang.String> toList)
msgV
- Vector of SOCMessage
s from servermsgDesc
- Short description of the vector, like 'previous' or 'current'toList
- Add to this listpublic void run()
gameEventQ
and deal with each one.
Remember that we're sent a SOCTimingPing
event once per second,
incrementing counter
. That allows the bot to wait a certain
time for other players before it decides whether to do something.
Nearly all bot actions start in this method; the overview of bot structures
is in the class javadoc
for prominence.
See comments within run() for minor details.
run
in interface java.lang.Runnable
run
in class java.lang.Thread
private final void resetFieldsAtEndTurn()
waitingForGameState
= true
expectPLAY
= true
waitingForOurTurn
= true
doneTrading
= false only if robotParameters
allow trade
counter
= 0
buildingPlan
negotiator.resetIsSelling()
,
.resetOffersMade()
,
.resetTargetPieces()
Does not call SOCDisplaylessPlayerClient.endTurn(SOCGame)
.
private boolean considerScenarioTurnFinalActions()
For example, _SC_PIRI
will check if we've reached the fortress
and have 5 or more warships, and if so will attack the fortress. Doing so ends the turn, so
we don't try to attack before end of turn.
NOTE: For now this method assumes it's called only in the SC_PIRI
scenario.
Caller must check the game for any relevant scenario SOCGameOptions before calling.
private void tradeStopWaitingClearOffer()
client.clearOffer
,
clear waitingForTradeResponse
and counter
.
private void considerPlayKnightCard()
PLAY1
.
ourPlayerData.hasPlayedDevCard()
must be false.
In scenario _SC_PIRI
(which has no robber and no largest army), play one
whenever we have it, someone else has resources, and we can convert a ship to a warship.
If we call playKnightCard()
, it sets the flags
expectPLACING_ROBBER
and waitingForGameState
.
rollOrPlayKnightOrExpectDice()
private void placeIfExpectPlacing()
expectPLACING_SETTLEMENT
), then
call client.putPiece
(game
, whatWeWantToBuild
).
Looks for one of these game states:
SOCGame.START1A
- SOCGame.START3B
SOCGame.PLACING_SETTLEMENT
SOCGame.PLACING_ROAD
SOCGame.PLACING_CITY
SOCGame.PLACING_SHIP
SOCGame.PLACING_FREE_ROAD1
SOCGame.PLACING_FREE_ROAD2
private void playKnightCard()
_SC_PIRI
, play a "Convert to Warship" card.
Sets expectPLACING_ROBBER
, waitingForGameState
.
Calls client.playDevCard
(KNIGHT
).
In scenario _SC_PIRI
, the server response messages are different, but we
still use those two flag fields; see expectPLACING_ROBBER
javadoc.
private void rollOrPlayKnightOrExpectDice()
Call when gameState SOCGame.PLAY
&& ! waitingForGameState
.
Clears expectPLAY
to false.
Sets either expectDICERESULT
, or expectPLACING_ROBBER
and waitingForGameState
.
In scenario _SC_PIRI
, don't play a Knight card before dice roll, because the scenario has
no robber: Playing before the roll won't un-block any of our resource hexes, and it might put us
over 7 resources.
considerPlayKnightCard()
private void buildOrGetResourceByTradeOrCard() throws java.lang.IllegalStateException
buildingPlan
for the next piece wanted.
Sets whatWeWantToBuild
by calling buildRequestPlannedPiece()
or using a Road Building dev card.
If we need resources and we can't get them through the robber,
the Road Building
or
Monopoly
or
Discovery
development cards,
then trades with the bank (tradeToTarget2(SOCResourceSet)
)
or with other players (makeOffer(SOCPossiblePiece)
).
Call when these conditions are all true:
ourTurn
planBuilding()
already called
buildingPlan
.empty()
SOCGame.PLAY1
or SOCGame.SPECIAL_BUILDING
waitingForGameState
, etc)
except possibly waitingForSpecialBuild
expectPLACING_ROAD
, etc)
waitingForOurTurn
expectPLAY
&& (counter < 4000))
May set any of these flags:
waitingForGameState
, and expectWAITING_FOR_DISCOVERY
or expectWAITING_FOR_MONOPOLY
waitingForTradeMsg
or waitingForTradeResponse
or doneTrading
waitingForDevCard
, or waitingForGameState
and expectPLACING_SETTLEMENT
(etc).
waitingForPickSpecialItem
waitingForSC_PIRI_FortressRequest
In a future iteration of the run() loop with the expected PLACING_
state, the
bot will build whatWeWantToBuild
by calling placeIfExpectPlacing()
.
java.lang.IllegalStateException
- if buildingPlan
.isEmpty()
private void handlePUTPIECE_updateGameData(SOCPutPiece mes)
handlePUTPIECE_updateTrackers(int, int, int)
.
private void handleCANCELBUILDREQUEST(SOCCancelBuildRequest mes)
During game startup (START1B or START2B):
When sent from server to client, CANCELBUILDREQUEST means the current
player wants to undo the placement of their initial settlement.
During piece placement (PLACING_ROAD, PLACING_CITY, PLACING_SETTLEMENT,
PLACING_FREE_ROAD1, or PLACING_FREE_ROAD2):
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.
private void handleMAKEOFFER(SOCMakeOffer mes)
considerOffer(SOCTradeOffer)
, and if
we accept, clear our buildingPlan
so we'll replan it.
Ignore our own MAKEOFFERs echoed from server.
private void handleREJECTOFFER(SOCRejectOffer mes)
private void handleDEVCARDACTION(SOCDevCardAction mes)
private void handlePUTPIECE_updateTrackers(int pn, int coord, int pieceType)
SOCPlayerTracker
s.
Also handles the "move piece to here" part of MOVEPIECE.
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 expectPLAY.
For initial settlements, won't track here:
Delay tracking until the corresponding road is placed,
in handlePUTPIECE_updateGameData(SOCPutPiece)
.
This prevents the need for tracker "undo" work if a human
player changes their mind on where to place the settlement.
pn
- Piece's player numbercoord
- Piece coordinatepieceType
- Piece type, as in SOCPlayingPiece.SETTLEMENT
private void buildRequestPlannedPiece()
buildingPlan
.pop()
,
unless we've already been told by the server to not build it.
Sets whatWeWantToBuild
, waitingForDevCard
,
or waitingForPickSpecialItem
.
Called from buildOrGetResourceByTradeOrCard()
.
Checks against whatWeFailedToBuild
to see if server has rejected this already.
Calls client.buyDevCard() or client.buildRequest().
Sets waitingForDevCard
or waitingForPickSpecialItem
,
or sets waitingForGameState
and expectPLACING_SETTLEMENT
(etc).
private final void planBuilding()
run()
under these conditions: Sets these fields and makes these calls:
SOCRobotDM.planStuff
(FAST_STRATEGY
or SMART_STRATEGY
)
buildingPlan
lastTarget
SOCRobotNegotiator.setTargetPiece(int, SOCPossiblePiece)
private void handlePLAYERELEMENT(SOCPlayerElement mes)
If this during the SOCGame.PLAY
state, then update the
SOCRobotNegotiator
's is-selling flags.
If our player is losing a resource needed for the buildingPlan
,
clear the plan if this is for the Special Building Phase (on the 6-player board).
In normal game play, we clear the building plan at the start of each turn.
Otherwise, only the game data is updated, nothing brain-specific.
protected void handlePLAYERELEMENT_numRsrc(SOCPlayerElement mes, SOCPlayer pl, int rtype, java.lang.String rtypeStr)
SOCPlayerElement.LOSE
action, and the player does not have enough of that type,
the rest are taken from the player's UNKNOWN amount.
ourPlayerData
, and debug print
if they don't match already.
If our player is losing a resource needed for the buildingPlan
,
clear the plan if this is for the Special Building Phase (on the 6-player board).
In normal game play, we clear the building plan at the start of each turn.
mes
- Message with amount and action (SET/GAIN/LOSE)pl
- Player to updatertype
- Type of resource, like SOCResourceConstants.CLAY
rtypeStr
- Resource type name, for debuggingprotected void trackNewSettlement(SOCSettlement newSettlement, boolean isCancel)
SOCGame.putPiece(SOCPlayingPiece)
or SOCGame.putTempPiece(SOCPlayingPiece)
.
During initial board setup, settlements aren't tracked when placed. They are deferred until their corresponding road placement, in case a human player decides to cancel their settlement and place it elsewhere. During normal play, the settlements are tracked immediately when placed. (Code previously in body of the run method.) Placing the code in its own method allows tracking that settlement when the road's putPiece message arrives.
newSettlement
- The newly placed settlement for the playerTrackersisCancel
- Is this our own robot's settlement placement, rejected by the server?
If so, this method call will cancel its placement within the game data / robot data.private void trackNewCity(SOCCity newCity, boolean isCancel)
newCity
- The newly placed cityisCancel
- Is this our own robot's city placement, rejected by the server?
If so, this method call will cancel its placement within the game data / robot data.protected void trackNewRoadOrShip(SOCRoad newRoad, boolean isCancel)
newRoad
- The newly placed road or shipisCancel
- Is this our own robot's placement, rejected by the server?
If so, this method call will cancel its placement within the game data / robot data.protected void cancelWrongPiecePlacement(SOCCancelBuildRequest mes)
SOCGame.isSpecialBuilding()
, will set variables to
force the end of our special building turn.
Also handles illegal requests to buy development cards
(piece type -2 in SOCCancelBuildRequest
).
This method increments failedBuildingAttempts
,
but won't leave the game if we've failed too many times.
The brain's run loop should make that decision.
mes
- Cancel message from server, including piece typeprotected void cancelWrongPiecePlacementLocal(SOCPlayingPiece cancelPiece)
This method invalidates that piece in trackers, so we don't try again to build it. Since we treat it like another player's new placement, we can remove any of our planned pieces depending on this one.
Also calls SOCPlayer.clearPotentialSettlement(int)
,
clearPotentialRoad, or clearPotentialCity.
cancelPiece
- Type and coordinates of the piece to cancel; null is allowed but not very useful.public void kill()
public void pause(int msec)
When SOCGame.isBotsOnly
, pause only 25% as long, to quicken the simulation
but not make it too fast to allow a person to observe.
In a 6-player game, pause only 75% as long, to shorten the overall game delay,
except if waitingForTradeResponse
.
This is indicated by the pauseFaster
flag.
msec
- number of milliseconds to pauseprotected void placeFirstSettlement(int firstSettlement)
firstSettlement
- First settlement's node coordinateplaceInitSettlement(int)
protected void placeInitSettlement(int initSettlement)
initSettlement
- Second or third settlement's node coordinate,
from OpeningBuildStrategy.planSecondSettlement()
or
from OpeningBuildStrategy#planThirdSettlement()
;
should not be -1placeFirstSettlement(int)
protected void planAndPlaceInitRoad()
START1B
, START2B
, START3B
.
Calls OpeningBuildStrategy.planInitRoad()
.
Road choice is based on the best nearby potential settlements, and doesn't
directly check ourPlayerData.isPotentialRoad(edgeCoord)
.
If the server rejects our road choice, then cancelWrongPiecePlacementLocal(SOCPlayingPiece)
will need to know which settlement node we were aiming for,
and call ourPlayerData.clearPotentialSettlement(nodeCoord)
.
The lastStartingRoadTowardsNode
field holds this coordinate.
protected void moveRobber()
protected void pickFreeResources(int numChoose)
buildingPlan
or, if that's empty (initial placement),
pick what's rare from OpeningBuildStrategy.estimateResourceRarity()
.
numChoose
- Number of resources to pickprotected void tradeStuff()
makeOffer(SOCPossiblePiece)
, considerOffer(SOCTradeOffer)
,
etc, and the javadoc for negotiator
.
protected void expandTradeTreeNode(SOCTradeTree currentTreeNode, java.util.Hashtable<SOCResourceSet,SOCTradeTree> table)
currentTreeNode
- the tree node that we're expandingtable
- the table of all of the nodes in the tree except this oneprotected int scoreTradeOutcome(SOCResourceSet tradeOutcome)
tradeOutcome
- a set of resources that would be the result of tradingprotected boolean tradeToTarget2(SOCResourceSet targetResources)
targetResources
- the resources that we want, can be null
for an empty set (method returns false)
protected int considerOffer(SOCTradeOffer offer)
offer
- the offer to consider
makeCounterOffer(SOCTradeOffer)
protected boolean makeOffer(SOCPossiblePiece target)
SOCRobotNegotiator.makeOffer(SOCPossiblePiece)
.
Will set either waitingForTradeResponse
or doneTrading
,
and update ourPlayerData
.setCurrentOffer()
,
target
- the resources that we want
protected boolean makeCounterOffer(SOCTradeOffer offer)
offer
- their offer
protected boolean chooseFreeResources(SOCResourceSet targetResources, int numChoose, boolean clearResChoices)
resourceChoices
.
Looks at our player's current resources.
targetResources
- Resources needed to build our next planned piece,
from SOCPossiblePiece.getResourcesToBuild()
for buildingPlan
.peek()numChoose
- Number of resources to chooseclearResChoices
- If true, clear resourceChoices
before choosing what to add to it;
set false if calling several times to iteratively build up a big choice.
resourceChoices
.getTotal()
to see how many were chosen.private boolean chooseFreeResourcesIfNeeded(SOCResourceSet targetResources, int numChoose, boolean chooseIfNotNeeded)
chooseFreeResources(SOCResourceSet, int, boolean)
and has set resourceChoices
.
targetResources
- Resources needed to build our next planned piece,
from SOCPossiblePiece.getResourcesToBuild()
for buildingPlan
.
If null
, returns false (no more resources required).numChoose
- Number of resources to choosechooseIfNotNeeded
- Even if we find we don't need them, choose anyway;
set true for Gold Hex choice, false for Discovery card pick.
private void debugInfo()
private void printResources()
|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |