|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object soc.game.SOCGame
public class SOCGame
A class for holding and manipulating game data.
Most methods are not implicitly thread-safe;
call takeMonitor()
and releaseMonitor()
around them.
The model in this client/server game is: The SOCGame at server contains the game's
complete state information, and game logic advances there.
Each client's local SOCGame contains only partial state (for instance, other
players' resources or devel cards may be of unknown type); and the server directly
updates clients' game state by sending messages such as
SOCGameState
and SOCSetPlayedDevCard
.
Within this package, you can check isAtServer
.
Many methods assume you've already checked whether the move is valid,
and won't check it a second time. For example, canPlayKnight(int)
should be called to check before calling playKnight()
.
For the board coordinate system and terms (hex, node, edge), see the
SOCBoard
class javadoc.
Games are created at the server in SOCGameListAtServer
and given an
expiration time 90 minutes away
(SOCGameListAtServer.GAME_TIME_EXPIRE_MINUTES
).
Players then choose their seats, optionally locking empty seats against joining robots,
and any player can click the Start Game button.
Game play begins with the server calling startGame()
, then sending messages to clients
with the starting game state and player data and a board layout.
After initial placement, normal play begins with the first player's turn, in state PLAY
;
updateAtGameFirstTurn()
is called for any work needed.
During game play, putPiece(SOCPlayingPiece)
and other game-action methods update gameState
.
updateAtTurn()
, putPiece and some other game-action methods update lastActionTime
.
The game's current plays and actions are tracked through game states, such as
5 or WAITING_FOR_DISCARDS
. A normal turn starts at PLAY
;
after dice are rolled, the turn will spend most of its time in PLAY1
. If you need to
add a state, please see the instructions at NEW
.
The winner is the player who has vp_winner
or more victory points (typically 10)
on their own turn. Some optional game scenarios have special win conditions, see checkForWinner()
.
The large sea board
features scenario events.
To listen for these, call setScenarioEventListener(SOCScenarioEventListener)
.
If the game has a scenario, its SOCGameOption
s will include "SC"
, possibly along with
other options whose key names start with "_SC_"
.
Nested Class Summary | |
---|---|
static class |
SOCGame.RollResult
Dice roll result, for reporting from rollDice() . |
static class |
SOCGame.SeatLockState
Seat lock states for lock/unlock. |
Field Summary | |
---|---|
private boolean |
active
true if this game is ACTIVE |
(package private) boolean |
allOriginalPlayers
used to track if there were any player subs |
private boolean |
askedSpecialBuildPhase
If true, it's a 6-player board and at least one player has requested to build during the Special Building Phase that occurs between turns. |
private SOCBoard |
board
the game board |
static SOCBoard.BoardFactory |
boardFactory
The SOCBoard.BoardFactory for creating new boards in the SOCGame constructors. |
SOCGameBoardReset |
boardResetOngoingInfo
For the server's use, if a reset is in progress, this holds the reset data until all robots have left (new game state is READY_RESET_WAIT_ROBOT_DISMISS ). |
private int |
boardResetVoteRequester
If a board reset vote is active, player number who requested the vote. |
private int[] |
boardResetVotes
If a board reset vote is active, votes are recorded here. |
private int |
boardResetVotesWaiting
If a board reset vote is active, we're waiting to receive this many more votes. |
static SOCResourceSet |
CARD_SET
the set of resources a player needs to buy a development card |
static SOCResourceSet |
CITY_SET
the set of resources a player needs to build a city |
int |
clientVersionHighest
For use at server; lowest and highest version of connected clients. |
int |
clientVersionLowest
For use at server; lowest and highest version of connected clients. |
private int |
clientVersionMinRequired
For use at server; lowest version of client which can connect to this game (based on game options/features added in a given version), or -1 if unknown. |
private int |
currentDice
the current dice result. |
private int |
currentPlayerNumber
the number of the current player |
private SOCGame.RollResult |
currentRoll
The current dice result, including any scenario items such as SOCVillage.distributeCloth(SOCGame) results. |
private boolean |
debugFreePlacement
Are we in the 'free placement' debug mode? See SOCGameHandler.processDebugCommand_freePlace, SOCPlayerInterface.setDebugPaintPieceMode. |
private boolean |
debugFreePlacementStartPlaced
Have we placed pieces in debugFreePlacement
during initial placement? Set in putPiece(SOCPlayingPiece) . |
private int[] |
devCardDeck
the development card deck. |
private static int[] |
EMPTY_INT_ARRAY
An empty int array for use in method calls. |
static SOCResourceSet |
EMPTY_RESOURCES
an empty set of resources. |
(package private) long |
expiration
Expiration time for this game in milliseconds (system clock time, not a duration from startTime );
Same format as System.currentTimeMillis() . |
private int |
firstPlayerNumber
the first player to place a settlement |
private boolean |
forcingEndTurn
If true, this turn is being ended. |
private int |
gameState
the current game state |
private boolean |
hasBuiltCity
True once any player has built a city. |
boolean |
hasMultiLocales
For use at server for i18n; does this game have any members (players or observers) with a locale different than getOwnerLocale() ?
Initially false, set true in SOCGameListAtServer.addMember if needed. |
boolean |
hasOldClients
For use at server; are there clients connected which aren't at the latest version? |
boolean |
hasScenarioWinCondition
Does this game's scenario have a special win condition besides vp_winner ?
For example, scenario _SC_CLVI will end the game if
less than half the SOCVillage s have cloth remaining. |
boolean |
hasSeaBoard
Is this game played on the SOCBoardLarge large board / sea board?
If true, our board's SOCBoard.getBoardEncodingFormat()
must be SOCBoard.BOARD_ENCODING_LARGE . |
(package private) boolean |
inUse
monitor for synchronization |
(package private) boolean |
isAtServer
Is this the server's complete copy of the game, not the client's (with some details unknown)? Set during startGame() . |
boolean |
isBotsOnly
true if the game's only players are bots, no humans. |
private boolean |
isFromBoardReset
true if the game came from a board reset |
boolean |
isPractice
true if the game's network is local for practice. |
long |
lastActionTime
The last time a game action happened; can be used to check for game inactivity. |
private boolean |
lastActionWasBankTrade
Used at server; was the most recent player action a bank trade? If true, allow the player to undo that trade. |
private int |
lastPlayerNumber
the last player to place the first settlement |
int |
maxPlayers
maxPlayers is 4 for the standard game, or 6 if this game is on the 6-player board, with corresponding rules. |
static int |
MAXPLAYERS
Maximum number of players in a game, in this version. |
static int |
MAXPLAYERS_STANDARD
maximum number of players in a standard game |
static int |
MINPLAYERS
minimum number of players in a game (was assumed == MAXPLAYERS in standard 1.0.6). |
private boolean |
movedShipThisTurn
Has the current player moved a ship already this turn? Valid only when hasSeaBoard . |
private java.lang.String |
name
the name of the game |
static int |
NEW
Game states. |
private static int |
NUM_DEVCARDS_6PLAYER
Number of development cards (34) in the 6-player rules. |
private static int |
NUM_DEVCARDS_STANDARD
Number of development cards (25) in the standard rules. |
private static int |
NUM_DEVCARDS_VP
Number of development cards (5) which are Victory Point cards. |
private int |
numDevCards
the number of development cards left in devCardDeck for buyDevCard() . |
static int |
OCCUPIED
seat states |
private int |
oldGameState
The saved game state; used in only a few places, where a state can happen from different start states. |
private int |
oldPlayerWithLargestArmy
To remember last playerWithLargestArmy during
saveLargestArmyState() / restoreLargestArmyState() . |
(package private) java.util.Stack<SOCOldLRStats> |
oldPlayerWithLongestRoad
used to restore the LR player |
private java.util.Map<java.lang.String,SOCGameOption> |
opts
the game options ( SOCGameOption ), or null |
static int |
OVER
The game is over. |
private java.lang.String |
ownerLocale
Locale of the client connection that created this game. |
private java.lang.String |
ownerName
For games at the server, the owner (creator) of the game. |
java.util.List<java.lang.Object> |
pendingMessagesOut
For games at server, a convenient place to hold outbound messages during game actions. |
private java.util.Vector<java.lang.Integer> |
placedShipsThisTurn
List of ship edge coordinates placed this turn. |
static int |
PLACING_CITY
|
static int |
PLACING_FREE_ROAD1
Player is placing first free road/ship |
static int |
PLACING_FREE_ROAD2
Player is placing second free road/ship |
static int |
PLACING_INV_ITEM
Player is placing the special SOCInventoryItem held in getPlacingItem() . |
static int |
PLACING_PIRATE
Player is placing the pirate ship on a new water hex, in a game which hasSeaBoard . |
static int |
PLACING_ROAD
|
static int |
PLACING_ROBBER
Player is placing the robber on a new land hex. |
static int |
PLACING_SETTLEMENT
|
static int |
PLACING_SHIP
This game hasSeaBoard , and a player has bought and is placing a ship. |
private SOCInventoryItem |
placingItem
The special inventory item currently being placed in state PLACING_INV_ITEM , or null. |
private boolean |
placingRobberForKnightCard
If true, and if state is PLACING_ROBBER ,
the robber is being moved because a knight card
has just been played. |
static int |
PLAY
Start of a normal turn. |
static int |
PLAY1
Done rolling (or moving robber on 7). |
private SOCPlayer[] |
players
the players; never contains a null element, use isSeatVacant(int)
to see if a position is occupied. |
private int |
playerWithLargestArmy
the player with the largest army, or -1 if none |
private int |
playerWithLongestRoad
the player with the longest road or trade route, or -1 if none |
private int |
playerWithWin
the player declared winner, if gamestate == OVER; otherwise -1 |
private java.util.Random |
rand
used to generate random numbers |
static int |
READY
Ready to start playing. |
static int |
READY_RESET_WAIT_ROBOT_DISMISS
This game object has just been created by a reset, but the old game contains robot players, so we must wait for them to leave before re-inviting anyone to continue the reset process. |
static int |
RESET_OLD
This game is an obsolete old copy of a new (reset) game with the same name. |
static SOCResourceSet |
ROAD_SET
the set of resources a player needs to build a road |
private SOCMoveRobberResult |
robberResult
The most recent moveRobber(int, int) or movePirate(int, int) result. |
private boolean |
robberyWithPirateNotRobber
Is the current robbery using the pirate ship, not the robber? If true, victims will be based on adjacent ships, not settlements/cities. |
private int |
roundCount
The number of normal rounds (each player has 1 turn per round, after initial placements), including this round. |
(package private) SOCScenarioEventListener |
scenarioEventListener
Listener for scenario events on the large sea board , or null. |
private SOCGame.SeatLockState[] |
seatLocks
the states of the locks for the player's seats |
private int[] |
seats
the states for the player's seats |
private static long |
serialVersionUID
The main game class has a serialVersionUID; pieces and players don't. |
static int |
SETOPTIONS_EXCL
|
static int |
SETOPTIONS_INCL
|
static SOCResourceSet |
SETTLEMENT_SET
the set of resources a player needs to build a settlement |
static SOCResourceSet |
SHIP_SET
the set of resources a player needs to build a ship |
static int |
SPECIAL_BUILDING
The 6-player board's Special Building Phase. |
private int |
specialBuildPhase_afterPlayerNumber
For the 6-player board's Special Building Phase, the player number whose normal turn (roll, place, etc) has just ended. |
private java.util.HashMap<java.lang.String,java.util.ArrayList<SOCSpecialItem>> |
spItems
Game's SOCSpecialItem s, if any, by type. |
static int |
START1A
Players place first settlement. |
static int |
START1B
Players place first road. |
static int |
START2A
Players place second settlement. |
static int |
START2B
Players place second road. |
static int |
START3A
(Game scenarios) Players place third settlement. |
static int |
START3B
Players place third road. |
static int |
STARTS_WAITING_FOR_PICK_GOLD_RESOURCE
Just placed an initial piece, waiting for current player to choose which Gold Hex resources to receive. |
(package private) java.util.Date |
startTime
Time when this game was created, or null if not active when created. |
private int |
turnCount
The number of normal turns (not rounds, not initial placements), including this turn. |
static int |
VACANT
seat states |
static int |
VERSION_FOR_CANCEL_FREE_ROAD2
Minimum version (1.1.17) that supports canceling the second free road or ship placement. |
static int |
VOTE_NO
|
static int |
VOTE_NONE
boardResetVotes per-player states: no vote sent; yes; no. |
static int |
VOTE_YES
|
int |
vp_winner
Number of victory points needed to win this game (default VP_WINNER_STANDARD == 10). |
static int |
VP_WINNER_STANDARD
Default number of victory points (10) needed to win. |
static int |
WAITING_FOR_DESTROY
Waiting for player to choose a settlement to destroy, or a city to downgrade (Dev card SOCDevCardConstants.DESTROY ). |
static int |
WAITING_FOR_DISCARDS
Waiting for player(s) to discard, after 7 is rolled in rollDice() . |
static int |
WAITING_FOR_DISCOVERY
Waiting for player to choose 2 resources (Discovery card) Next game state is PLAY1 . |
static int |
WAITING_FOR_MONOPOLY
Waiting for player to choose a resource (Monopoly card) Next game state is PLAY1 . |
static int |
WAITING_FOR_PICK_GOLD_RESOURCE
Waiting for player(s) to choose which Gold Hex resources to receive. |
static int |
WAITING_FOR_ROB_CHOOSE_PLAYER
Waiting for player to choose a player to rob, with the robber or pirate ship, after rolling 7 or playing a Knight/Soldier card. |
static int |
WAITING_FOR_ROB_CLOTH_OR_RESOURCE
Waiting for player to choose whether to rob cloth or rob a resource. |
static int |
WAITING_FOR_ROBBER_OR_PIRATE
Waiting for player to choose the robber or the pirate ship, after rollDice() or playKnight() . |
static int |
WAITING_FOR_SWAP
Waiting for player to choose a settlement or city to swap with another player (Dev card SOCDevCardConstants.SWAP ). |
Constructor Summary | |
---|---|
SOCGame(java.lang.String n)
create a new, active game |
|
SOCGame(java.lang.String n,
boolean isActive)
create a new game that can be ACTIVE or INACTIVE |
|
SOCGame(java.lang.String n,
boolean isActive,
java.util.Map<java.lang.String,SOCGameOption> op)
create a new game that can be ACTIVE or INACTIVE, and have options and optionally a scenario (game option "SC" ). |
|
SOCGame(java.lang.String n,
java.util.Map<java.lang.String,SOCGameOption> op)
create a new, active game with options and optionally a scenario (game option "SC" ). |
Method Summary | |
---|---|
void |
addPlayer(java.lang.String name,
int pn)
Add a new player sitting at a certain seat, or sit them again in their same seat (rejoining after a disconnect). |
protected boolean |
advanceTurn()
advance the turn to the next player. |
protected boolean |
advanceTurnBackwards()
advance the turn to the previous player, used during initial placement. |
private boolean |
advanceTurnStateAfterPutPiece()
After placing a piece on the board, update the state of the game, and possibly current player, for play to continue. |
private boolean |
advanceTurnToSpecialBuilding()
For the 6-player board, check whether we should either start or continue the Special Building Phase . |
boolean |
allOriginalPlayers()
|
void |
askSpecialBuild(int pn,
boolean onlyIfCan)
For 6-player mode's Special Building Phase, check state and set the flag for this player asking to build. |
int[] |
attackPirateFortress(SOCShip adjacent)
The current player has built ships to their pirate fortress, and attacks now to try to conquer and recapture it. |
void |
buyCity(int pn)
a player is buying a city. |
int |
buyDevCard()
the current player is buying a dev card. |
void |
buyRoad(int pn)
a player is buying a road. |
void |
buySettlement(int pn)
a player is buying a settlement. |
void |
buyShip(int pn)
a player is buying a city. |
boolean |
canAskSpecialBuild(int pn,
boolean throwExceptions)
For 6-player mode's Special Building Phase ,
can the player currently request to special build?
See 'throws' for the conditions checked. |
SOCShip |
canAttackPirateFortress()
Can the current player attack their pirate fortress, and try to conquer and recapture it? This method is validation before calling attackPirateFortress(SOCShip) . |
boolean |
canBuyOrAskSpecialBuild(int pn)
Can the player either buy and place a piece (or development card) now, or can they ask now for the Special Building Phase (in a 6-player game)? Based on game state and current player number, not on resources available. |
boolean |
canCancelBuildPiece(int buildType)
Can the current player cancel building a piece in this game state? True for each piece's normal placing state ( PLACING_ROAD , etc),
and for initial settlement placement. |
void |
cancelBuildCity(int pn)
a player is UNbuying a city; return resources, set gameState PLAY1 (or SPECIAL_BUILDING) |
boolean |
cancelBuildRoad(int pn)
a player is UNbuying a road; return resources, set gameState PLAY1 (or SPECIAL_BUILDING) |
void |
cancelBuildSettlement(int pn)
a player is UNbuying a settlement; return resources, set gameState PLAY1 (or SPECIAL_BUILDING) |
boolean |
cancelBuildShip(int pn)
a player is UNbuying a ship; return resources, set gameState PLAY1 (or SPECIAL_BUILDING) |
SOCInventoryItem |
cancelPlaceInventoryItem(boolean forceEndTurn)
In state PLACING_INV_ITEM , the current player is canceling special SOCInventoryItem placement. |
boolean |
canChooseMovePirate()
Based on game options, can the pirate ship be moved instead of the robber? True only if hasSeaBoard . |
boolean |
canChoosePlayer(int pn)
When moving the robber or pirate, can this player be chosen to be robbed? Game state must be WAITING_FOR_ROB_CHOOSE_PLAYER or WAITING_FOR_PICK_GOLD_RESOURCE . |
boolean |
canChooseRobClothOrResource(int pn)
Can this player be robbed of either cloth or resources? True only if hasSeaBoard and when robbing with the pirate
(getRobberyPirateFlag() ). |
boolean |
canDiscard(int pn,
SOCResourceSet rs)
|
boolean |
canDoDiscoveryAction(SOCResourceSet pick)
|
boolean |
canDoMonopolyAction()
|
boolean |
canEndTurn(int pn)
Can this player end the current turn? |
boolean |
canMakeBankTrade(SOCResourceSet give,
SOCResourceSet get)
|
boolean |
canMakeTrade(int offering,
int accepting)
Can these two players currently trade? If game option "NT" is set, players can trade only with the bank/ports, not with other players. |
boolean |
canMovePirate(int pn,
int hco)
Can this player currently move the pirate ship to these coordinates? Must be a water hex, per SOCBoardLarge.isHexOnWater(int) . |
boolean |
canMoveRobber(int pn,
int co)
Can this player currently move the robber to these coordinates? Must be different from current robber coordinates. |
SOCShip |
canMoveShip(int pn,
int fromEdge)
Can this player currently move this ship, based on game state and their trade routes and settlements/cities? Must be current player. |
SOCShip |
canMoveShip(int pn,
int fromEdge,
int toEdge)
Can this player currently move this ship to this new coordinate, based on game state and their trade routes and settlements/cities? Must be current player. |
boolean |
canPickGoldHexResources(int pn,
SOCResourceSet rs)
Can the player pick these resources from the gold hex? rs. getTotal()
must == SOCPlayer.getNeedToPickGoldHexResources() . |
boolean |
canPlacePort(SOCPlayer pl,
int edge)
For scenario option _SC_FTRI ,
can a "gift" port be placed at this edge? All these conditions must be met: hasSeaBoard is true
Must be a coastal edge: SOCBoardLarge.isEdgeCoastline(int)
No port already at this edge or an adjacent edge
Player must have a settlement or city at one node (one end) of the edge
Player is current player
Does not check whether SOCGameOption.K_SC_FTRI is set. |
boolean |
canPlaceShip(SOCPlayer pl,
int shipEdge)
Can this player place a ship on this edge? The edge must return SOCPlayer.isPotentialShip(int)
and must not be adjacent to SOCBoardLarge.getPirateHex() . |
boolean |
canPlayDiscovery(int pn)
return true if the player can play a Discovery card |
int |
canPlayInventoryItem(int pn,
int itype)
Can this player play this special SOCInventoryItem now? Checks the game state, scenario options, and
player's inventory. |
boolean |
canPlayKnight(int pn)
Can this player currently play a knight card? gameState must be PLAY or PLAY1 . |
boolean |
canPlayMonopoly(int pn)
return true if the player can play a Monopoly card |
boolean |
canPlayRoadBuilding(int pn)
Can the current player play a Road Building card? |
boolean |
canRemovePort(SOCPlayer pl,
int edge)
For scenario option _SC_FTRI ,
can a "gift" port be removed from this edge? All these conditions must be met: hasSeaBoard is true
Player is current player
Game state is PLACING_SHIP , PLACING_FREE_ROAD1 or PLACING_FREE_ROAD2
edge has a port
Port must be in no land area (LA == 0), or in SOCBoardLarge.getPlayerExcludedLandAreas()
Does not check whether SOCGameOption.K_SC_FTRI is set. |
boolean |
canRollDice(int pn)
|
boolean |
canUndoBankTrade(SOCResourceSet undo_gave,
SOCResourceSet undo_got)
Can we undo this bank trade? True only if the last action this turn was a bank trade with the same resources. |
private boolean |
checkForWinner_SC_CLVI()
Check if less than half the villages have cloth remaining. |
void |
checkForWinner()
check current player's vp total to see if the game is over. |
void |
chooseMovePirate(boolean pirateNotRobber)
Choose to move the pirate or the robber, from game state WAITING_FOR_ROBBER_OR_PIRATE . |
int |
choosePlayerForRobbery(int pn)
The current player has chosen a victim to rob. |
boolean |
couldBuildCity(int pn)
|
boolean |
couldBuildRoad(int pn)
|
boolean |
couldBuildSettlement(int pn)
|
boolean |
couldBuildShip(int pn)
|
boolean |
couldBuyDevCard(int pn)
|
void |
destroyGame()
set vars to null so gc can clean up |
void |
discard(int pn,
SOCResourceSet rs)
A player is discarding resources. |
static void |
discardOrGainPickRandom(SOCResourceSet fromHand,
int numToPick,
boolean isDiscard,
SOCResourceSet picks,
java.util.Random rand)
Choose discards at random; does not actually discard anything. |
void |
doDiscoveryAction(SOCResourceSet pick)
perform the Discovery card action |
int[] |
doMonopolyAction(int rtype)
perform the Monopoly card action. |
void |
endTurn()
end the turn for the current player, and check for winner. |
SOCForceEndTurnResult |
forceEndTurn()
In an active game, force current turn to be able to be ended. |
private SOCForceEndTurnResult |
forceEndTurnChkDiscardOrGain(int pn,
boolean isDiscard)
Randomly discard from this player's hand by calling discard(int, SOCResourceSet) ,
or gain random resources by calling pickGoldHexResources(int, SOCResourceSet) . |
private SOCForceEndTurnResult |
forceEndTurnStartState(boolean advTurnForward)
Special forceEndTurn() treatment for start-game states. |
java.lang.String |
gameOverMessageToPlayer(SOCPlayer pl)
If game is over, formulate a message to tell a player. |
int |
getAvailableSeatCount()
How many seats are vacant and available for players? Based on isSeatVacant(int) , and game
option "PL" (maximum players) or maxPlayers . |
SOCBoard |
getBoard()
Get the game board. |
int |
getClientVersionMinRequired()
For use at server; lowest version of client which can connect to this game (based on game options/features added in a given version), or -1 if unknown or if this game has no options. |
int |
getCurrentDice()
|
int |
getCurrentPlayerNumber()
|
long |
getExpiration()
Get the expiration time at which this game will be destroyed. |
int |
getFirstPlayer()
|
SOCFortress |
getFortress(int node)
For scenario option _SC_PIRI , get the Pirate Fortress
at this node location, if any. |
static int |
getGameOptionIntValue(java.util.Map<java.lang.String,SOCGameOption> opts,
java.lang.String optKey)
What is this integer game option's current value? |
static int |
getGameOptionIntValue(java.util.Map<java.lang.String,SOCGameOption> opts,
java.lang.String optKey,
int defValue,
boolean onlyIfBoolSet)
What is this integer game option's current value? |
int |
getGameOptionIntValue(java.lang.String optKey)
What is this integer game option's current value? |
java.util.Map<java.lang.String,SOCGameOption> |
getGameOptions()
|
static java.lang.String |
getGameOptionStringValue(java.util.Map<java.lang.String,SOCGameOption> opts,
java.lang.String optKey)
What is this string game option's current value? |
java.lang.String |
getGameOptionStringValue(java.lang.String optKey)
What is this string game option's current value? |
int |
getGameState()
Current game state. |
java.lang.String |
getName()
|
int |
getNumDevCards()
Get the number of development cards remaining to be bought. |
java.lang.String |
getOwner()
For games at the server, the owner (creator) of the game. |
java.lang.String |
getOwnerLocale()
For games at the server, get the game owner (creator)'s locale, or null . |
SOCInventoryItem |
getPlacingItem()
Get the special Inventory Item to be placed by the current player in state PLACING_INV_ITEM ,
if any, from the most recent call to setPlacingItem(SOCInventoryItem) . |
SOCPlayer |
getPlayer(int pn)
|
SOCPlayer |
getPlayer(java.lang.String nn)
Get the player sitting in this game with this name. |
SOCPlayer[] |
getPlayers()
|
java.util.Vector<SOCPlayer> |
getPlayersOnHex(int hex)
Get the players who have settlements or cities on this hex. |
java.util.Vector<SOCPlayer> |
getPlayersShipsOnHex(int hex)
|
SOCPlayer |
getPlayerWithLargestArmy()
|
SOCPlayer |
getPlayerWithLongestRoad()
|
SOCPlayer |
getPlayerWithWin()
Find the player who was declared winner at end of game. |
java.util.Vector<SOCPlayer> |
getPossibleVictims()
Given the robber or pirate's current position on the board, and getRobberyPirateFlag() ,
get the list of victims with adjacent settlements/cities or ships. |
int |
getResetOldGameState()
If the game board was reset, get the old game state. |
int |
getResetPlayerVote(int pn)
Get this player's vote on a board reset request. |
boolean |
getResetVoteActive()
|
int |
getResetVoteRequester()
If a board reset vote is active, player number who requested the vote. |
boolean |
getResetVoteResult()
If a board-reset vote is complete, give its result. |
private SOCResourceSet |
getResourcesGainedFromRoll(SOCPlayer player,
int roll)
For rollDice() , figure out what resources a player gets on a given roll,
based on the hexes adjacent to the player's settlements and cities
and based on the robber's position. |
private void |
getResourcesGainedFromRollPieces(int roll,
SOCResourceSet resources,
SOCResourceSet missedResources,
int robberHex,
java.util.Collection<? extends SOCPlayingPiece> sEnum,
int incr)
Figure out what resources these piece positions would get on a given roll, based on the hexes adjacent to the pieces' node coordinates. |
boolean |
getRobberyPirateFlag()
Does the current or most recent robbery use the pirate ship, not the robber? If true, victims will be based on adjacent ships, not settlements/cities. |
int |
getRoundCount()
The number of normal rounds (each player has 1 turn per round, after initial placements), including this round. |
SOCGame.SeatLockState |
getSeatLock(int pn)
Get a seat's lock state. |
SOCSpecialItem |
getSpecialItem(java.lang.String typeKey,
int idx)
Get a special item of a given type, by index within the list of all items of that type in this game. |
SOCSpecialItem |
getSpecialItem(java.lang.String typeKey,
int gi,
int pi,
int pn)
Get a special item of a given type, by index within the game's or player's list of all items of that type. |
java.util.ArrayList<SOCSpecialItem> |
getSpecialItems(java.lang.String typeKey)
Get a list of all special items of a given type in this game. |
java.util.Set<java.lang.String> |
getSpecialItemTypes()
Get all types of this game's SOCSpecialItem s, if any. |
java.util.Date |
getStartTime()
|
boolean |
hasBuiltCity()
Has any player built a city? Used with house-rule game option "N7C" . |
boolean |
hasHumanPlayers()
Does this game contain any human players? |
boolean |
hasTradeOffers()
Are there currently any trade offers? Calls each player's SOCPlayer.getCurrentOffer() . |
boolean |
isBoardReset()
|
boolean |
isDebugFreePlacement()
Are we in the 'free placement' debug mode? See SOCGameHandler.processDebugCommand_freePlace, SOCPlayerInterface.setDebugPaintPieceMode. |
boolean |
isForcingEndTurn()
If true, this turn is being ended. |
boolean |
isGameOptionDefined(java.lang.String optKey)
Is this game option contained in the current game's options? |
static boolean |
isGameOptionSet(java.util.Map<java.lang.String,SOCGameOption> opts,
java.lang.String optKey)
Is this boolean-valued game option currently set to true? |
boolean |
isGameOptionSet(java.lang.String optKey)
Is this boolean-valued game option currently set to true? |
boolean |
isInitialPlacement()
Are we in the Initial Placement part of the game? Includes game states START1A - START3B
and STARTS_WAITING_FOR_PICK_GOLD_RESOURCE . |
boolean |
isPickResourceIncludingPirateFleet(int pn)
For scenario option _SC_PIRI , if true and
canPickGoldHexResources(int, SOCResourceSet) in state WAITING_FOR_PICK_GOLD_RESOURCE ,
this player's "gold hex" free resources include victory over a pirate fleet attack at a dice roll. |
boolean |
isSeatVacant(int pn)
|
boolean |
isShipWarship(SOCShip sh)
For scenario option _SC_PIRI , is this ship upgraded to a warship?
Counts down sh 's player's SOCPlayer.getNumWarships()
while it looks for sh among the ships from SOCPlayer.getRoads() ,
which is in the same chronological order as warship conversions. |
boolean |
isSpecialBuilding()
During game play, are we in the Special Building Phase ?
Includes game state SPECIAL_BUILDING , and placement game states during this phase. |
void |
makeBankTrade(SOCResourceSet give,
SOCResourceSet get)
perform a bank trade, or undo the last bank trade. |
void |
makeTrade(int offering,
int accepting)
perform a trade between two players. |
SOCMoveRobberResult |
movePirate(int pn,
int ph)
Move the pirate ship. |
private SOCMoveRobberResult |
movePirate(int pn,
int ph,
int pirFleetStrength)
Move the pirate, optionally with a pirate fleet strength. |
SOCMoveRobberResult |
moveRobber(int pn,
int rh)
move the robber. |
void |
moveShip(SOCShip sh,
int toEdge)
Move this ship on the board and update all related game state. |
void |
pickGoldHexResources(int pn,
SOCResourceSet rs)
A player is picking which resources to gain from the gold hex. |
int |
placePort(int edge)
For scenario option _SC_FTRI in game state PLACING_INV_ITEM , place
the "gift" port at this edge. |
void |
placePort(SOCPlayer pl,
int ptype,
int edge)
For scenario option _SC_FTRI , place a "gift" port at this edge. |
void |
playDiscovery()
the current player plays a Discovery card |
SOCResourceSet |
playerDiscardOrGainRandom(int pn,
boolean isDiscard)
Force this non-current player to discard or gain resources randomly. |
SOCInventoryItem |
playInventoryItem(int itype)
Play a special SOCInventoryItem for the current player. |
void |
playKnight()
The current player plays a Knight card. |
void |
playMonopoly()
the current player plays a monopoly card |
void |
playRoadBuilding()
The current player plays a Road Building card. |
void |
putPiece(SOCPlayingPiece pp)
Put this piece on the board and update all related game state. |
private void |
putPieceCommon_checkFogHexes(int[] hexCoords,
boolean initialSettlement)
On the large sea board, look for and reveal any adjacent fog hex, if we're placing a road or ship touching the fog hex's corner node. |
private void |
putPieceCommon(SOCPlayingPiece pp,
boolean isTempPiece)
Put a piece or temporary piece on the board, and update all related game state. |
void |
putTempPiece(SOCPlayingPiece pp)
A temporary piece has been put on the board; update all related game state. |
void |
releaseMonitor()
release the monitor for this game |
void |
removePlayer(java.lang.String name)
remove a player from their seat. |
SOCInventoryItem |
removePort(SOCPlayer pl,
int edge)
For scenario option _SC_FTRI , remove a "gift" port
at this edge to be placed elsewhere. |
void |
removeShip(SOCShip sh)
Remove this ship from the board and update all related game state. |
SOCGame |
resetAsCopy()
Create a new game with same players and name, new board; like calling constructor otherwise. |
void |
resetVoteBegin(int reqPN)
Begin a board-reset vote. |
void |
resetVoteClear()
At end of turn, clear flags for board reset voting: requester, players' setAskedBoardReset. |
boolean |
resetVoteRegister(int pn,
boolean votingYes)
Register this player's vote in a board reset request. |
void |
restoreLargestArmyState()
Restore the state of who had largest army. |
void |
revealFogHiddenHex(int hexCoord,
int hexType,
int diceNum)
Reveal one land or water hex hidden by fog . |
private void |
rollDice_update7gameState()
When a 7 is rolled, update the gameState :
Always WAITING_FOR_DISCARDS if any SOCPlayer.getResources() total > 7. |
SOCGame.RollResult |
rollDice()
roll the dice. |
void |
saveLargestArmyState()
Save the state of who has largest army. |
void |
setCurrentDice(int dr)
set the current dice result |
void |
setCurrentPlayerNumber(int pn)
Set the number of the current player, and check for winner. |
void |
setDebugFreePlacement(boolean debugOn)
Turn the "free placement" debug mode on or off, if possible. |
void |
setExpiration(long ex)
Set the expiration time at which this game will be destroyed. |
void |
setFirstPlayer(int pn)
Sets who the first player is. |
void |
setGameState(int gs)
set the current game state. |
void |
setNumDevCards(int nd)
set the number of dev cards in the deck |
void |
setOwner(java.lang.String gameOwnerName,
java.lang.String gameOwnerLocale)
For games at the server, set the game owner (creator). |
void |
setPlacingItem(SOCInventoryItem item)
Set or clear the special Inventory Item to be placed by the current player in state PLACING_INV_ITEM . |
protected void |
setPlayer(int pn,
SOCPlayer pl)
set the data for a player |
void |
setPlayersLandHexCoordinates()
For each player, call pl.setLandHexCoordinates
(SOCBoardLarge.getLandHexCoords() ). |
void |
setPlayerWithLargestArmy(SOCPlayer pl)
set the player with the largest army |
void |
setPlayerWithLongestRoad(SOCPlayer pl)
set the player with the longest road or trade route |
void |
setScenarioEventListener(SOCScenarioEventListener sel)
Set or clear the scenario event listener. |
void |
setSeatLock(int pn,
SOCGame.SeatLockState sl)
Lock or unlock a seat, or mark a bot's seat to be cleared on reset. |
SOCSpecialItem |
setSpecialItem(java.lang.String typeKey,
int idx,
SOCSpecialItem itm)
Add or replace a special item in the game's list of items of that type. |
private void |
startGame_setupDevCards()
For startGame() , fill and shuffle the development card deck. |
void |
startGame()
do the things involved in starting a game: shuffle the tiles and cards, make a board, set players' legal and potential piece locations, choose first player. |
int |
stealFromPlayer(int pn,
boolean choseCloth)
the current player has choosen a victim to rob. |
private void |
stealFromPlayerPirateFleet(int pn,
int pirFleetStrength)
In game scenario _SC_PIRI , the pirate fleet is moved every
dice roll, and may steal from the single player with an adjacent settlement or city. |
void |
takeMonitor()
Take the synchronization monitor for this game. |
java.lang.String |
toString()
toString contains the game name. |
void |
undoPutInitSettlement(SOCPlayingPiece pp)
undo the putting of an initial settlement. |
protected void |
undoPutPieceCommon(SOCPlayingPiece pp,
boolean isTempPiece)
undo the putting of a temporary or initial piece or a ship being moved. |
void |
undoPutTempPiece(SOCPlayingPiece pp)
undo the putting of a temporary piece |
void |
updateAtBoardLayout()
Update any miscellaneous game info as needed after the board layout is set, before the game starts. |
private void |
updateAtGameFirstTurn()
Update game state as needed after initial placement before the first turn of normal play: Call each player's SOCPlayer.clearPotentialSettlements()
If hasSeaBoard , check board for Added Layout Part "AL" for node lists that
become legal locations for settlements after initial placement, and make them legal now. |
void |
updateAtTurn()
Update game state as needed when a player begins their turn (before dice are rolled). |
void |
updateLargestArmy()
update which player has the largest army larger than 2 |
void |
updateLongestRoad(int pn)
update which player has longest road longer than 4. |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait |
Field Detail |
---|
private static final long serialVersionUID
public static final int NEW
NEW
is a brand-new game, not yet ready to start playing.
Players are choosing where to sit, or have all sat but no one has yet clicked
the "start game" button.
Next state from NEW is READY
if robots, or START1A
if only humans
are playing.
General assumptions for states and their numeric values:
START1A
and < OVER
START2B
or START3B
, going directly to PLAY
PLAY1
, after dice-roll/card-play in PLAY
PLAY1
, < OVER
; state name starts with
PLACING_ or WAITING_
The code reacts to (switches based on) game state in several places. The main places to check, if you add a game state:
SOCBoardPanel.updateMode()
SOCBuildingPanel.updateButtonStatus()
SOCPlayerInterface.updateAtGameState()
putPiece(SOCPlayingPiece)
advanceTurnStateAfterPutPiece()
forceEndTurn()
SOCRobotBrain.run()
SOCGameHandler.sendGameState(SOCGame)
If your new state might be waiting for several players (not just the current player) to
respond with a choice (such as picking resources to discard or gain), also update
GameHandler.endTurnIfInactive(SOCGame, long)
. Otherwise the robot will be
forced to lose its turn while waiting for human players.
Other places to check, if you add a game state:
public static final int READY
START1A
.
READY_RESET_WAIT_ROBOT_DISMISS
,
Constant Field Valuespublic static final int SETOPTIONS_EXCL
public static final int SETOPTIONS_INCL
public static final int READY_RESET_WAIT_ROBOT_DISMISS
READY
.
See boardResetOngoingInfo
and (private) SOCServer.resetBoardAndNotify.
public static final int START1A
START1B
to place each player's 1st road.
public static final int START1B
START1A
to place next
player's 1st settlement, or if all have placed settlements,
START2A
to place 2nd settlement.
public static final int START2A
START2B
to place 2nd road.
If the settlement is placed on a Gold Hex, the next state
is STARTS_WAITING_FOR_PICK_GOLD_RESOURCE
.
If game scenario option _SC_3IP
is set, then instead of
this second settlement giving resources, a third round of placement will do that;
next game state after START2A remains START2B
.
public static final int STARTS_WAITING_FOR_PICK_GOLD_RESOURCE
_SC_FOG
)
when any initial road, settlement, or ship reveals a gold hex.
The next game state will be based on oldGameState,
which is the state whose placement led to STARTS_WAITING_FOR_PICK_GOLD_RESOURCE
.
For settlements not revealed from fog:
Next game state is START2B
to place 2nd road.
If game scenario option _SC_3IP
is set,
next game state is START3B
.
Valid only when hasSeaBoard
, settlement adjacent to SOCBoardLarge.GOLD_HEX
,
or gold revealed from SOCBoardLarge.FOG_HEX
by a placed road, ship, or settlement.
WAITING_FOR_PICK_GOLD_RESOURCE
,
pickGoldHexResources(int, SOCResourceSet)
,
Constant Field Valuespublic static final int START2B
START2A
to place previous
player's 2nd settlement (player changes in reverse order), or if all have placed
settlements, PLAY
to begin first player's turn.
If game scenario option _SC_3IP
is set, then instead of
starting normal play, a third settlement and road are placed by each player,
with game state START3A
.
public static final int START3A
START3B
to place 3rd road.
If the settlement is placed on a Gold Hex, the next state
is STARTS_WAITING_FOR_PICK_GOLD_RESOURCE
.
Valid only when game scenario option _SC_3IP
is set.
public static final int START3B
START3A
to place previous
player's 3rd settlement (player changes in normal order), or if all have placed
settlements, PLAY
to begin first player's turn.
Valid only when game scenario option _SC_3IP
is set.
public static final int PLAY
PLAY1
.
If 7 is rolled, might be WAITING_FOR_DISCARDS
or WAITING_FOR_ROBBER_OR_PIRATE
or PLACING_ROBBER
or PLACING_PIRATE
.
If 7 is rolled with scenario option _SC_PIRI, there is no robber to move, but
the player will choose their robbery victim (WAITING_FOR_ROB_CHOOSE_PLAYER
) after any discards.
If the number rolled is on a gold hex, next state might be
WAITING_FOR_PICK_GOLD_RESOURCE
.
More special notes for scenario _SC_PIRI: When the dice is rolled, the pirate fleet moves
along a path, and attacks the sole player with an adjacent settlement to the pirate hex, if any.
This is resolved before any of the normal dice-rolling actions (distributing resources, handling a 7, etc.)
If the player ties or loses (pirate fleet is stronger than player's fleet of warships), the roll is
handled as normal, as described above. If the player wins, they get to pick a random resource.
Unless the roll is 7, this can be dealt with along with other gained resources (gold hexes).
So: If the player wins and the roll is 7, the player must pick their resource before any normal 7 discarding.
In that case only, the next state is WAITING_FOR_PICK_GOLD_RESOURCE
, which will be
followed by WAITING_FOR_DISCARDS
or WAITING_FOR_ROB_CHOOSE_PLAYER
.
public static final int PLAY1
PLAY
.
public static final int PLACING_ROAD
public static final int PLACING_SETTLEMENT
public static final int PLACING_CITY
public static final int PLACING_ROBBER
WAITING_FOR_ROBBER_OR_PIRATE
if the game hasSeaBoard
.
Next game state may be WAITING_FOR_ROB_CHOOSE_PLAYER
if multiple possible victims.
PLACING_PIRATE
,
canMoveRobber(int, int)
,
moveRobber(int, int)
,
Constant Field Valuespublic static final int PLACING_PIRATE
hasSeaBoard
.
May follow state WAITING_FOR_ROBBER_OR_PIRATE
.
Next game state may be WAITING_FOR_ROB_CHOOSE_PLAYER
if multiple possible victims.
In scenario _SC_CLVI
, next may be WAITING_FOR_ROB_CLOTH_OR_RESOURCE
.
PLACING_ROBBER
,
canMovePirate(int, int)
,
movePirate(int, int)
,
Constant Field Valuespublic static final int PLACING_SHIP
hasSeaBoard
, and a player has bought and is placing a ship.
public static final int PLACING_FREE_ROAD1
public static final int PLACING_FREE_ROAD2
public static final int PLACING_INV_ITEM
SOCInventoryItem
held in getPlacingItem()
.
For some kinds of item, placement can be canceled by calling cancelPlaceInventoryItem(boolean)
.
The placement method depends on the scenario and item type; for example,
_SC_FTRI
has trading port items and would
call placePort(int)
.
Placement requires its own game state (not PLAY1
) because sometimes
it's triggered by the game after another action, not initiated by player request.
When setting this gameState: In case placement is canceled, set
oldGameState
to PLAY1
or SPECIAL_BUILDING
.
public static final int WAITING_FOR_DISCARDS
rollDice()
.
Next game state is WAITING_FOR_DISCARDS
(if other players still need to discard),
WAITING_FOR_ROBBER_OR_PIRATE
,
or PLACING_ROBBER
.
In scenario option _SC_PIRI, there is no robber
to move, but the player will choose their robbery victim
(WAITING_FOR_ROB_CHOOSE_PLAYER
) after any discards.
If there are no possible victims, next state is PLAY1
.
discard(int, SOCResourceSet)
,
Constant Field Valuespublic static final int WAITING_FOR_ROB_CHOOSE_PLAYER
PLAY1
or WAITING_FOR_ROB_CLOTH_OR_RESOURCE
.
To see whether we're moving the robber or the pirate, use getRobberyPirateFlag()
.
To choose the player, call choosePlayerForRobbery(int)
.
In scenario option _SC_PIRI, there is no robber
to move, but the player will choose their robbery victim.
currentRoll
.sc_clvi_robPossibleVictims
holds the list of possible victims. In that scenario,
the player also doesn't control the pirate ships, and
never has Knight cards to move the robber and steal.
So in that scenario, the only time the game state is WAITING_FOR_ROB_CHOOSE_PLAYER
is when the player must choose to steal from a possible victim, or choose to steal
from no one, after a 7 is rolled. To choose the victim, call choosePlayerForRobbery(int)
.
To choose no one, call choosePlayerForRobbery(-1)
.
Before v2.0.00, this game state was called WAITING_FOR_CHOICE
.
playKnight()
,
canChoosePlayer(int)
,
canChooseRobClothOrResource(int)
,
stealFromPlayer(int, boolean)
,
Constant Field Valuespublic static final int WAITING_FOR_DISCOVERY
PLAY1
.
public static final int WAITING_FOR_MONOPOLY
PLAY1
.
public static final int WAITING_FOR_ROBBER_OR_PIRATE
rollDice()
or playKnight()
.
Next game state is PLACING_ROBBER
or PLACING_PIRATE
.
canChooseMovePirate()
,
chooseMovePirate(boolean)
,
WAITING_FOR_DISCARDS
,
Constant Field Valuespublic static final int WAITING_FOR_ROB_CLOTH_OR_RESOURCE
PLACING_PIRATE
or WAITING_FOR_ROB_CHOOSE_PLAYER
.
Used with scenario option _SC_CLVI
.
movePirate(int, int)
,
canChooseRobClothOrResource(int)
,
Constant Field Valuespublic static final int WAITING_FOR_PICK_GOLD_RESOURCE
PLAY1
, sometimes
PLACING_FREE_ROAD2
or SPECIAL_BUILDING
.
(oldGameState
holds the next state after this WAITING state.)
Valid only when hasSeaBoard
, settlements or cities
adjacent to SOCBoardLarge.GOLD_HEX
.
If scenario option _SC_PIRI
is active,
this state is also used when a 7 is rolled and the player has won against a
pirate fleet attack. They must choose a free resource. oldGameState
is PLAY
.
Then, the 7 is resolved as normal. See PLAY
javadoc for details.
That's the only time free resources are picked on rolling 7.
STARTS_WAITING_FOR_PICK_GOLD_RESOURCE
,
pickGoldHexResources(int, SOCResourceSet)
,
Constant Field Valuespublic static final int WAITING_FOR_DESTROY
SOCDevCardConstants.DESTROY
).
Used with game option "DH".
public static final int WAITING_FOR_SWAP
SOCDevCardConstants.SWAP
).
Used with game option "DH".
public static final int SPECIAL_BUILDING
currentPlayerNumber
.
So, it begins by calling advanceTurn()
to
the next player, and continues clockwise until
currentPlayerNumber
== specialBuildPhase_afterPlayerNumber
.
At that point, the Special Building Phase is over,
and it's the next player's turn as usual.
public static final int OVER
vp_winner
) victory points,
or all players have left the game.
checkForWinner()
,
Constant Field Valuespublic static final int RESET_OLD
OVER
.
resetAsCopy()
,
getResetOldGameState()
,
Constant Field Valuespublic static final int VACANT
public static final int OCCUPIED
public static final int VOTE_NONE
boardResetVotes
per-player states: no vote sent; yes; no.
public static final int VOTE_YES
public static final int VOTE_NO
public static final int MAXPLAYERS
maxPlayers
,
MAXPLAYERS_STANDARD
,
Constant Field Valuespublic static final int MAXPLAYERS_STANDARD
MAXPLAYERS
,
maxPlayers
,
Constant Field Valuespublic static final int MINPLAYERS
MAXPLAYERS
in standard 1.0.6).
Use isSeatVacant(int)
to determine if a player is present;
players[i] will be non-null although no player is there.
public static final int VP_WINNER_STANDARD
vp_winner
, can be changed from 10 in
constructor with the "VP" SOCGameOption
.
Before v1.1.14, this was public static final int VP_WINNER.
private static final int NUM_DEVCARDS_VP
_SC_PIRI
.
(If 4 or more players in that scenario, they become KNIGHT
cards.)
NUM_DEVCARDS_STANDARD
,
Constant Field Valuesprivate static final int NUM_DEVCARDS_STANDARD
NUM_DEVCARDS_6PLAYER
,
Constant Field Valuesprivate static final int NUM_DEVCARDS_6PLAYER
NUM_DEVCARDS_STANDARD
,
Constant Field Valuespublic static final int VERSION_FOR_CANCEL_FREE_ROAD2
cancelBuildRoad(int)
,
cancelBuildShip(int)
,
Constant Field Valuespublic static final SOCResourceSet EMPTY_RESOURCES
SETTLEMENT_SET
public static final SOCResourceSet SETTLEMENT_SET
settlement
SOCPlayingPiece.getResourcesToBuild(int)
public static final SOCResourceSet ROAD_SET
road
SOCPlayingPiece.getResourcesToBuild(int)
public static final SOCResourceSet CITY_SET
city
SOCPlayingPiece.getResourcesToBuild(int)
public static final SOCResourceSet SHIP_SET
ship
SOCPlayingPiece.getResourcesToBuild(int)
public static final SOCResourceSet CARD_SET
SOCPlayingPiece.getResourcesToBuild(int)
,
SOCInventory
public static SOCBoard.BoardFactory boardFactory
SOCBoard.BoardFactory
for creating new boards in the SOCGame constructors.
Differs at client and at server.
If null, SOCGame constructor sets to SOCBoard.DefaultBoardFactory
.
private static final int[] EMPTY_INT_ARRAY
boolean inUse
private java.lang.String name
boolean isAtServer
startGame()
.
public transient java.util.List<java.lang.Object> pendingMessagesOut
putPiece(SOCPlayingPiece)
), create pending PLAYERELEMENT messages from
SOCScenarioEventListener.playerEvent(...)
,
send the usual messages related to that action, then check this list and send out
the pending PLAYERELEMENT message so that the game's clients will update that player's
SOCPlayer.setScenarioPlayerEvents(int)
or other related fields, before the GAMESTATE message.
Note: Only a few of the server message-handling methods check this field, because
only those few can potentially lead to special victory points or other game/scenario events.
If you add code where other player actions can lead to pendingMessagesOut
adds, be sure
the server handler for those actions checks this list afterwards, to send before GAMESTATE.
Because this is server-only, it's null until startGame()
.
To send and clear this list's contents, the server should call
SOCGameHandler.sendGamePendingMessages(SOCGame, boolean)
.
private java.lang.String ownerName
resetAsCopy()
copies ownerName,
even if they aren't still connected to the game.
NOT CURRENTLY SET AT CLIENT.
private java.lang.String ownerLocale
hasMultiLocales
when adding a member to the game.
Currently, if the game is reset, resetAsCopy()
copies ownerLocale
,
even if they aren't still connected to the game.
Server only, this field is not set at client.
private boolean active
public final int vp_winner
VP_WINNER_STANDARD
== 10).
After game events such as playing a piece or moving the robber, check if current player's
VP >= vp_winner
and call checkForWinner()
if so.
hasScenarioWinCondition
public final boolean hasScenarioWinCondition
vp_winner
?
For example, scenario _SC_CLVI
will end the game if
less than half the SOCVillage
s have cloth remaining. See checkForWinner()
for a full list and more details.
When set, methods that check current player's VP >= vp_winner
will
also call checkForWinner()
.
public boolean isPractice
Since 1.1.09: This flag is set at the server, only if the server is a local practice server whose stringport name is SOCServer.PRACTICE_STRINGPORT.
Before 1.1.13, this field was called isLocal, but that was misleading; the full client can launch a locally hosted tcp LAN server.
public boolean isBotsOnly
This flag should be set by the server when creating the game. If a human observer exits
a game with this flag, the game should continue play unless its state is OVER
.
private boolean hasBuiltCity
"N7C"
.
SOCScenarioEventListener scenarioEventListener
large sea board
, or null.
Package access for read-only use by SOCPlayer
.
public boolean hasOldClients
public int clientVersionLowest
public int clientVersionHighest
private int clientVersionMinRequired
Calculated by SOCVersionedItem.itemsMinimumVersion(Map)
.
Format is the internal integer format, see Version.versionNumber()
.
Value may sometimes be too low at client, see getClientVersionMinRequired()
for details.
public boolean hasMultiLocales
getOwnerLocale()
?
Initially false, set true in SOCGameListAtServer.addMember
if needed.
private boolean debugFreePlacement
private boolean debugFreePlacementStartPlaced
debugFreePlacement
during initial placement? Set in putPiece(SOCPlayingPiece)
.
private boolean isFromBoardReset
public transient SOCGameBoardReset boardResetOngoingInfo
READY_RESET_WAIT_ROBOT_DISMISS
).
This field is null except within the newly-created game object during reset.
private int boardResetVoteRequester
boardResetVotes
before reading or writing.
private int[] boardResetVotes
VOTE_NONE
, VOTE_YES
, VOTE_NO
.
Indexed 0 to SOCGame.MAXPLAYERS-1.
Synchronize on this object before reading or writing.
private int boardResetVotesWaiting
boardResetVotes
before reading or writing.
When the vote is complete, or before the first vote has begun, this is 0.
Set in resetVoteBegin, resetVoteRegister. Cleared in resetVoteClear.
private SOCBoard board
private java.util.Map<java.lang.String,SOCGameOption> opts
SOCGameOption
), or null
private SOCPlayer[] players
isSeatVacant(int)
to see if a position is occupied. Length is maxPlayers
.
private int[] seats
private SOCGame.SeatLockState[] seatLocks
private int currentPlayerNumber
private int firstPlayerNumber
private int lastPlayerNumber
public final int maxPlayers
The 6-player extensions are orthogonal to other board type/expansion flags such as hasSeaBoard
;
one doesn't imply or exclude the other.
public final boolean hasSeaBoard
SOCBoardLarge
large board / sea board?
If true, our board's SOCBoard.getBoardEncodingFormat()
must be SOCBoard.BOARD_ENCODING_LARGE
.
When hasSeaBoard
, getBoard()
can always be cast to SOCBoardLarge
.
The 6-player extensions (maxPlayers
== 6) are orthogonal to hasSeaBoard
or other board types/expansions; one doesn't imply or exclude the other.
In most scenarios the sea board has a pirate ship that can be moved instead of
the robber. See game states WAITING_FOR_ROBBER_OR_PIRATE
and PLACING_PIRATE
.
private int currentDice
PLAY
).
currentRoll
private SOCGame.RollResult currentRoll
SOCVillage.distributeCloth(SOCGame)
results.
This is the object returned from rollDice()
each turn.
currentDice
private SOCMoveRobberResult robberResult
moveRobber(int, int)
or movePirate(int, int)
result.
Used at server only.
private int gameState
private int oldGameState
oldGameState is read in these states:
STARTS_WAITING_FOR_PICK_GOLD_RESOURCE
:
After the resource is picked, oldGameState will be the starting state for
advanceTurnStateAfterPutPiece()
.
PLACING_ROAD
, PLACING_SETTLEMENT
, PLACING_CITY
, PLACING_SHIP
:
Unless oldGameState is SPECIAL_BUILDING
,
advanceTurnStateAfterPutPiece()
will set the state to PLAY1
.
So will cancelBuildRoad(int)
, cancelBuildSettlement(int)
, etc.
PLACING_INV_ITEM
:
oldGameState
== PLAY1
or SPECIAL_BUILDING
,
same advance/cancel logic as other PLACING_
states mentioned above.
PLACING_ROBBER
, WAITING_FOR_ROBBER_OR_PIRATE
:
oldGameState = PLAY1
WAITING_FOR_ROB_CHOOSE_PLAYER
, PLACING_PIRATE
, WAITING_FOR_ROB_CLOTH_OR_RESOURCE
WAITING_FOR_DISCOVERY
in playDiscovery()
, doDiscoveryAction(SOCResourceSet)
WAITING_FOR_MONOPOLY
in playMonopoly()
, doMonopolyAction(int)
WAITING_FOR_PICK_GOLD_RESOURCE
:
oldGameState holds the next state to go to when all players are done picking resources.
After picking gold from a dice roll, this will usually be PLAY1
.
Sometimes will be PLACING_FREE_ROAD2
or SPECIAL_BUILDING
.
getResetOldGameState()
holds the state before the reset.
private boolean placingRobberForKnightCard
PLACING_ROBBER
,
the robber is being moved because a knight card
has just been played. Thus, if forceEndTurn()
is called, the knight card should then be returned to
the player's hand.
private boolean forcingEndTurn
endTurn()
whenever possible. Usually set when we have called forceEndTurn()
, and
forced the current player to discard randomly, and are waiting for other players
to discard in gamestate WAITING_FOR_DISCARDS
. Once all players have
discarded, the turn should be ended.
forceEndTurn()
private boolean askedSpecialBuildPhase
specialBuildPhase_afterPlayerNumber
private int specialBuildPhase_afterPlayerNumber
SPECIAL_BUILDING
.
The Special Building Phase changes currentPlayerNumber
.
So, it begins by calling advanceTurn()
to
the next player, and continues clockwise until
currentPlayerNumber
== specialBuildPhase_afterPlayerNumber
.
At that point, the Special Building Phase is over,
and it's the next player's turn as usual.
askedSpecialBuildPhase
private int playerWithLargestArmy
private int oldPlayerWithLargestArmy
playerWithLargestArmy
during
saveLargestArmyState()
/ restoreLargestArmyState()
.
private int playerWithLongestRoad
java.util.Stack<SOCOldLRStats> oldPlayerWithLongestRoad
private int playerWithWin
private int numDevCards
devCardDeck
for buyDevCard()
.
private int[] devCardDeck
SOCDevCardConstants
.
numDevCards
tracks the cards remaining to buy.
private java.util.HashMap<java.lang.String,java.util.ArrayList<SOCSpecialItem>> spItems
SOCSpecialItem
s, if any, by type.
This is not the union of each player's spItems
, but a separately maintained Map of item lists.
See getter/setter javadocs for details on type keys and rationale for lack of synchronization.
ArrayList is used to guarantee we can store null items.
Initialized at server and client in updateAtBoardLayout()
using
SOCSpecialItem.makeKnownItem(String, int)
.
private java.util.Random rand
boolean allOriginalPlayers
java.util.Date startTime
active
when created.
lastActionTime
,
expiration
long expiration
startTime
);
Same format as System.currentTimeMillis()
.
startTime
public long lastActionTime
updateAtTurn()
, putPiece(SOCPlayingPiece)
,
and a few other game action methods.
Same format as System.currentTimeMillis()
.
The server can set this field to 0 to tell itself to end a turn soon, but
otherwise the value should be a recent time.
At the end of a game, the server may increase this value by
90 minutes (SOCGameListAtServer.GAME_TIME_EXPIRE_MINUTES
)
in order to remove it from the SOCGameTimeoutChecker
run loop.
getStartTime()
,
getExpiration()
private boolean lastActionWasBankTrade
lastActionTime
is updated.
TODO: Consider lastActionType instead, it's more general.
private boolean robberyWithPirateNotRobber
chooseMovePirate(boolean)
, movePirate(int, int)
, moveRobber(int, int)
,
and other places that set gameState to PLACING_ROBBER
or PLACING_PIRATE
.
getRobberyPirateFlag()
private boolean movedShipThisTurn
hasSeaBoard
.
private java.util.Vector<java.lang.Integer> placedShipsThisTurn
hasSeaBoard
.
private SOCInventoryItem placingItem
PLACING_INV_ITEM
, or null.
Can be set with setPlacingItem(SOCInventoryItem)
before or during that state.
private int turnCount
updateAtTurn()
.
private int roundCount
updateAtTurn()
.
Constructor Detail |
---|
public SOCGame(java.lang.String n)
n
- the name of the game. For network message safety, must not contain
control characters, SOCMessage.sep_char
, or SOCMessage.sep2_char
.
This is enforced by calling SOCMessage.isSingleLineAndSafe(String)
.public SOCGame(java.lang.String n, java.util.Map<java.lang.String,SOCGameOption> op) throws java.lang.IllegalArgumentException
"SC"
).
n
- the name of the game. For network message safety, must not contain
control characters, SOCMessage.sep_char
, or SOCMessage.sep2_char
.
This is enforced by calling SOCMessage.isSingleLineAndSafe(String)
.op
- if game has options, map of SOCGameOption
; otherwise null.
Will validate options and include optional scenario's SOCScenario.scOpts
by calling
SOCGameOption.adjustOptionsToKnown(Map, Map, boolean)
with doServerPreadjust false,
and set game's minimum version by calling
SOCVersionedItem.itemsMinimumVersion(Map)
.
java.lang.IllegalArgumentException
- if op contains unknown options, or any
object class besides SOCGameOption
public SOCGame(java.lang.String n, boolean isActive) throws java.lang.IllegalArgumentException
n
- the name of the game. For network message safety, must not contain
control characters, SOCMessage.sep_char
, or SOCMessage.sep2_char
.
This is enforced by calling SOCMessage.isSingleLineAndSafe(String)
.isActive
- true if this is an active game, false for inactive
java.lang.IllegalArgumentException
- if game name fails
SOCMessage.isSingleLineAndSafe(String)
. This check was added in 1.1.07.public SOCGame(java.lang.String n, boolean isActive, java.util.Map<java.lang.String,SOCGameOption> op) throws java.lang.IllegalArgumentException
"SC"
).
n
- the name of the game. For network message safety, must not contain
control characters, SOCMessage.sep_char
, or SOCMessage.sep2_char
.
This is enforced by calling SOCMessage.isSingleLineAndSafe(String)
.isActive
- true if this is an active game, false for inactiveop
- if game has options, map of SOCGameOption
; otherwise null.
Will validate options and include optional scenario's SOCScenario.scOpts
by calling
SOCGameOption.adjustOptionsToKnown(Map, Map, boolean)
with doServerPreadjust false,
and set game's minimum version by calling
SOCVersionedItem.itemsMinimumVersion(Map)
.
java.lang.IllegalArgumentException
- if op contains unknown options, or any
object class besides SOCGameOption
, or if game name
fails SOCMessage.isSingleLineAndSafe(String)
.Method Detail |
---|
public void takeMonitor()
releaseMonitor()
.
public void releaseMonitor()
takeMonitor()
public boolean allOriginalPlayers()
hasHumanPlayers()
public boolean hasHumanPlayers()
SOCPlayer.isRobot()
).allOriginalPlayers()
public java.util.Date getStartTime()
getExpiration()
public long getExpiration()
startTime
);
same epoch as Date.getTime()
getStartTime()
public void setScenarioEventListener(SOCScenarioEventListener sel) throws java.lang.IllegalStateException
large sea board
scenario events.
Only one listener is allowed. If you are setting the listener, it must currently be null.
sel
- Listener, or null for none
java.lang.IllegalStateException
- If listener already not null, sel is not null, and listener is not selpublic void setExpiration(long ex)
ex
- the absolute expiration time in milliseconds
(system clock time, not a duration from startTime
);
same epoch as Date.getTime()
public java.lang.String getOwner()
setOwner(String, String)
was never calledgetOwnerLocale()
public void setOwner(java.lang.String gameOwnerName, java.lang.String gameOwnerLocale) throws java.lang.IllegalStateException
gameOwnerName
- The game owner's player name, or null to cleargameOwnerLocale
- The game owner's locale, or null
to clear
java.lang.IllegalStateException
- if gameOwnerName not null, but the game's owner is already setpublic final java.lang.String getOwnerLocale()
null
.
Used by SOCGameListAtServer.addMember
to determine whether to set hasMultiLocales
.
public void addPlayer(java.lang.String name, int pn) throws java.lang.IllegalStateException, java.lang.IllegalArgumentException
If the game just started, players are placing their first settlement and road
(gamestate is < START2A
), and the new player sits at a vacant seat,
check and update the first player number or last player number if necessary.
If the new player's pn
is less than getCurrentPlayerNumber()
,
they already missed their first settlement and road placement but will get their second one.
Note: Once the game has started and everyone already has placed their
first settlement and road (gamestate is >= START2A
), no one new
should sit down at a vacant seat, they won't have initial placements to receive
resources. This method doesn't know if the seat has always been vacant, or if
a robot has just left the game to vacate the seat. So this restriction must be
enforced earlier, when the player requests sitting down at a vacant seat or at
a robot's position.
name
- the player's name; must pass SOCMessage.isSingleLineAndSafe(String)
.pn
- the player's requested player number; the seat number at which they would sit
java.lang.IllegalStateException
- if player is already sitting in
another seat in this game, or if there are no open seats
(based on seats[] == OCCUPIED, and game option "PL" or maxPlayers
)
via getAvailableSeatCount()
java.lang.IllegalArgumentException
- if name fails SOCMessage.isSingleLineAndSafe(String)
.
This exception was added in 1.1.07.isSeatVacant(int)
public void removePlayer(java.lang.String name) throws java.lang.IllegalArgumentException
null
. isSeatVacant(playerNum)
becomes true.
If they are the current player,
call this and then call canEndTurn(int)
.
You'll need to then call endTurn()
or forceEndTurn()
.
name
- the player's name
java.lang.IllegalArgumentException
- if name isn't in this game.
This exception was added in 1.1.07.public boolean isSeatVacant(int pn)
pn
- the number of the seat
getAvailableSeatCount()
public int getAvailableSeatCount()
isSeatVacant(int)
, and game
option "PL" (maximum players) or maxPlayers
.
isSeatVacant(int)
public SOCGame.SeatLockState getSeatLock(int pn)
pn
- the number of the seatpublic void setSeatLock(int pn, SOCGame.SeatLockState sl) throws java.lang.IllegalStateException
NEW
) versus when the game is active.
For details, see the javadocs for SOCGame.SeatLockState.LOCKED
,
UNLOCKED
and CLEAR_ON_RESET
.
For player consistency, seat locks can't be changed while getResetVoteActive()
in server version 1.1.19 and higher.
Before v2.0.00, this was lockSeat(pn
} and unlockSeat(pn)
.
pn
- the number of the seatsl
- the new lock state for this seat
java.lang.IllegalStateException
- if the game is still forming
but sl
is SOCGame.SeatLockState.CLEAR_ON_RESET
,
or if getResetVoteActive()
public SOCPlayer getPlayer(int pn) throws java.lang.ArrayIndexOutOfBoundsException
pn
- the player number, in range 0 to maxPlayers
-1
java.lang.ArrayIndexOutOfBoundsException
- if pn
is out of rangepublic SOCPlayer getPlayer(java.lang.String nn)
nn
- the nickname
public java.lang.String getName()
public java.util.Map<java.lang.String,SOCGameOption> getGameOptions()
SOCGameOption
), or nullisGameOptionDefined(String)
,
isGameOptionSet(String)
,
getGameOptionIntValue(String)
public boolean isGameOptionDefined(java.lang.String optKey)
optKey
- Name of a SOCGameOption
isGameOptionSet(String)
,
getGameOptionIntValue(String)
public boolean isGameOptionSet(java.lang.String optKey)
optKey
- Name of a SOCGameOption
of type OTYPE_BOOL
,
OTYPE_INTBOOL
or OTYPE_ENUMBOOL
isGameOptionDefined(String)
,
getGameOptionIntValue(String)
,
getGameOptionStringValue(String)
public static boolean isGameOptionSet(java.util.Map<java.lang.String,SOCGameOption> opts, java.lang.String optKey)
opts
- A map of SOCGameOption
, or nulloptKey
- Name of a SOCGameOption
of type OTYPE_BOOL
,
OTYPE_INTBOOL
or OTYPE_ENUMBOOL
isGameOptionDefined(String)
,
isGameOptionSet(String)
,
getGameOptionIntValue(Map, String)
,
getGameOptionStringValue(Map, String)
public int getGameOptionIntValue(java.lang.String optKey)
Does not reference SOCGameOption.getBoolValue()
, only the int value,
so this will return a value even if the bool value is false.
optKey
- A SOCGameOption
of type OTYPE_INT
,
OTYPE_INTBOOL
,
OTYPE_ENUM
or OTYPE_ENUMBOOL
intValue
,
or 0 if not defined in this game's options;
OTYPE_ENUM's choices give an intVal in range 1 to n.isGameOptionDefined(String)
,
isGameOptionSet(String)
public static int getGameOptionIntValue(java.util.Map<java.lang.String,SOCGameOption> opts, java.lang.String optKey)
Does not reference SOCGameOption.getBoolValue()
, only the int value,
so this will return a value even if the bool value is false.
opts
- A map of SOCGameOption
, or nulloptKey
- A SOCGameOption
of type OTYPE_INT
,
OTYPE_INTBOOL
,
OTYPE_ENUM
or OTYPE_ENUMBOOL
intValue
,
or 0 if not defined in the set of options;
OTYPE_ENUM's and _ENUMBOOL's choices give an intVal in range 1 to n.isGameOptionDefined(String)
,
isGameOptionSet(String)
,
getGameOptionIntValue(Map, String, int, boolean)
public static int getGameOptionIntValue(java.util.Map<java.lang.String,SOCGameOption> opts, java.lang.String optKey, int defValue, boolean onlyIfBoolSet)
Can optionally reference SOCGameOption.getBoolValue()
, not only the int value.
opts
- A map of SOCGameOption
, or nulloptKey
- A SOCGameOption
of type OTYPE_INT
,
OTYPE_INTBOOL
,
OTYPE_ENUM
or OTYPE_ENUMBOOL
defValue
- Default value to use if optKey not definedonlyIfBoolSet
- Check the option's SOCGameOption.getBoolValue()
too;
if false, return defValue.
Do not set this parameter if the type doesn't use a boolean component.
intValue
,
or defValue if not defined in the set of options;
OTYPE_ENUM's and _ENUMBOOL's choices give an intVal in range 1 to n.isGameOptionDefined(String)
,
isGameOptionSet(String)
,
getGameOptionIntValue(Map, String)
public java.lang.String getGameOptionStringValue(java.lang.String optKey)
optKey
- A SOCGameOption
of type
OTYPE_STR
or OTYPE_STRHIDE
getStringValue
or null if not defined in this game's optionsisGameOptionDefined(String)
,
isGameOptionSet(String)
public static java.lang.String getGameOptionStringValue(java.util.Map<java.lang.String,SOCGameOption> opts, java.lang.String optKey)
opts
- A map of SOCGameOption
, or nulloptKey
- A SOCGameOption
of type
OTYPE_STR
or OTYPE_STRHIDE
getStringValue
or null if not defined in this set of optionsisGameOptionDefined(String)
,
isGameOptionSet(String)
public int getClientVersionMinRequired()
SOCVersionedItem.itemsMinimumVersion(Map)
.
For options where the minimum version changes with its current value, some
option version data is hardcoded in SOCGameOption.getMinVersion(Map)
,
executed on the server with a newer version than an older client. So, the
version returned may be too low when called at that client. The server
will let the client know if it's too old to join or create a game due
to options.
Version.versionNumber()
.public boolean isBoardReset()
public SOCBoard getBoard()
hasSeaBoard
, getBoard()
can always be cast to SOCBoardLarge
.
public SOCPlayer[] getPlayers()
protected void setPlayer(int pn, SOCPlayer pl)
pn
- the number of the playerpl
- the player data
java.lang.IllegalArgumentException
- if pl is nullpublic int getCurrentPlayerNumber()
public void setCurrentPlayerNumber(int pn)
updateAtTurn()
afterwards.
Called only at client - server instead calls endTurn()
or advanceTurn()
.
Check for gamestate OVER
after calling setCurrentPlayerNumber.
This is needed because a player can win only during their own turn;
if they reach winning points (vp_winner
or more) during another
player's turn, they don't win immediately. When it later becomes their turn,
and setCurrentPlayerNumber is called, gamestate may become OVER
.
pn
- the player number, or -1 permitted in state OVER
endTurn()
,
checkForWinner()
public int getRoundCount()
public boolean hasBuiltCity()
game option
"N7C"
.
No setter is needed: During normal game play, putPiece(SOCCity)
will
update this flag. If a client joins a game after it's started, the server will send PUTPIECE messages
for any cities already on the board.
putPiece(soc.game.SOCPlayingPiece)
(SOCCity
) has been called for a non-temporary piecepublic int getCurrentDice()
public void setCurrentDice(int dr)
dr
- the dice resultpublic int getGameState()
NEW
.
At the client, a newly joined game has state 0 until the server sends a GAMESTATE message. Keep this in mind when initializing the game's user interface.
isInitialPlacement()
,
isSpecialBuilding()
public void setGameState(int gs)
OVER
, and no playerWithWin yet determined, call checkForWinner.
For general information about what states are expected when,
please see the javadoc for NEW
.
This method is generally called at the client, due to messages from the server based on the server's complete game data.
gs
- the game statecheckForWinner()
public int getResetOldGameState() throws java.lang.IllegalStateException
java.lang.IllegalStateException
- Game state must be RESET_OLD
when called; during normal game play, oldGameState is private.public final boolean isInitialPlacement()
START1A
- START3B
and STARTS_WAITING_FOR_PICK_GOLD_RESOURCE
.
public boolean isForcingEndTurn()
endTurn()
whenever possible. Usually set if we have called forceEndTurn()
, and
forced the current player to discard randomly, and are waiting for other players
to discard in gamestate WAITING_FOR_DISCARDS
. Once all players have
discarded, the turn should be ended.
forceEndTurn()
public final boolean isPickResourceIncludingPirateFleet(int pn)
_SC_PIRI
, if true and
canPickGoldHexResources(int, SOCResourceSet)
in state WAITING_FOR_PICK_GOLD_RESOURCE
,
this player's "gold hex" free resources include victory over a pirate fleet attack at a dice roll.
pn
- Player numberpublic int getNumDevCards()
public void setNumDevCards(int nd)
nd
- the number of dev cards in the deckpublic java.util.Set<java.lang.String> getSpecialItemTypes()
SOCSpecialItem
s, if any.
Only some scenarios and expansions use Special Items.
See getSpecialItems(String)
for Special Item details and locking.
null
if nonepublic java.util.ArrayList<SOCSpecialItem> getSpecialItems(java.lang.String typeKey)
spItems
, but a separately maintained list of items.
Only some scenarios and expansions use Special Items.
Locks: This getter is not synchronized: It's assumed that the structure of Special Item lists is set up at game creation time, and not often changed. If a specific item type or access pattern requires synchronization, do so outside this class and document the details.
typeKey
- Special item type. Typically a SOCGameOption
keyname; see the SOCSpecialItem
class javadoc for details.
null
if none; will never return an empty list.
Some list items may be null
depending on the list structure created by the scenario or expansion.SOCPlayer.getSpecialItems(String)
,
getSpecialItemTypes()
public SOCSpecialItem getSpecialItem(java.lang.String typeKey, int idx)
spItems
, but a separately maintained list of items.
Only some scenarios and expansions use Special Items.
Locks: This getter is not synchronized: It's assumed that the structure of Special Item lists is set up at game creation time, and not often changed. If a specific item type or access pattern requires synchronization, do so outside this class and document the details.
typeKey
- Special item type. Typically a SOCGameOption
keyname; see the SOCSpecialItem
class javadoc for details.idx
- Index within the list of special items of that type; must be within the list's current size
null
if none of that type, or if that index is null
within the list
or is beyond the size of the listgetSpecialItem(String, int, int, int)
,
SOCPlayer.getSpecialItem(String, int)
,
SOCSpecialItem.playerPickItem(String, SOCGame, SOCPlayer, int, int)
,
SOCSpecialItem.playerSetItem(String, SOCGame, SOCPlayer, int, int, boolean)
public SOCSpecialItem getSpecialItem(java.lang.String typeKey, int gi, int pi, int pn)
gi
and pi
are used, checks game first for an existing object, and if none (null),
checks the player. Only some scenarios and expansions use Special Items.
Locks: Call takeMonitor()
before calling this method.
typeKey
- Special item type. Typically a SOCGameOption
keyname; see the SOCSpecialItem
class javadoc for details.gi
- Index within the game's list of special items of that type, or -1; must be within the list's current sizepi
- Player item index (requires pn
!= -1), or -1pn
- Owning player number, or -1
null
if none of that type or if that index is null
within the list
or is beyond the size of the listgetSpecialItem(String, int)
,
SOCPlayer.getSpecialItem(String, int)
,
SOCSpecialItem.playerPickItem(String, SOCGame, SOCPlayer, int, int)
,
SOCSpecialItem.playerSetItem(String, SOCGame, SOCPlayer, int, int, boolean)
public SOCSpecialItem setSpecialItem(java.lang.String typeKey, int idx, SOCSpecialItem itm) throws java.lang.IndexOutOfBoundsException
spItems
, but a separately maintained list of items.
Only some scenarios and expansions use Special Items.
typeKey
- Special item type. Typically a SOCGameOption
keyname; see the SOCSpecialItem
class javadoc for details. If no list with this key exists, it will be created here.idx
- Index within the list of special items of that type; if this is past the list's current size,
null
elements will be inserted as needed until idx
is a valid index
If idx
is within the list, the current element at that index will be replaced.itm
- Item object to set within the list
null
if none
java.lang.IndexOutOfBoundsException
- if idx
< 0SOCPlayer.setSpecialItem(String, int, SOCSpecialItem)
public SOCInventoryItem getPlacingItem()
PLACING_INV_ITEM
,
if any, from the most recent call to setPlacingItem(SOCInventoryItem)
.
See that method for lifecycle details.
null
public void setPlacingItem(SOCInventoryItem item)
PLACING_INV_ITEM
.
Can be set before or during that state, either for convenience or because the server must send multiple messages.
The item can't be held between turns, and is lost if not placed on the current player's turn.
Inventory Item placement methods such as placePort(SOCPlayer, int, int)
will clear the item
to null
when called in PLACING_INV_ITEM
.
item
- The item being placed, or null
to cleargetPlacingItem()
public SOCPlayer getPlayerWithLargestArmy()
public void setPlayerWithLargestArmy(SOCPlayer pl)
pl
- the playerpublic SOCPlayer getPlayerWithLongestRoad()
public void setPlayerWithLongestRoad(SOCPlayer pl)
pl
- the player, or null to clearpublic SOCPlayer getPlayerWithWin()
checkForWinner()
; there is no corresponding setter.
public void setPlayersLandHexCoordinates() throws java.lang.IllegalStateException
pl.setLandHexCoordinates
(SOCBoardLarge.getLandHexCoords()
).
If the landhex coords are null, do nothing.
To be used with hasSeaBoard
(v3 board encoding) after creating (at server)
or receiving (at client) a new board layout. So, call from
startGame()
or after SOCBoardLarge.setLandHexLayout(int[])
.
For the v1 and v2 board encodings, the land hex coordinates never change, so
SOCPlayerNumbers
knows them already.
java.lang.IllegalStateException
- if the board has the v1 or v2 encodingpublic java.lang.String gameOverMessageToPlayer(SOCPlayer pl) throws java.lang.IllegalStateException
pl
- Player to tell (may be the winner)
java.lang.IllegalStateException
- If the game state is not OVERprotected boolean advanceTurnBackwards()
forcingEndTurn
flag.
OVER
.advanceTurn()
protected boolean advanceTurn()
forcingEndTurn
flag.
OVER
.advanceTurnBackwards()
private boolean advanceTurnToSpecialBuilding()
Special Building Phase
.
This method does 1 of 4 possible things:
SPECIAL_BUILDING
)
but it's asked for: Set gameState to SPECIAL_BUILDING
.
Set specialBuildPhase_afterPlayerNumber
to current player number,
because their turn is ending.
(Special case: if current player wants to special build at start of
their own turn, set _afterPlayerNumber to PREVIOUS player.)
Then, set current player to the first player who wants to Special Build
(it may be unchanged).
SPECIAL_BUILDING
.
PLAY1
.
Set current player to the player whose turn is ending
(specialBuildPhase_afterPlayerNumber
).
In 1.1.09 and later:
SPECIAL_BUILDING
public void revealFogHiddenHex(int hexCoord, int hexType, int diceNum) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException
fog
.
Updates board.
If a SOCBoard.WATER_HEX
is revealed, updates players' legal ship edges.
hexCoord
- Coordinate of the hex to revealhexType
- Revealed hex type, same value as SOCBoard.getHexTypeFromCoord(int)
,
from SOCBoardLarge.revealFogHiddenHexPrep(int)
diceNum
- Revealed hex dice number, same value as SOCBoard.getNumberOnHexFromCoord(int)
, or 0
java.lang.IllegalArgumentException
- if hexCoord isn't currently a FOG_HEX
java.lang.IllegalStateException
- if ! game.hasSeaBoard
public boolean canRemovePort(SOCPlayer pl, int edge) throws java.lang.NullPointerException
_SC_FTRI
,
can a "gift" port be removed from this edge? hasSeaBoard
is true
PLACING_SHIP
, PLACING_FREE_ROAD1
or PLACING_FREE_ROAD2
edge
has a port
SOCBoardLarge.getPlayerExcludedLandAreas()
SOCGameOption.K_SC_FTRI
is set.
pl
- Player who would remove the portedge
- Port's edge coordinate
pl
java.lang.NullPointerException
- if pl
is nullSOCBoardLarge.canRemovePort(int)
,
removePort(SOCPlayer, int)
,
canPlacePort(SOCPlayer, int)
public SOCInventoryItem removePort(SOCPlayer pl, int edge) throws java.lang.UnsupportedOperationException, java.lang.NullPointerException
_SC_FTRI
, remove a "gift" port
at this edge to be placed elsewhere. Assumes canRemovePort(SOCPlayer, int)
has already
been called to validate player, edge, and game state.
This method will remove the port from the board. At server it will also either add it to the
player's inventory or set the game's placingItem field; change the game state if placing
it immediately; and then fire SOCScenarioPlayerEvent.REMOVED_TRADE_PORT
.
At the server: Not called directly; called only from other game/player methods.
Ports are currently removed only by a player's adjacent ship placement, so
SOCPlayer.putPiece(SOCPlayingPiece, boolean)
would eventually call this
method if canRemovePort(..)
. The server calls
pl.getPortMovePotentialLocations(false)
to determine if immediate placement is possible and thus required.
In the PlayerEvent handler or after this method returns, check
getGameState()
== PLACING_INV_ITEM
to see whether the port must immediately
be placed, or was instead added to the player's inventory.
At the client: Call this method to update the board data and player port flags.
The server will send other messages about game state and player inventory. If those set
getGameState()
to PLACING_INV_ITEM
, the current player must choose a location for
port placement: Call
SOCPlayer.getPortMovePotentialLocations(true)
to present options to the user. The user will choose an edge and send a request to the server. The server
will validate and if valid call placePort(int)
and send updated status to the game's clients.
pl
- Player who is removing the port: Must be current player. Ignored at client, null
is okay there.edge
- Port's edge coordinate
SOCInventoryItem.itype
in range
-WOOD_PORT
to -MISC_PORT
java.lang.UnsupportedOperationException
- if ! hasSeaBoard
java.lang.NullPointerException
- if pl
is null at serverpublic boolean canPlacePort(SOCPlayer pl, int edge) throws java.lang.NullPointerException
_SC_FTRI
,
can a "gift" port be placed at this edge? hasSeaBoard
is true
SOCBoardLarge.isEdgeCoastline(int)
SOCGameOption.K_SC_FTRI
is set. Does not check getGameState()
.
pl
- Player who would placeedge
- Edge where a port is wanted; coordinate not checked for validity.
SOCPlayer.getPortMovePotentialLocations(boolean)
can calculate edges that
meet all conditions for canPlacePort
.
java.lang.NullPointerException
- if pl
is nullcanRemovePort(SOCPlayer, int)
,
placePort(SOCPlayer, int, int)
public int placePort(int edge) throws java.lang.IllegalStateException, java.lang.IllegalArgumentException, java.lang.UnsupportedOperationException
_SC_FTRI
in game state PLACING_INV_ITEM
, place
the "gift" port at this edge. The port in getPlacingItem()
will be placed. State becomes previous state
(PLAY1
or SPECIAL_BUILDING
). Calls setPlacingItem(null)
.
Assumes canPlacePort(SOCPlayer, int)
has already been called to validate.
edge
- An available coastal edge adjacent to pl
's settlement or city,
which should be checked with canPlacePort(SOCPlayer, int)
MISC_PORT
to WOOD_PORT
)
java.lang.IllegalStateException
- if not state PLACING_INV_ITEM
, or (internal error) placingItem
is null
java.lang.IllegalArgumentException
- if ptype
is out of range, or
if edge
is not coastal (is between 2 land hexes or 2 water hexes)
java.lang.UnsupportedOperationException
- if ! hasSeaBoard
placePort(SOCPlayer, int, int)
,
removePort(SOCPlayer, int)
public void placePort(SOCPlayer pl, int ptype, int edge) throws java.lang.IllegalArgumentException, java.lang.NullPointerException, java.lang.UnsupportedOperationException
_SC_FTRI
, place a "gift" port at this edge.
Assumes canPlacePort(SOCPlayer, int)
has already been called to validate.
Any port placement in state PLACING_INV_ITEM
calls setPlacingItem(null)
.
pl
- Player who is placingptype
- The type of port (in range MISC_PORT
to WOOD_PORT
)edge
- An available coastal edge adjacent to pl
's settlement or city,
which should be checked with canPlacePort(SOCPlayer, int)
java.lang.IllegalArgumentException
- if ptype
is out of range, or
if edge
is not coastal (is between 2 land hexes or 2 water hexes)
java.lang.NullPointerException
- if pl
is null
java.lang.UnsupportedOperationException
- if ! hasSeaBoard
placePort(int)
,
removePort(SOCPlayer, int)
public boolean canPlaceShip(SOCPlayer pl, int shipEdge)
SOCPlayer.isPotentialShip(int)
and must not be adjacent to SOCBoardLarge.getPirateHex()
.
Does not check game state, resources, or pieces remaining.
pl
- PlayershipEdge
- Edge to place a ship
canMoveShip(int, int, int)
,
SOCPlayer.getNumPieces(int)
public void putPiece(SOCPlayingPiece pp)
checkForWinner()
; gamestate may become OVER
.
For example, if game state when called is START2A
(or START3A
in
some scenarios), this is their final initial settlement, so it gives the player
some resources.
If hasSeaBoard
and _SC_FOG
,
you should check for gamestate WAITING_FOR_PICK_GOLD_RESOURCE
after calling, to see if they placed next to a gold hex revealed from fog
(see paragraph below).
SOCBoard.putPiece(SOCPlayingPiece)
and each player's
SOCPlayer.putPiece(pp, false)
.
Updates longest road if necessary.
Calls advanceTurnStateAfterPutPiece()
.
(player.putPiece may also score Special Victory Point(s), see below.)
If the piece is a city, putPiece removes the settlement there.
If the piece is a settlement, and its owning player has their SOCFortress
there
(scenario _SC_PIRI
), putPiece removes the defeated fortress.
If placing this piece reveals any fog hex
, that happens first of all.
Hex is revealed (at server only) via putPieceCommon_checkFogHexes(int[], boolean)
.
Current player gets a resource from each revealed hex, and a scenario player event is fired.
See that method's javadoc for details.
putPiece's caller should check SOCPlayer.getNeedToPickGoldHexResources()
!= 0.
Revealing a gold hex from fog will set that player field and also
sets gamestate to WAITING_FOR_PICK_GOLD_RESOURCE
.
Calls checkForWinner()
and otherwise advances turn or state.
After the final initial road or ship placement, clears all players' potential settlements by
calling advanceTurnStateAfterPutPiece()
which calls updateAtGameFirstTurn()
.
SOCPlayer.isPotentialRoad(int)
and SOCPlayer.getNumPieces(int)
to verify pp before calling this method, and also check
getGameState()
to ensure that piece type can be placed now.SOCPlayer.canPlaceSettlement(int)
to check potentials and other game conditions.canPlaceShip(SOCPlayer, int)
to check
the potentials and pirate ship location.
large sea board
, placing
a settlement in a new Land Area may award the player a Special Victory Point (SVP).
This method will increment SOCPlayer.getSpecialVP()
and set the player's SOCScenarioPlayerEvent.SVP_SETTLED_ANY_NEW_LANDAREA
flag.
Some scenarios use extra initial pieces in fixed locations, placed in
SOCBoardLargeAtServer.startGame_putInitPieces. To prevent the state or current player from
advancing, temporarily set game state READY
before calling putPiece for these.
During isDebugFreePlacement()
, the gamestate is not changed,
unless the current player gains enough points to win.
pp
- the piece to put on the board; coordinates are not checked for validity, see "valid placements" noteprivate void putPieceCommon(SOCPlayingPiece pp, boolean isTempPiece)
putPiece(SOCPlayingPiece)
and putTempPiece(SOCPlayingPiece)
.
See putPiece(SOCPlayingPiece)
javadoc for more information on what putPieceCommon does.
pp
- The piece to put on the board; coordinates are not checked for validityisTempPiece
- Is this a temporary piece? If so, do not change current
player or gamestate, or call our SOCScenarioEventListener
.private final void putPieceCommon_checkFogHexes(int[] hexCoords, boolean initialSettlement)
SOCScenarioGameEvent.SGE_FOG_HEX_REVEALED
and gives the current player that resource (if not desert or water or gold).
The server should send the clients messages to reveal the hex
and give the resource to that player.
If gold is revealed, calls
currentPlayer.setNeedToPickGoldHexResources(numGoldHexes)
.
Called only at server, only when hasSeaBoard
.
During initial placement, placing a settlement could reveal up to 3 hexes.
hexCoords
- Hex coordinates to check type for SOCBoardLarge.FOG_HEX
initialSettlement
- Are we checking for initial settlement placement?
If so, keep checking after finding a fog hex.private boolean advanceTurnStateAfterPutPiece()
Called at server and at each client by putPieceCommon(SOCPlayingPiece, boolean)
.
At clients, the PUTPIECE message that triggers that call will soon be
followed by a GAMESTATE message to confirm the new state.
In START2B
or START3B
after the last initial road/ship placement, calls
updateAtGameFirstTurn()
and then updateAtTurn()
.
Also used in forceEndTurn()
to continue the game
after a cancelled piece placement in START1A
..START3B
.
If the current player number changes here, isForcingEndTurn()
is cleared.
This method is not called after placing a SOCInventoryItem
on the board, which
happens only with some scenario options such as _SC_FTRI
.
OVER
.public void putTempPiece(SOCPlayingPiece pp)
pp
- the piece to put on the boardundoPutTempPiece(SOCPlayingPiece)
,
saveLargestArmyState()
public SOCShip canMoveShip(int pn, int fromEdge)
PLAY1
.
Only the ship at the newer end of an open trade route can be moved. So, to move a ship, one of its end nodes must be clear: No settlement or city, and no other adjacent ship on the other side of the node.
You cannot place a ship, and then move the same ship, during the same turn. You cannot move a ship from an edge of the pirate ship's hex.
Trade routes can branch, so it may be that more than one ship could be moved. The game limits players to one move per turn.
pn
- Player numberfromEdge
- Edge coordinate to move the ship from; must contain this player's ship
canMoveShip(int, int, int)
public SOCShip canMoveShip(int pn, int fromEdge, int toEdge)
PLAY1
.
Only the ship at the newer end of an open trade route can be moved. So, to move a ship, one of fromEdge's end nodes must be clear: No settlement or city, and no other adjacent ship on the other side of the node.
The new location toEdge must also be a potential ship location,
even if fromEdge was unoccupied; calls
pn.isPotentialShipMoveTo(toEdge, fromEdge)
to check that.
You cannot move a ship to or from an edge of the pirate ship's hex.
Trade routes can branch, so it may be that more than one ship could be moved. The game limits players to one move per turn.
Scenario option _SC_PIRI
:
Ship movement options are limited, because the route can't branch
and only a few sea edges are legal for placement.
pn
- Player numberfromEdge
- Edge coordinate to move the ship from; must contain this player's ship.toEdge
- Edge coordinate to move to; must be different than fromEdge.
Checks players[pn].isPotentialShip(toEdge)
.
canMoveShip(int, int)
,
moveShip(SOCShip, int)
public void moveShip(SOCShip sh, int toEdge)
checkForWinner()
; gamestate may become OVER
if a player gets the longest trade route.
Calls undoPutPieceCommon(sh, false)
and putPiece(SOCPlayingPiece)
.
Updates longest trade route.
Not for use with temporary pieces.
Note: Because sh and toEdge
are not checked for validity, please call
canMoveShip(int, int, int)
before calling this method.
The call to putPiece incorrectly adds the moved ship's new location to placedShipsThisTurn, but since we can only move 1 ship per turn, the add is harmless.
During isDebugFreePlacement()
, the gamestate is not changed,
unless the current player gains enough points to win.
Scenario option _SC_FOG
:
moveShip's caller should check SOCPlayer.getNeedToPickGoldHexResources()
!= 0.
Revealing a gold hex from fog will set that player field and also
sets gamestate to WAITING_FOR_PICK_GOLD_RESOURCE
.
sh
- the ship to move on the board; its coordinate must be
the edge to move from. Must not be a temporary ship.toEdge
- Edge coordinate to move topublic void removeShip(SOCShip sh)
_SC_PIRI
by attackPirateFortress(SOCShip)
and at the client.
Calls undoPutPieceCommon(sh, false)
.
Not for use with temporary pieces.
sh
- the ship to removeprotected void undoPutPieceCommon(SOCPlayingPiece pp, boolean isTempPiece)
If a ship is removed in scenario _SC_PIRI
, makes sure its player's
SOCPlayer.getNumWarships()
is never more than the number of their ships on the board.
pp
- the piece to remove from the boardisTempPiece
- Is this a temporary piece? If so, do not call the
game's SOCScenarioEventListener
.public void undoPutTempPiece(SOCPlayingPiece pp)
pp
- the piece to remove from the boardundoPutInitSettlement(SOCPlayingPiece)
,
restoreLargestArmyState()
public void undoPutInitSettlement(SOCPlayingPiece pp)
undoPutTempPiece(SOCPlayingPiece)
instead).
pp
- the piece to remove from the boardcanCancelBuildPiece(int)
public void startGame()
START1A
.
Updates lastActionTime
.
Called only at server, not client. For a method called during game start
at server and clients, see updateAtBoardLayout()
.
Some scenarios require other methods to finish setting up the game; call them in this order before any other board or game methods:
startGame()
SOCPlayer.setRestrictedLegalShips(int[])
SOCBoardLargeAtServer.startGame_putInitPieces(SOCGame)
private final void startGame_setupDevCards()
startGame()
, fill and shuffle the development card deck.
devCardDeck
contents are based on game options and number of players.
public void setFirstPlayer(int pn)
pn
and on vacant seats, also recalculates lastPlayer.
pn
- the seat number of the first player, or -1 if not set yetpublic int getFirstPlayer()
public boolean canEndTurn(int pn)
In some states, the current player can't end their turn yet (such as needing to move the robber, or choose resources for a year-of-plenty card, or discard if a 7 is rolled).
pn
- player number of the player who wants to end the turn
PLAY1
or SPECIAL_BUILDING
)endTurn()
,
forceEndTurn()
public void endTurn()
OVER
after calling endTurn.
endTurn() is called only at server - client instead calls
setCurrentPlayerNumber(int)
, then client calls updateAtTurn()
.
endTurn() also calls updateAtTurn()
.
endTurn() is not called before the first dice roll.
endTurn() will call updateAtTurn()
.
In the 6-player game, calling endTurn() may begin or
continue the Special Building Phase
.
Does not clear any player's SOCPlayer.hasAskedSpecialBuild()
flag.
The winner check is needed because a player can win only
during their own turn; if they reach winning points (vp_winner
or more) during another player's turn, they must wait.
So, this method calls checkForWinner()
if the new current player has
vp_winner
or if the game's hasScenarioWinCondition
is true.
In 1.1.09 and later, player is allowed to Special Build at start of their
own turn, only if they haven't yet rolled or played a dev card.
To do so, call askSpecialBuild(int, boolean)
and then endTurn()
.
checkForWinner()
,
forceEndTurn()
,
isForcingEndTurn()
public void updateAtBoardLayout()
Called at server and clients during game startup, immediately after all board-layout methods
and related game methods like setPlayersLandHexCoordinates()
have been called.
When called at the client, the board layout is set, but neither the gameState nor the players' potential settlements have been sent from the server yet. Even if the client joined after game start, this method will still be called at that client.
Currently used only for Special Item placement by the _SC_WOND
scenario,
where (1 + maxPlayers
) wonders are available for the players to choose from, held in game
Special Item indexes 1 - n. Because of this limited and non-dynamic use, it's easier to set them up in code
here than to create, send, and parse messages with all details of the game's Special Items. This method
sets up the Special Items as they are during game start. If the game has started before a client joins,
other messages sent during the join will then update Special Item info in case they've changed since
game start.
private void updateAtGameFirstTurn()
SOCPlayer.clearPotentialSettlements()
hasSeaBoard
, check board for Added Layout Part "AL"
for node lists that
become legal locations for settlements after initial placement, and make them legal now.
(This Added Layout Part is rarely used, currently is in scenario SC_WOND
.)
If any node has an adjacent settlement or city, that node won't be made legal.
Calls SOCBoardLarge.addLegalNodes(int[], int)
for each referenced node list.
Does not adjust players' potential settlement locations, because at the start of a game,
players won't have roads to any node 2 away from their settlements, so they will have no
new potential settlements yet. Does call each player's
pl.addLegalSettlement(coord, true)
.
Called at server and client by advanceTurnStateAfterPutPiece()
, before updateAtTurn()
.
Before v2.0.00, this was in various places. The players' potential settlements were cleared by
putPiece
after placing their last initial road. If a bot's initial placement turn was
forced to end, their potentials might not have been cleared.
public void updateAtTurn()
May be called during initial placement.
(Game methods don't call during this time, but the server sends each client
a message to call updateAtTurn whenever the current player changes.)
Is called at the end of initial placement, before the first player's first roll.
On the 6-player board, is called at the start of
each player's Special Building Phase
.
SOCPlayer.updateAtTurn()
SOCPlayer.updateAtOurTurn()
,
to mark their new dev cards as old and clear other flags
PLAY
, increment turnCount (and roundCount if necessary).
These include the current turn; they both are 1 during the first player's first turn.
setGameState(int)
and setCurrentPlayerNumber(int)
.
At server, this is called from within endTurn()
.
public SOCForceEndTurnResult forceEndTurn() throws java.lang.IllegalStateException
PLAY1
, but does not call endTurn()
.
If player was placing for SPECIAL_BUILDING
, will cancel that
placement and set state to SPECIAL_BUILDING
.
Called by controller of game (server). The results are then reported to the other players as if the player had manually taken actions to end their turn. (Resources are shown as returned to player's hand from Cancel Build Road, etc.)
Since only the server calls endTurn()
, this method does not do so.
This method also does not check if a board-reset vote is in progress,
because endTurn will unconditionally cancel such a vote.
Does not clear any player's SOCPlayer.hasAskedSpecialBuild()
flag;
do that at the server, and report it out to other players.
After calling forceEndTurn, usually the gameState will be PLAY1
,
and the caller should call endTurn()
. The isForcingEndTurn()
flag is also set. The return value in this case is
FORCE_ENDTURN_NONE
.
The state in this case could also be SPECIAL_BUILDING
.
Exceptions (where caller should not call endTurn) are these return types:
SOCForceEndTurnResult.FORCE_ENDTURN_RSRC_DISCARD_WAIT
- Have forced current player to discard or gain resources randomly,
must now wait for other players to pick their discards or gains.
gameState is WAITING_FOR_DISCARDS
, current player
as yet unchanged.
SOCForceEndTurnResult.FORCE_ENDTURN_SKIP_START_ADV
- During initial placement, have skipped placement of
a player's first or third settlement or road. gameState is
START1A
or START3A
, current player has changed.
Game's first or last player may have changed.
SOCForceEndTurnResult.FORCE_ENDTURN_SKIP_START_ADVBACK
- During initial placement, have skipped placement of
a player's second settlement or road. (Or, final player's
first _and_ second settlement or road.)
gameState is START2A
, current player has changed.
Game's first or last player may have changed.
Note that for the very last initial road placed, during normal
gameplay, that player continues by rolling the first turn's dice.
To force skipping such a placement, the caller should call endTurn()
to change the current player. This is indicated by
SOCForceEndTurnResult.FORCE_ENDTURN_SKIP_START_TURN
.
See also SOCGameHandler.forceEndGameTurn, SOCGameHandler.endGameTurnOrForce.
SOCForceEndTurnResult.FORCE_ENDTURN_NONE
SOCForceEndTurnResult.FORCE_ENDTURN_SKIP_START_ADV
SOCForceEndTurnResult.FORCE_ENDTURN_SKIP_START_ADVBACK
SOCForceEndTurnResult.FORCE_ENDTURN_SKIP_START_TURN
SOCForceEndTurnResult.FORCE_ENDTURN_RSRC_RET_UNPLACE
SOCForceEndTurnResult.FORCE_ENDTURN_UNPLACE_ROBBER
SOCForceEndTurnResult.FORCE_ENDTURN_RSRC_DISCARD
SOCForceEndTurnResult.FORCE_ENDTURN_RSRC_DISCARD_WAIT
SOCForceEndTurnResult.FORCE_ENDTURN_LOST_CHOICE
java.lang.IllegalStateException
- if game is not active
(gamestate < START1A
or >= OVER
)canEndTurn(int)
,
endTurn()
private SOCForceEndTurnResult forceEndTurnStartState(boolean advTurnForward)
currentPlayerNumber
.
Handles START1A
- START3B
and STARTS_WAITING_FOR_PICK_GOLD_RESOURCE
.
See forceEndTurn()
for description.
Check for gamestate >= OVER
after calling this method,
in case all players have left the game.
advTurnForward
- Should the next player be normal (placing first settlement),
or backwards (placing second settlement)?
SOCForceEndTurnResult.FORCE_ENDTURN_SKIP_START_ADV
,
SOCForceEndTurnResult.FORCE_ENDTURN_SKIP_START_ADVBACK
,
or SOCForceEndTurnResult.FORCE_ENDTURN_SKIP_START_TURN
.private SOCForceEndTurnResult forceEndTurnChkDiscardOrGain(int pn, boolean isDiscard)
discard(int, SOCResourceSet)
,
or gain random resources by calling pickGoldHexResources(int, SOCResourceSet)
.
Then look at other players' hand size. If no one else must discard or pick,
ready to end turn, set state PLAY1
.
Otherwise, must wait for them; if so,
set game state (WAITING_FOR_DISCARDS
or WAITING_FOR_PICK_GOLD_RESOURCE
).
When called, assumes isForcingEndTurn()
flag is already set.
Not called for STARTS_WAITING_FOR_PICK_GOLD_RESOURCE
,
which has different result types and doesn't need to check other players.
pn
- Player number to force to randomly discard or gainisDiscard
- True to discard resources, false to gain
SOCForceEndTurnResult.FORCE_ENDTURN_RSRC_DISCARD
or SOCForceEndTurnResult.FORCE_ENDTURN_RSRC_DISCARD_WAIT
.playerDiscardOrGainRandom(int, boolean)
public static void discardOrGainPickRandom(SOCResourceSet fromHand, int numToPick, boolean isDiscard, SOCResourceSet picks, java.util.Random rand) throws java.lang.IllegalArgumentException
fromHand
- Discard from this set, or gain to add to this setnumToPick
- This many must be discarded or gainedisDiscard
- True to discard resources, false to gainpicks
- Add the picked resources to this set (typically new and empty when called)rand
- Source of random
java.lang.IllegalArgumentException
- if isDiscard and
numDiscards > fromHand.getKnownTotal()
public SOCResourceSet playerDiscardOrGainRandom(int pn, boolean isDiscard) throws java.lang.IllegalStateException
On return, gameState will be:
WAITING_FOR_DISCARDS
if other players still must discard
WAITING_FOR_PICK_GOLD_RESOURCE
if other players still must pick their resources
PLAY1
if everyone has picked (gained) resources
PLAY1
if everyone has discarded, and isForcingEndTurn()
is set
PLACING_ROBBER
if everyone has discarded, and isForcingEndTurn()
is not set
playerDiscardRandom(..)
.
pn
- Player number to discard; player must must need to discard,
must not be current player (use forceEndTurn()
for that)isDiscard
- True to discard resources, false to gain (pick from gold hex)
java.lang.IllegalStateException
- If the gameState isn't WAITING_FOR_DISCARDS
or WAITING_FOR_PICK_GOLD_RESOURCE
,
or if pn's SOCPlayer.getNeedToDiscard()
is false
and their SOCPlayer.getNeedToPickGoldHexResources()
== 0,
or if pn == currentPlayer.public boolean canRollDice(int pn)
pn
- player number of the player who wants to roll
public SOCGame.RollResult rollDice()
getGameState()
will usually become PLAY1
.
If the board contains gold hexes, it may become WAITING_FOR_PICK_GOLD_RESOURCE
.
For 7, gameState becomes either WAITING_FOR_DISCARDS
,
WAITING_FOR_ROBBER_OR_PIRATE
, or PLACING_ROBBER
.
For scenario option SOCGameOption.K_SC_CLVI
, calls
SOCBoardLarge.distributeClothFromRoll(SOCGame, int)
.
Cloth are worth VP, so check for game state OVER
if results include SOCGame.RollResult.cloth
.
For scenario option SOCGameOption.K_SC_PIRI
, calls
SOCBoardLarge.movePirateHexAlongPath(int)
.
Check SOCGame.RollResult.sc_piri_fleetAttackVictim
and SOCGame.RollResult.sc_piri_fleetAttackRsrcs
.
Note that if player's warships are stronger than the pirate fleet, sc_piri_loot will contain
SOCResourceConstants.GOLD_LOCAL
, and that player's SOCPlayer.setNeedToPickGoldHexResources(int)
will be set to include the free pick.
Called at server only.
SOCGame.RollResult.cloth
. The game reuses the same instance
each turn, so its field contents will change when rollDice()
is called again.private final void rollDice_update7gameState()
gameState
:
Always WAITING_FOR_DISCARDS
if any SOCPlayer.getResources()
total > 7.
Otherwise PLACING_ROBBER
, WAITING_FOR_ROBBER_OR_PIRATE
, or for
scenario option _SC_PIRI
, WAITING_FOR_ROB_CHOOSE_PLAYER
or PLAY1
.
For state WAITING_FOR_DISCARDS
, also sets SOCPlayer.setNeedToDiscard(boolean)
.
For state PLACING_ROBBER
, also clears robberyWithPirateNotRobber
.
For _SC_PIRI, sets currentRoll.sc_robPossibleVictims.
This is a separate method from rollDice()
because for _SC_PIRI, if a player wins against
the pirate fleet, this "7 update" happens only after they pick and gain their free resource.
private SOCResourceSet getResourcesGainedFromRoll(SOCPlayer player, int roll)
rollDice()
, figure out what resources a player gets on a given roll,
based on the hexes adjacent to the player's settlements and cities
and based on the robber's position.
If hasSeaBoard
, and the player's adjacent to a
SOCBoardLarge.GOLD_HEX
, the gold-hex resources they must pick
are returned as SOCResourceConstants.GOLD_LOCAL
.
player
- the playerroll
- the total number rolled on the dice
private final void getResourcesGainedFromRollPieces(int roll, SOCResourceSet resources, SOCResourceSet missedResources, int robberHex, java.util.Collection<? extends SOCPlayingPiece> sEnum, int incr)
getResourcesGainedFromRoll(SOCPlayer, int)
.
If hasSeaBoard
, and the player's adjacent to a
SOCBoardLarge.GOLD_HEX
, the gold-hex resources they must pick
are returned as SOCResourceConstants.GOLD_LOCAL
.
roll
- the total number rolled on the diceresources
- Add new resources to this setrobberHex
- Robber's position, from SOCBoard.getRobberHex()
sEnum
- Enumeration of a type of the player's SOCPlayingPiece
s;
should be either SOCSettlement
s or SOCCity
sincr
- Add this many resources (1 or 2) per playing piecepublic boolean canDiscard(int pn, SOCResourceSet rs)
pn
- the number of the player that is discardingrs
- the resources that the player is discarding
discard(int, SOCResourceSet)
public void discard(int pn, SOCResourceSet rs)
WAITING_FOR_DISCARDS
or WAITING_FOR_ROBBER_OR_PIRATE
or PLACING_ROBBER
accordingly.
Assumes canDiscard(int, SOCResourceSet)
already called to validate.
In scenario option _SC_PIRI, there is no robber
to move, but the player will choose their robbery victim
(state WAITING_FOR_ROB_CHOOSE_PLAYER
) after any discards.
If there are no possible victims, state becomes PLAY1
.
Check for those game states after calling this method.
Special case:
If isForcingEndTurn()
, and no one else needs to discard,
gameState becomes PLAY1
but the caller must call
endTurn()
as soon as possible.
pn
- the number of the playerrs
- the resources that are being discardedpublic boolean canPickGoldHexResources(int pn, SOCResourceSet rs)
getTotal()
must == SOCPlayer.getNeedToPickGoldHexResources()
.
Game state must be WAITING_FOR_PICK_GOLD_RESOURCE
or STARTS_WAITING_FOR_PICK_GOLD_RESOURCE
.
pn
- the number of the player that is pickingrs
- the resources that the player is picking
pickGoldHexResources(int, SOCResourceSet)
public void pickGoldHexResources(int pn, SOCResourceSet rs)
WAITING_FOR_PICK_GOLD_RESOURCE
or oldGameState (usually PLAY1
) accordingly.
(Or, during initial placement, usually START2B
or START3B
, after initial settlement at gold.)
During normal play, the oldGameState might sometimes be PLACING_FREE_ROAD2
or SPECIAL_BUILDING
.
Assumes canPickGoldHexResources(int, SOCResourceSet)
already called to validate.
During initial placement from STARTS_WAITING_FOR_PICK_GOLD_RESOURCE
,
calls advanceTurnStateAfterPutPiece()
.
the current player won't change if the gold pick was for the player's final initial settlement.
If the gold pick was for placing a road or ship that revealed a gold hex from fog
,
the player will probably change here, since the player changes after most inital roads or ships.
Also used in scenario SC_PIRI
after winning a pirate fleet battle at dice roll.
Called at server only; clients will instead get SOCPlayerElement messages
for the resources picked and the "need to pick" flag, and will call
SOCPlayer.getResources()
.add and SOCPlayer.setNeedToPickGoldHexResources(int)
.
pn
- the number of the playerrs
- the resources that are being pickedpublic boolean canChooseMovePirate()
hasSeaBoard
.
_SC_CLVI
, the player
must have SOCScenarioPlayerEvent.CLOTH_TRADE_ESTABLISHED_VILLAGE
.
_SC_PIRI
has a pirate fleet
and no robber; this scenario is checked in rollDice()
and does not call
canChooseMovePirate()
.
_SC_WOND
does not use the pirate ship.
WAITING_FOR_ROBBER_OR_PIRATE
,
chooseMovePirate(boolean)
public void chooseMovePirate(boolean pirateNotRobber) throws java.lang.IllegalStateException
WAITING_FOR_ROBBER_OR_PIRATE
.
Game state becomes PLACING_ROBBER
or PLACING_PIRATE
.
getRobberyPirateFlag()
is set or cleared accordingly.
Called from server's game handler and also from forceEndTurn()
if necessary.
pirateNotRobber
- True to move pirate, false to move robber
java.lang.IllegalStateException
- if gameState != WAITING_FOR_ROBBER_OR_PIRATE
public boolean canMoveRobber(int pn, int co)
game option
RD is set to true
("Robber can't return to the desert").
Must be current player. Game state must be PLACING_ROBBER
.
pn
- the number of the player that is moving the robberco
- the new robber hex coordinates; not validated
moveRobber(int, int)
,
canMovePirate(int, int)
public SOCMoveRobberResult moveRobber(int pn, int rh) throws java.lang.IllegalArgumentException
Called only at server. Client gets messages with results of the move, and
calls SOCBoard.setRobberHex(int, boolean)
.
If no victims (players to possibly steal from): State becomes oldGameState.
If just one victim: call stealFromPlayer, State becomes oldGameState.
If multiple possible victims: Player must choose a victim: State becomes WAITING_FOR_ROB_CHOOSE_PLAYER
.
Assumes canMoveRobber(int, int)
has been called already to validate the move.
Assumes gameState PLACING_ROBBER
.
pn
- the number of the player that is moving the robberrh
- the robber's new hex coordinate; must be > 0, not validated beyond that
java.lang.IllegalArgumentException
- if rh <= 0public boolean canMovePirate(int pn, int hco)
SOCBoardLarge.isHexOnWater(int)
.
Must be different from current pirate coordinates.
Game must have hasSeaBoard
.
Must be current player. Game state must be PLACING_PIRATE
.
For scenario option _SC_CLVI
, the player
must have SOCScenarioPlayerEvent.CLOTH_TRADE_ESTABLISHED_VILLAGE
.
pn
- the number of the player that is moving the piratehco
- the new pirate hex coordinates; will check for a water hex
movePirate(int, int)
,
canMoveRobber(int, int)
public SOCMoveRobberResult movePirate(int pn, int ph) throws java.lang.IllegalArgumentException
robberResult
field.
Called only at server. Client gets messages with results of the move, and
calls SOCBoardLarge.setPirateHex(int, boolean)
.
If no victims (players to possibly steal from): State becomes oldGameState.
If multiple possible victims: Player must choose a victim: State becomes WAITING_FOR_ROB_CHOOSE_PLAYER
.
Once chosen, call choosePlayerForRobbery(int)
to choose a victim.
If just one victim: call stealFromPlayer, State becomes oldGameState.
If cloth robbery gives player enough VP to win, sets gameState to OVER
.
Or: If just one victim but canChooseRobClothOrResource(int)
,
state becomes WAITING_FOR_ROB_CLOTH_OR_RESOURCE
.
Once chosen, call stealFromPlayer(int, boolean)
.
Assumes canMovePirate(int, int)
has been called already to validate the move.
Assumes gameState PLACING_PIRATE
.
In game scenario _SC_PIRI
, the pirate is moved not by the player,
but by the game at every dice roll. See movePirate(int, int, int)
instead of this method.
pn
- the number of the player that is moving the pirate shipph
- the pirate's new hex coordinate; should be a water hex
In scenario _SC_PIRI only, might contain SOCResourceConstants.GOLD_LOCAL
if the player wins; see movePirate(int, int, int)
for details.
java.lang.IllegalArgumentException
- if ph <= 0private SOCMoveRobberResult movePirate(int pn, int ph, int pirFleetStrength) throws java.lang.IllegalArgumentException
rollDice()
in scenario _SC_PIRI
.
See movePirate(int, int)
for method javadocs in "normal" operation (not _SC_PIRI
).
In game scenario _SC_PIRI
, the pirate is moved not by the player,
but by the game at every dice roll. See SOCBoardLarge.movePirateHexAlongPath(int)
and stealFromPlayerPirateFleet(int, int)
for details.
SOCMoveRobberResult.victims
will be the player(s) having a settlement/city adjacent to
the new pirate hex
SOCMoveRobberResult.sc_piri_loot
will be set to the robbed resource(s), if any
sc_piri_loot
will contain SOCResourceConstants.GOLD_LOCAL
SOCPlayer.setNeedToPickGoldHexResources(int)
rollDice()
will set the game state and that player flag
pn
- the number of the player that is moving the pirate shipph
- the pirate's new hex coordinate; should be a water hexpirFleetStrength
- Pirate fleet strength, or -1 if not scenario _SC_PIRI
movePirate(int, int)
java.lang.IllegalArgumentException
- if ph
< 0public boolean canChoosePlayer(int pn)
WAITING_FOR_ROB_CHOOSE_PLAYER
or WAITING_FOR_PICK_GOLD_RESOURCE
.
To choose the player and rob, call choosePlayerForRobbery(int)
.
pn
- the number of the player to rob, or -1 to rob no one
in game scenario _SC_PIRI as described in
WAITING_FOR_ROB_CHOOSE_PLAYER
.
getRobberyPirateFlag()
,
getPossibleVictims()
,
canChooseRobClothOrResource(int)
,
stealFromPlayer(int, boolean)
public int choosePlayerForRobbery(int pn)
canChooseRobClothOrResource(int)
to check that.
Calls stealFromPlayer(int, boolean)
to perform the robbery and set gameState back to oldGameState.
If cloth robbery gives player enough VP to win, sets gameState to OVER
.
If they must choose what to steal, instead sets gameState to WAITING_FOR_ROB_CLOTH_OR_RESOURCE
.
Once chosen, call stealFromPlayer(int, boolean)
.
Does not validate pn; assumes canChoosePlayer(int)
has been called already.
In scenario option _SC_PIRI, the player can
choose to not steal from anyone after rolling a 7.
In that case, call with pn == -1.
State becomes PLAY1
.
pn
- the number of the player being robbed
SOCResourceConstants
, or 0
if must choose first (state WAITING_FOR_ROB_CLOTH_OR_RESOURCE
),
or SOCResourceConstants.CLOTH_STOLEN_LOCAL
for cloth.public boolean canChooseRobClothOrResource(int pn)
hasSeaBoard
and when robbing with the pirate
(getRobberyPirateFlag()
). True only if the player has
both cloth and resources.
Assumes canChoosePlayer(int)
has been called already.
Used with scenario option _SC_CLVI
.
pn
- Player number to check
public SOCShip canAttackPirateFortress()
attackPirateFortress(SOCShip)
.
To attack, game state must be PLAY1
.
The current player must have a SOCPlayer.getFortress()
!= null
,
and a ship on an edge adjacent to that SOCFortress
's node.
Used with scenario option _SC_PIRI
.
SOCFortress
, or null
if they can't attackpublic int[] attackPirateFortress(SOCShip adjacent)
canAttackPirateFortress()
called first, to validate and get the adjacent
ship.
Before calling, call SOCPlayer.getFortress()
so that you can get its new strength afterwards,
and call SOCPlayer.getNumWarships()
in case the player doesn't win and the ship they lose is a warship.
The player's fleet strength (SOCPlayer.getNumWarships()
) will be compared to a pirate defense
strength of 1 to 6 (random). Players lose 1 ship on a tie, 2 ships if defeated by the pirates.
If the player wins, the SOCFortress
strength is reduced by 1. After several wins, its strength is 0 and
the fortress is recaptured, becoming a SOCSettlement
for the player. This method will fire a
SOCScenarioPlayerEvent.PIRI_FORTRESS_RECAPTURED
to announce this to any listener.
Used with scenario option _SC_PIRI
.
adjacent
- The current player's ship adjacent to their SOCFortress
,
from canAttackPirateFortress()
; unless player wins, this ship will be lost to the pirates.
adjacent
's coordinates.
adjacent
's coordinates, results[2] is the other lost ship's coord.
public java.util.Vector<SOCPlayer> getPlayersOnHex(int hex)
hex
- the coordinates of the hex; not checked for validity
players
touching a hex
with settlements/cities, or an empty Vector if none.
Any player with multiple settlements/cities on the hex
will be in the list just once, not once per piece.public java.util.Vector<SOCPlayer> getPlayersShipsOnHex(int hex)
hex
- the coordinates of the hex
players
touching a hex
with ships, or an empty Vector if nonepublic SOCFortress getFortress(int node)
_SC_PIRI
, get the Pirate Fortress
at this node location, if any. A player must defeat 'their' fortress to win.
node
- Coordinate to check for fortress
SOCPlayer.getFortress()
; use SOCBoard.settlementAtNode(int)
to
get the settlement that it's converted into after defeat.public boolean getRobberyPirateFlag()
public java.util.Vector<SOCPlayer> getPossibleVictims()
getRobberyPirateFlag()
,
get the list of victims with adjacent settlements/cities or ships.
Victims are players with resources; for scenario option
_SC_CLVI
, also players with cloth
when robbing with the pirate.
For scenario option SOCGameOption.K_SC_PIRI
, this is called
after a 7 is rolled, or after the game moves the pirate ship (fleet).
When a 7 is rolled, the current player may rob from any player with resources.
When the pirate ship is moved (at every dice roll), the player with a
port settlement/city adjacent to the pirate ship's hex is attacked,
unless there are multiple adjacent players (nothing happens).
canChoosePlayer(int)
,
choosePlayerForRobbery(int)
public int stealFromPlayer(int pn, boolean choseCloth)
For the cloth game scenario, can steal cloth, and can gain victory points from having
cloth. If cloth robbery gives player enough VP to win, sets gameState to OVER
.
Does not validate pn; assumes canChoosePlayer(int)
and choosePlayerForRobbery(int)
have been called already.
pn
- the number of the player being robbedchoseCloth
- player has both resources and cloth
,
the robbing player chose to steal cloth.
Even if false (no choice made), will steal cloth
if player has 0 resources
.
SOCResourceConstants
,
or SOCResourceConstants.CLOTH_STOLEN_LOCAL
for cloth.stealFromPlayerPirateFleet(int, int)
private void stealFromPlayerPirateFleet(int pn, int pirFleetStrength)
_SC_PIRI
, the pirate fleet is moved every
dice roll, and may steal from the single player with an adjacent settlement or city.
If pirate fleet is stronger than player's fleet (SOCPlayer.getNumWarships()
),
perform the robbery. Number of resources stolen are 1 + victim's number of cities.
The stolen resources are discarded, no player gets them.
Does not change gameState.
Results will be reported back through robberResult
:
SOCMoveRobberResult.sc_piri_loot
to the resource(s) stolen, if any
sc_piri_loot.getTotal()
will be 0
pirFleetStrength
, nothing is gained or lost
sc_piri_loot
will contain 1 SOCResourceConstants.GOLD_LOCAL
Caller must set SOCPlayer.setNeedToPickGoldHexResources(int)
, not set here.
pn
.
pn
- The player number being robbed; not validatedpirFleetStrength
- Pirate fleet strength, from rollDice()
dice rollstealFromPlayer(int, boolean)
public boolean hasTradeOffers()
SOCPlayer.getCurrentOffer()
.
public boolean canMakeTrade(int offering, int accepting)
offering
- the number of the player making the offeraccepting
- the number of the player accepting the offer
canMakeBankTrade(SOCResourceSet, SOCResourceSet)
public void makeTrade(int offering, int accepting)
Assumes canMakeTrade(int, int)
already was called.
If game option "NT" is set, players can trade only
with the bank, not with other players.
offering
- the number of the player making the offeraccepting
- the number of the player accepting the offermakeBankTrade(SOCResourceSet, SOCResourceSet)
public boolean canUndoBankTrade(SOCResourceSet undo_gave, SOCResourceSet undo_got)
To undo the bank trade, call canMakeBankTrade(SOCResourceSet, SOCResourceSet)
with give/get swapped from the original call, then call
makeBankTrade(SOCResourceSet, SOCResourceSet)
the same way.
undo_gave
- Undo giving these resources (get these back from the bank)undo_got
- Undo getting these resources (give these back to the bank)
public boolean canMakeBankTrade(SOCResourceSet give, SOCResourceSet get)
give
- what the player will give to the bankget
- what the player wants from the bank
canUndoBankTrade(SOCResourceSet, SOCResourceSet)
public void makeBankTrade(SOCResourceSet give, SOCResourceSet get)
This method does not validate against game rules, so call
canMakeBankTrade(SOCResourceSet, SOCResourceSet)
first.
Undo was added in version 1.1.13; if the player's previous action
this turn was a bank trade, it can be undone by calling
canUndoBankTrade(SOCResourceSet, SOCResourceSet)
,
then calling makeBankTrade(SOCResourceSet, SOCResourceSet)
with
the give/get swapped. This is the only time the resource count
of give is less than get here (for example,
give back 1 brick to get back 3 sheep).
give
- what the player will give to the bankget
- what the player wants from the bankpublic boolean couldBuildRoad(int pn)
pn
- the number of the player
public boolean couldBuildSettlement(int pn)
pn
- the number of the player
SOCPlayer.canPlaceSettlement(int)
public boolean couldBuildCity(int pn)
pn
- the number of the player
public boolean couldBuyDevCard(int pn)
pn
- the number of the player
buyDevCard()
public boolean couldBuildShip(int pn)
pn
- the number of the player
hasSeaBoard
because players would have 0 ship pieces.canPlaceShip(SOCPlayer, int)
public void buyRoad(int pn)
couldBuildRoad(int)
is true, does not check it here.
pn
- the number of the playerputPiece(SOCPlayingPiece)
,
cancelBuildRoad(int)
public void buySettlement(int pn)
couldBuildSettlement(int)
is true, does not check it here.
pn
- the number of the playerputPiece(SOCPlayingPiece)
,
cancelBuildSettlement(int)
public void buyCity(int pn)
couldBuildCity(int)
is true, does not check it here.
pn
- the number of the playerputPiece(SOCPlayingPiece)
,
cancelBuildCity(int)
public void buyShip(int pn)
couldBuildShip(int)
is true, does not check it here.
pn
- the number of the playerputPiece(SOCPlayingPiece)
,
cancelBuildShip(int)
public boolean canCancelBuildPiece(int buildType)
PLACING_ROAD
, etc),
and for initial settlement placement.
In v1.1.17+, also true in PLACING_FREE_ROAD2
to skip the second placement.
buildType
- Piece type (SOCPlayingPiece.ROAD
, CITY
, etc)
cancelBuildRoad(int)
public boolean cancelBuildRoad(int pn)
In version 1.1.17 and newer (VERSION_FOR_CANCEL_FREE_ROAD2
),
can also use to skip placing the second free road in PLACING_FREE_ROAD2
;
sets gameState to PLAY or PLAY1 as if the free road was placed.
In v2.0.00 and newer, can similarly call cancelBuildShip(int)
in that state.
pn
- the number of the player
PLACING_FREE_ROAD2
)public void cancelBuildSettlement(int pn)
To cancel an initial settlement, call undoPutInitSettlement(SOCPlayingPiece)
instead.
pn
- the number of the playerpublic void cancelBuildCity(int pn)
pn
- the number of the playerpublic boolean cancelBuildShip(int pn)
Can also use to skip placing the second free ship in PLACING_FREE_ROAD2
;
sets gameState to PLAY or PLAY1 as if the free ship was placed.
Can similarly call cancelBuildRoad(int)
in that state.
pn
- the number of the player
PLACING_FREE_ROAD2
)public SOCInventoryItem cancelPlaceInventoryItem(boolean forceEndTurn)
PLACING_INV_ITEM
, the current player is canceling special SOCInventoryItem
placement.
Return it to their hand, and set gameState back to PLAY1
or SPECIAL_BUILDING
based on oldGameState.
If ! SOCInventoryItem.canCancelPlay
, does nothing unless forceEndTurn
.
If placingItem
is null
, sets game state to oldGameState
and returns null
.
forceEndTurn
- If true, player's turn is being ended. Return item to inventory even if ! item.canCancelPlay
.
null
if none or if placement can't be canceled for this typepublic boolean isShipWarship(SOCShip sh)
_SC_PIRI
, is this ship upgraded to a warship?
Counts down sh
's player's SOCPlayer.getNumWarships()
while it looks for sh
among the ships from SOCPlayer.getRoads()
,
which is in the same chronological order as warship conversions.
(Those are the ships heading out to sea starting at the player's coastal settlement.)
sh
- A ship whose player is in this game
SOCPlayer.getRoads()
contains, among its
first SOCPlayer.getNumWarships()
ships, a ship
located at sh.getCoordinates()
.playKnight()
public int buyDevCard()
Note: Not checked for validity; please call couldBuyDevCard(int)
first.
If called while the game is starting, when getCurrentPlayerNumber()
== -1,
removes and returns a dev card from the deck without giving it to any player.
SOCDevCardConstants
.public boolean canPlayKnight(int pn)
PLAY
or PLAY1
.
Must have a SOCDevCardConstants.KNIGHT
and must
not have already played a dev card this turn.
In game scenario _SC_PIRI
,
can this player currently play a Warship (Knight) card to
convert one of their ships into a warship?
Conditions in first paragraph must be true, and player's SOCPlayer.getRoads()
must contain more ships than SOCPlayer.getNumWarships()
.
That scenario has no robber on the board, only the pirate fleet.
pn
- the number of the player
public boolean canPlayRoadBuilding(int pn)
This card directs the player to place 2 roads. Checks of game rules online show they "MAY" or "CAN", not "MUST", place 2. If they have 2 or more roads, place 2. If they have just 1 road, place 1. If they have 0 roads, cannot play the card.
pn
- the number of the player
playRoadBuilding()
public boolean canPlayDiscovery(int pn)
pn
- the number of the playerpublic boolean canPlayMonopoly(int pn)
pn
- the number of the playerpublic int canPlayInventoryItem(int pn, int itype)
SOCInventoryItem
now? Checks the game state, scenario options, and
player's inventory. Returns 0 or the reason why they can't play it right now.
Assumes server or client player is calling, and thus player has no unknown dev cards (itype == 0).
If calling at client for another player, and the scenario allows special items of type 0, these
currently can't be distinguished from SOCDevCardConstants.UNKNOWN
dev cards.
_SC_FTRI
: Trade ports received as gifts.
Playable in state PLAY1
or SPECIAL_BUILDING
and only when player has a
coastal settlement/city with no adjacent existing port. Returns 4 if
SOCPlayer.getPortMovePotentialLocations(boolean)
== null
.
(See "returns" section below for the standard other return codes.)
Because the rules require building a coastal settlement/city before placing
the new port, which is done during PLAY1
or SPECIAL_BUILDING
, the port can't be placed
before the dice roll or in other game states.
pn
- Player numberitype
- Inventory item type, from SOCInventoryItem.itype
itype
in player's SOCInventory
playInventoryItem(int)
public SOCInventoryItem playInventoryItem(int itype)
SOCInventoryItem
for the current player. The current game must have a
scenario SOCGameOption
that uses the inventory item. Assumes canPlayInventoryItem(int, int)
has been called to check game options and state, player inventory, etc.
_SC_FTRI
: Trade ports received as gifts.
Game state becomes PLACING_INV_ITEM
. Player must now choose and validate a location
and then call placePort(int)
.
itype
- Special item type, from SOCInventoryItem.itype
null
if not found playable in current player's inventory
or not recognized in current game. canPlayInventoryItem(int, int)
checks those things,
so if you've called that, you shouldn't get null
returned from here.public void playKnight()
canPlayKnight(int)
already called, and the play is allowed.
gameState becomes either PLACING_ROBBER
or WAITING_FOR_ROBBER_OR_PIRATE
.
In scenario _SC_PIRI
, instead the player
converts a normal ship to a warship. There is no robber piece in this scenario.
Call SOCPlayer.getNumWarships()
afterwards to get the current player's new count.
Ships are converted in the chronological order they're placed, out to sea from the
player's coastal settlement; see isShipWarship(SOCShip)
.
public void playRoadBuilding()
Assumes canPlayRoadBuilding(int)
has already been called, and move is valid.
The card can be played before or after rolling the dice.
Doesn't set oldGameState, because after placing the road, we might need that field.
public void playDiscovery()
public void playMonopoly()
public boolean canDoDiscoveryAction(SOCResourceSet pick)
pick
- the resources that the player wants
public boolean canDoMonopolyAction()
public void doDiscoveryAction(SOCResourceSet pick)
pick
- what the player pickedpublic int[] doMonopolyAction(int rtype)
rtype
- the type of resource to monopolize
public void updateLargestArmy()
public void saveLargestArmyState()
restoreLargestArmyState()
between them.
public void restoreLargestArmyState()
saveLargestArmyState()
between them.
public void updateLongestRoad(int pn)
SOCPlayer.calcLongestRoad2()
.
Assumes all other players' longest road has been updated already.
All players' SOCPlayer.getLongestRoadLength()
is called here.
if there is a tie, the last player to have LR keeps it. if two or more players are tied for LR and none of them used to have LR, then no one has LR.
If SOCGameOption.K_SC_0RVP
is set, does nothing.
pn
- the number of the player who is affectedpublic void checkForWinner()
OVER
,
set player with win.
This method is called from other game methods which may award VPs or may cause a win,
such as buyDevCard()
and putPiece(SOCPlayingPiece)
, and at the start
of each turn by endTurn()
under some conditions (see that method).
Per rules FAQ, a player can win only during their own turn.
If a player reaches winning points (vp_winner
or more) but it's
not their turn, there is not yet a winner. This could happen if,
for example, the longest road is broken by a new settlement, and
the next-longest road is not the current player's road.
The win is determined not by who has the highest point total, but
solely by reaching enough victory points (vp_winner
) during your own turn.
Some game scenarios have other special win conditions (hasScenarioWinCondition
):
_SC_CLVI
will end the game if
less than half the SOCVillage
s have cloth remaining. The player
with the most VP wins; if tied, the tied player with the most cloth wins.
The winner is not necessarily the current player.
_SC_PIRI
requires the player to
defeat and recapture 'their' pirate fortress to win.
_SC_WOND
requires the player to
build a Wonder to a higher level than any other player's Wonder; the player
can win even without reaching vp_winner
VP.
getGameState()
,
getPlayerWithWin()
private final boolean checkForWinner_SC_CLVI()
checkForWinner()
for details.
Sets state to OVER
. Returns true.
Caller should fire SOCScenarioGameEvent.SGE_CLVI_WIN_VILLAGE_CLOTH_EMPTY
.
public void destroyGame()
public SOCGame resetAsCopy()
NEW
,
or if there are robots, it will be set to READY_RESET_WAIT_ROBOT_DISMISS
by the SOCGameBoardReset
constructor.
Deep copy: Player names, faceIDs, and robot-flag are copied from
old game, but all other fields set as new Player and Board objects.
Robot players are NOT carried over, and must be asked to re-join.
(This simplifies the robot client.)
Any vacant seats will be locked, so a robot won't sit there.
Old game's state becomes RESET_OLD
.
Old game's previous state is saved to getResetOldGameState()
.
Please call destroyGame() on old game when done examining its state.
Assumes that if the game had more than one human player, they've already voted interactively to reset the board.
resetVoteBegin(int)
public void resetVoteBegin(int reqPN) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException
reqPN
- Player number requesting the vote
java.lang.IllegalArgumentException
- If this player number has already
requested a reset this turn
java.lang.IllegalStateException
- If there is already a vote in progressgetResetVoteRequester()
,
resetVoteRegister(int, boolean)
,
getResetVoteResult()
public int getResetVoteRequester()
resetVoteBegin(int)
public boolean getResetVoteActive()
public boolean resetVoteRegister(int pn, boolean votingYes) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException
pn
- Player numbervotingYes
- Are they voting yes, or no?
java.lang.IllegalArgumentException
- If pn already voted, or can't vote (vacant or robot).
java.lang.IllegalStateException
- If voting is not currently active.getResetPlayerVote(int)
public int getResetPlayerVote(int pn)
pn
- Player number
VOTE_YES
, VOTE_NO
,
or if player hasn't yet voted, VOTE_NONE
.resetVoteRegister(int, boolean)
,
getResetVoteResult()
public void resetVoteClear()
endTurn()
because
endTurn is called only at the server, not at clients.
Do not call this to cancel a vote during normal gameplay, because
it would allow players to ask for a reset more than once per turn.
public boolean getResetVoteResult() throws java.lang.IllegalStateException
java.lang.IllegalStateException
- if voting is still active. See getResetVoteActive()
.getResetPlayerVote(int)
public boolean canBuyOrAskSpecialBuild(int pn)
In 1.1.09 and later, player is allowed to Special Build at start of their own turn, only if they haven't yet rolled or played a dev card.
pn
- Player numbercanAskSpecialBuild(int, boolean)
public boolean isSpecialBuilding()
Special Building Phase
?
Includes game state SPECIAL_BUILDING
, and placement game states during this phase.
public boolean canAskSpecialBuild(int pn, boolean throwExceptions) throws java.lang.IllegalStateException, java.lang.IllegalArgumentException
Special Building Phase
,
can the player currently request to special build?
See 'throws' for the conditions checked.
In 1.1.09 and later, player is allowed to Special Build at start of their
own turn, only if they haven't yet rolled or played a dev card.
To do so, call askSpecialBuild(int, boolean)
and then endTurn()
.
pn
- The player's number
java.lang.IllegalStateException
- if game is not 6-player, or pn is current player,
or pn.hasAskedSpecialBuild()
or pn.hasSpecialBuilt()
is true,
or if gamestate is earlier than PLAY
, or >= OVER
,
or if the first player is asking before completing their first turn.
java.lang.IllegalArgumentException
- if pn is not a valid player (vacant seat, etc).canBuyOrAskSpecialBuild(int)
public void askSpecialBuild(int pn, boolean onlyIfCan) throws java.lang.IllegalStateException, java.lang.IllegalArgumentException
In 1.1.09 and later, player is allowed to Special Build at start of their
own turn, only if they haven't yet rolled or played a dev card.
To do so, call askSpecialBuild(int, boolean)
and then endTurn()
.
Also sets game's askedSpecialBuildPhase flag in 1.1.09 and later.
Note that this method only sets the flags, and cannot clear them.
You can clear the player's flag via SOCPlayer.setAskedSpecialBuild(boolean)
,
but cannot directly clear askedSpecialBuildPhase.
Normal game flow does not need a way to do so.
pn
- The player's numberonlyIfCan
- Check if player can do so, before setting player and game flags.
Should always be true for server calls.
java.lang.IllegalStateException
- if game is not 6-player, or is currently this player's turn,
or if gamestate is earlier than PLAY
, or >= OVER
.
java.lang.IllegalArgumentException
- if pn is not a valid player (vacant seat, etc).public boolean isDebugFreePlacement()
putPiece(SOCPlayingPiece)
public void setDebugFreePlacement(boolean debugOn) throws java.lang.IllegalStateException
Should only be turned on during the debugging human player's turn,
in game state PLAY1
or during isInitialPlacement()
states.
When turning it off during initial placement, all players must have
either 1 settlement and road, or at least 2 settlements and roads.
This allows the game setup routines to work properly during this debug
mode. The current player will be set to the first player (if 2+
settlements/roads placed) or the last player (1 settlement placed).
Check getCurrentPlayerNumber()
and getGameState()
after calling setDebugFreePlacement(false)
during initial placement.
For more details, see isDebugFreePlacement()
javadoc.
debugOn
- Should the mode be on?
java.lang.IllegalStateException
- if turning on when gameState is not PLAY1
or an initial placement state (START1A
- START3B
),
or turning off during initial placement with an unequal number of pieces placed.public java.lang.String toString()
toString
in class java.lang.Object
|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |