soc.game
Class SOCGame

java.lang.Object
  extended by soc.game.SOCGame
All Implemented Interfaces:
java.io.Serializable, java.lang.Cloneable

public class SOCGame
extends java.lang.Object
implements java.io.Serializable, java.lang.Cloneable

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 SOCGameOptions will include "SC", possibly along with other options whose key names start with "_SC_".

Author:
Robert S. Thomas
See Also:
Serialized Form

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 SOCVillages 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 SOCSpecialItems, 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 SOCSpecialItems, 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

serialVersionUID

private static final long serialVersionUID
The main game class has a serialVersionUID; pieces and players don't. Currently we don't expect to persist a game between versions.

See Also:
Constant Field Values

NEW

public static final int NEW
Game states. 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:

The code reacts to (switches based on) game state in several places. The main places to check, if you add a game state:

Also, if your state is similar to an existing state, do a where-used search for that state, and decide where both states should be reacted to.

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:

See Also:
Constant Field Values

READY

public static final int READY
Ready to start playing. All humans have chosen a seat. Wait for requested robots to sit down. Once robots have joined the game (this happens in other threads, possibly in other processes), gameState will become START1A.

See Also:
READY_RESET_WAIT_ROBOT_DISMISS, Constant Field Values

SETOPTIONS_EXCL

public static final int SETOPTIONS_EXCL
See Also:
Constant Field Values

SETOPTIONS_INCL

public static final int SETOPTIONS_INCL
See Also:
Constant Field Values

READY_RESET_WAIT_ROBOT_DISMISS

public static final 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. Once they have all left, state becomes READY. See boardResetOngoingInfo and (private) SOCServer.resetBoardAndNotify.

Since:
1.1.07
See Also:
Constant Field Values

START1A

public static final int START1A
Players place first settlement. Proceed in order for each player; next state is START1B to place each player's 1st road.

See Also:
Constant Field Values

START1B

public static final int START1B
Players place first road. Next state is START1A to place next player's 1st settlement, or if all have placed settlements, START2A to place 2nd settlement.

See Also:
Constant Field Values

START2A

public static final int START2A
Players place second settlement. Proceed in reverse order for each player; next state is 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.

See Also:
Constant Field Values

STARTS_WAITING_FOR_PICK_GOLD_RESOURCE

public static final int STARTS_WAITING_FOR_PICK_GOLD_RESOURCE
Just placed an initial piece, waiting for current player to choose which Gold Hex resources to receive. This can happen after the second or third initial settlement, or (with the fog scenario _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.

Since:
2.0.00
See Also:
WAITING_FOR_PICK_GOLD_RESOURCE, pickGoldHexResources(int, SOCResourceSet), Constant Field Values

START2B

public static final int START2B
Players place second road. Next state is 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.

See Also:
Constant Field Values

START3A

public static final int START3A
(Game scenarios) Players place third settlement. Proceed in normal order for each player; next state is 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.

See Also:
Constant Field Values

START3B

public static final int START3B
Players place third road. Next state is 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.

See Also:
Constant Field Values

PLAY

public static final int PLAY
Start of a normal turn. Time to roll or play a card. Next state depends on card or roll, but usually is 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.

See Also:
Constant Field Values

PLAY1

public static final int PLAY1
Done rolling (or moving robber on 7). Time for other turn actions, such as building or buying or trading, or playing a card if not already done. Next state depends on what's done, but usually is the next player's PLAY.

See Also:
Constant Field Values

PLACING_ROAD

public static final int PLACING_ROAD
See Also:
Constant Field Values

PLACING_SETTLEMENT

public static final int PLACING_SETTLEMENT
See Also:
Constant Field Values

PLACING_CITY

public static final int PLACING_CITY
See Also:
Constant Field Values

PLACING_ROBBER

public static final int PLACING_ROBBER
Player is placing the robber on a new land hex. May follow state WAITING_FOR_ROBBER_OR_PIRATE if the game hasSeaBoard. Next game state may be WAITING_FOR_ROB_CHOOSE_PLAYER if multiple possible victims.

See Also:
PLACING_PIRATE, canMoveRobber(int, int), moveRobber(int, int), Constant Field Values

PLACING_PIRATE

public static final int PLACING_PIRATE
Player is placing the pirate ship on a new water hex, in a game which 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.

Since:
2.0.00
See Also:
PLACING_ROBBER, canMovePirate(int, int), movePirate(int, int), Constant Field Values

PLACING_SHIP

public static final int PLACING_SHIP
This game hasSeaBoard, and a player has bought and is placing a ship.

Since:
2.0.00
See Also:
Constant Field Values

PLACING_FREE_ROAD1

public static final int PLACING_FREE_ROAD1
Player is placing first free road/ship

See Also:
Constant Field Values

PLACING_FREE_ROAD2

public static final int PLACING_FREE_ROAD2
Player is placing second free road/ship

See Also:
Constant Field Values

PLACING_INV_ITEM

public static final int PLACING_INV_ITEM
Player is placing the special 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.

Since:
2.0.00
See Also:
Constant Field Values

WAITING_FOR_DISCARDS

public static final int WAITING_FOR_DISCARDS
Waiting for player(s) to discard, after 7 is rolled in 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.

See Also:
discard(int, SOCResourceSet), Constant Field Values

WAITING_FOR_ROB_CHOOSE_PLAYER

public static final 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. Next game state is 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.

See Also:
playKnight(), canChoosePlayer(int), canChooseRobClothOrResource(int), stealFromPlayer(int, boolean), Constant Field Values

WAITING_FOR_DISCOVERY

public static final int WAITING_FOR_DISCOVERY
Waiting for player to choose 2 resources (Discovery card) Next game state is PLAY1.

See Also:
Constant Field Values

WAITING_FOR_MONOPOLY

public static final int WAITING_FOR_MONOPOLY
Waiting for player to choose a resource (Monopoly card) Next game state is PLAY1.

See Also:
Constant Field Values

WAITING_FOR_ROBBER_OR_PIRATE

public static final int WAITING_FOR_ROBBER_OR_PIRATE
Waiting for player to choose the robber or the pirate ship, after rollDice() or playKnight(). Next game state is PLACING_ROBBER or PLACING_PIRATE.

Since:
2.0.00
See Also:
canChooseMovePirate(), chooseMovePirate(boolean), WAITING_FOR_DISCARDS, Constant Field Values

WAITING_FOR_ROB_CLOTH_OR_RESOURCE

public static final int WAITING_FOR_ROB_CLOTH_OR_RESOURCE
Waiting for player to choose whether to rob cloth or rob a resource. Previous game state is PLACING_PIRATE or WAITING_FOR_ROB_CHOOSE_PLAYER. Used with scenario option _SC_CLVI.

Since:
2.0.00
See Also:
movePirate(int, int), canChooseRobClothOrResource(int), Constant Field Values

WAITING_FOR_PICK_GOLD_RESOURCE

public static final int WAITING_FOR_PICK_GOLD_RESOURCE
Waiting for player(s) to choose which Gold Hex resources to receive. Next game state is usually 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.

Since:
2.0.00
See Also:
STARTS_WAITING_FOR_PICK_GOLD_RESOURCE, pickGoldHexResources(int, SOCResourceSet), Constant Field Values

WAITING_FOR_DESTROY

public static final int WAITING_FOR_DESTROY
Waiting for player to choose a settlement to destroy, or a city to downgrade (Dev card SOCDevCardConstants.DESTROY). Used with game option "DH".

Since:
2.0.00
See Also:
Constant Field Values

WAITING_FOR_SWAP

public static final int WAITING_FOR_SWAP
Waiting for player to choose a settlement or city to swap with another player (Dev card SOCDevCardConstants.SWAP). Used with game option "DH".

Since:
2.0.00
See Also:
Constant Field Values

SPECIAL_BUILDING

public static final int SPECIAL_BUILDING
The 6-player board's Special Building Phase. Takes place at the end of any player's normal turn (roll, place, etc). 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.

Since:
1.1.08
See Also:
Constant Field Values

OVER

public static final int OVER
The game is over. A player has accumulated enough (vp_winner) victory points, or all players have left the game.

See Also:
checkForWinner(), Constant Field Values

RESET_OLD

public static final int RESET_OLD
This game is an obsolete old copy of a new (reset) game with the same name. To assist logic, numeric constant value is greater than OVER.

See Also:
resetAsCopy(), getResetOldGameState(), Constant Field Values

VACANT

public static final int VACANT
seat states

See Also:
Constant Field Values

OCCUPIED

public static final int OCCUPIED
seat states

See Also:
Constant Field Values

VOTE_NONE

public static final int VOTE_NONE
boardResetVotes per-player states: no vote sent; yes; no.

See Also:
Constant Field Values

VOTE_YES

public static final int VOTE_YES
See Also:
Constant Field Values

VOTE_NO

public static final int VOTE_NO
See Also:
Constant Field Values

MAXPLAYERS

public static final int MAXPLAYERS
Maximum number of players in a game, in this version. Was 4 before 1.1.08, now is 6.

See Also:
maxPlayers, MAXPLAYERS_STANDARD, Constant Field Values

MAXPLAYERS_STANDARD

public static final int MAXPLAYERS_STANDARD
maximum number of players in a standard game

Since:
1.1.08
See Also:
MAXPLAYERS, maxPlayers, Constant Field Values

MINPLAYERS

public static final int MINPLAYERS
minimum number of players in a game (was assumed ==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.

See Also:
Constant Field Values

VP_WINNER_STANDARD

public static final int VP_WINNER_STANDARD
Default number of victory points (10) needed to win. Per-game copy is 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.

Since:
1.1.14
See Also:
Constant Field Values

NUM_DEVCARDS_VP

private static final int NUM_DEVCARDS_VP
Number of development cards (5) which are Victory Point cards. Not used in scenario _SC_PIRI. (If 4 or more players in that scenario, they become KNIGHT cards.)

Since:
2.0.00
See Also:
NUM_DEVCARDS_STANDARD, Constant Field Values

NUM_DEVCARDS_STANDARD

private static final int NUM_DEVCARDS_STANDARD
Number of development cards (25) in the standard rules.

Since:
1.1.08
See Also:
NUM_DEVCARDS_6PLAYER, Constant Field Values

NUM_DEVCARDS_6PLAYER

private static final int NUM_DEVCARDS_6PLAYER
Number of development cards (34) in the 6-player rules.

Since:
1.1.08
See Also:
NUM_DEVCARDS_STANDARD, Constant Field Values

VERSION_FOR_CANCEL_FREE_ROAD2

public static final int VERSION_FOR_CANCEL_FREE_ROAD2
Minimum version (1.1.17) that supports canceling the second free road or ship placement.

Since:
1.1.17
See Also:
cancelBuildRoad(int), cancelBuildShip(int), Constant Field Values

EMPTY_RESOURCES

public static final SOCResourceSet EMPTY_RESOURCES
an empty set of resources.

See Also:
SETTLEMENT_SET

SETTLEMENT_SET

public static final SOCResourceSet SETTLEMENT_SET
the set of resources a player needs to build a settlement

See Also:
SOCPlayingPiece.getResourcesToBuild(int)

ROAD_SET

public static final SOCResourceSet ROAD_SET
the set of resources a player needs to build a road

See Also:
SOCPlayingPiece.getResourcesToBuild(int)

CITY_SET

public static final SOCResourceSet CITY_SET
the set of resources a player needs to build a city

See Also:
SOCPlayingPiece.getResourcesToBuild(int)

SHIP_SET

public static final SOCResourceSet SHIP_SET
the set of resources a player needs to build a ship

Since:
2.0.00
See Also:
SOCPlayingPiece.getResourcesToBuild(int)

CARD_SET

public static final SOCResourceSet CARD_SET
the set of resources a player needs to buy a development card

See Also:
SOCPlayingPiece.getResourcesToBuild(int), SOCInventory

boardFactory

public static SOCBoard.BoardFactory boardFactory
The SOCBoard.BoardFactory for creating new boards in the SOCGame constructors. Differs at client and at server. If null, SOCGame constructor sets to SOCBoard.DefaultBoardFactory.

Since:
2.0.00

EMPTY_INT_ARRAY

private static final int[] EMPTY_INT_ARRAY
An empty int array for use in method calls.

Since:
2.0.00

inUse

boolean inUse
monitor for synchronization


name

private java.lang.String name
the name of the game


isAtServer

boolean isAtServer
Is this the server's complete copy of the game, not the client's (with some details unknown)? Set during startGame().

Since:
1.1.17

pendingMessagesOut

public transient java.util.List<java.lang.Object> pendingMessagesOut
For games at server, a convenient place to hold outbound messages during game actions. Public access for use by SOCServer. The server will handle a game action as usual (for example, 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).

Since:
2.0.00

ownerName

private java.lang.String ownerName
For games at the server, the owner (creator) of the game. Will be the name of a player / server connection. Currently, if the game is reset, resetAsCopy() copies ownerName, even if they aren't still connected to the game. NOT CURRENTLY SET AT CLIENT.

Since:
1.1.10

ownerLocale

private java.lang.String ownerLocale
Locale of the client connection that created this game. Used to determine whether to set 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.

Since:
2.0.00

active

private boolean active
true if this game is ACTIVE


vp_winner

public final int vp_winner
Number of victory points needed to win this game (default 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.

Since:
1.1.14
See Also:
hasScenarioWinCondition

hasScenarioWinCondition

public final 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 SOCVillages 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().

Since:
2.0.00

isPractice

public boolean isPractice
true if the game's network is local for practice. Used by client to route messages to appropriate connection. NOT CURRENTLY SET AT SERVER. Instead check if server's strSocketName != null, or if connection instanceof LocalStringConnection.

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.


isBotsOnly

public boolean isBotsOnly
true if the game's only players are bots, no humans. Useful for bot AI experiments. Not sent over the network: Must be set at server, or set at bot client at start of game.

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.

Since:
2.0.00

hasBuiltCity

private boolean hasBuiltCity
True once any player has built a city. Used with house-rule game option "N7C".

Since:
1.1.19

scenarioEventListener

SOCScenarioEventListener scenarioEventListener
Listener for scenario events on the large sea board, or null. Package access for read-only use by SOCPlayer.

Since:
2.0.00

hasOldClients

public boolean hasOldClients
For use at server; are there clients connected which aren't at the latest version?


clientVersionLowest

public int clientVersionLowest
For use at server; lowest and highest version of connected clients.


clientVersionHighest

public int clientVersionHighest
For use at server; lowest and highest version of connected clients.


clientVersionMinRequired

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.

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.


hasMultiLocales

public 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.

Since:
2.0.00

debugFreePlacement

private boolean debugFreePlacement
Are we in the 'free placement' debug mode? See SOCGameHandler.processDebugCommand_freePlace, SOCPlayerInterface.setDebugPaintPieceMode.

Since:
1.1.12

debugFreePlacementStartPlaced

private boolean debugFreePlacementStartPlaced
Have we placed pieces in debugFreePlacement during initial placement? Set in putPiece(SOCPlayingPiece).

Since:
1.1.12

isFromBoardReset

private boolean isFromBoardReset
true if the game came from a board reset


boardResetOngoingInfo

public transient 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). This field is null except within the newly-created game object during reset.

Since:
1.1.07

boardResetVoteRequester

private int boardResetVoteRequester
If a board reset vote is active, player number who requested the vote. All human players must vote unanimously, or board reset is rejected. -1 if no vote is active. Synchronize on boardResetVotes before reading or writing.


boardResetVotes

private int[] boardResetVotes
If a board reset vote is active, votes are recorded here. Values: VOTE_NONE, VOTE_YES, VOTE_NO. Indexed 0 to SOCGame.MAXPLAYERS-1. Synchronize on this object before reading or writing.


boardResetVotesWaiting

private int boardResetVotesWaiting
If a board reset vote is active, we're waiting to receive this many more votes. All human players vote, except the vote requester. Robots do not vote. Synchronize on 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.


board

private SOCBoard board
the game board


opts

private java.util.Map<java.lang.String,SOCGameOption> opts
the game options (SOCGameOption), or null

Since:
1.1.07

players

private SOCPlayer[] players
the players; never contains a null element, use isSeatVacant(int) to see if a position is occupied. Length is maxPlayers.


seats

private int[] seats
the states for the player's seats


seatLocks

private SOCGame.SeatLockState[] seatLocks
the states of the locks for the player's seats


currentPlayerNumber

private int currentPlayerNumber
the number of the current player


firstPlayerNumber

private int firstPlayerNumber
the first player to place a settlement


lastPlayerNumber

private int lastPlayerNumber
the last player to place the first settlement


maxPlayers

public final int maxPlayers
maxPlayers is 4 for the standard game, or 6 if this game is on the 6-player board, with corresponding rules.

The 6-player extensions are orthogonal to other board type/expansion flags such as hasSeaBoard; one doesn't imply or exclude the other.

Since:
1.1.08

hasSeaBoard

public final 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. 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.

Since:
2.0.00

currentDice

private int currentDice
the current dice result. -1 at start of game, 0 during player's turn before roll (state PLAY).

See Also:
currentRoll

currentRoll

private SOCGame.RollResult currentRoll
The current dice result, including any scenario items such as SOCVillage.distributeCloth(SOCGame) results. This is the object returned from rollDice() each turn.

Since:
2.0.00
See Also:
currentDice

robberResult

private SOCMoveRobberResult robberResult
The most recent moveRobber(int, int) or movePirate(int, int) result. Used at server only.

Since:
2.0.00

gameState

private int gameState
the current game state


oldGameState

private int oldGameState
The saved game state; used in only a few places, where a state can happen from different start states. Not set every time the game state changes.

oldGameState is read in these states:

Also used if the game board was reset: getResetOldGameState() holds the state before the reset.


placingRobberForKnightCard

private boolean placingRobberForKnightCard
If true, and if state is 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.


forcingEndTurn

private boolean forcingEndTurn
If true, this turn is being ended. Controller of game (server) should call 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.

See Also:
forceEndTurn()

askedSpecialBuildPhase

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.

Since:
1.1.08
See Also:
specialBuildPhase_afterPlayerNumber

specialBuildPhase_afterPlayerNumber

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. Game state is 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.

Since:
1.1.08
See Also:
askedSpecialBuildPhase

playerWithLargestArmy

private int playerWithLargestArmy
the player with the largest army, or -1 if none


oldPlayerWithLargestArmy

private int oldPlayerWithLargestArmy
To remember last playerWithLargestArmy during saveLargestArmyState() / restoreLargestArmyState().


playerWithLongestRoad

private int playerWithLongestRoad
the player with the longest road or trade route, or -1 if none


oldPlayerWithLongestRoad

java.util.Stack<SOCOldLRStats> oldPlayerWithLongestRoad
used to restore the LR player


playerWithWin

private int playerWithWin
the player declared winner, if gamestate == OVER; otherwise -1


numDevCards

private int numDevCards
the number of development cards left in devCardDeck for buyDevCard().


devCardDeck

private int[] devCardDeck
the development card deck. Each element is a dev card type from SOCDevCardConstants. numDevCards tracks the cards remaining to buy.


spItems

private java.util.HashMap<java.lang.String,java.util.ArrayList<SOCSpecialItem>> spItems
Game's SOCSpecialItems, 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).

Since:
2.0.00

rand

private java.util.Random rand
used to generate random numbers


allOriginalPlayers

boolean allOriginalPlayers
used to track if there were any player subs


startTime

java.util.Date startTime
Time when this game was created, or null if not active when created.

See Also:
lastActionTime, expiration

expiration

long expiration
Expiration time for this game in milliseconds (system clock time, not a duration from startTime); Same format as System.currentTimeMillis().

See Also:
startTime

lastActionTime

public long lastActionTime
The last time a game action happened; can be used to check for game inactivity. Updated in 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.

Since:
1.1.11
See Also:
getStartTime(), getExpiration()

lastActionWasBankTrade

private boolean lastActionWasBankTrade
Used at server; was the most recent player action a bank trade? If true, allow the player to undo that trade. Updated whenever lastActionTime is updated.

TODO: Consider lastActionType instead, it's more general.

Since:
1.1.13

robberyWithPirateNotRobber

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. Set in chooseMovePirate(boolean), movePirate(int, int), moveRobber(int, int), and other places that set gameState to PLACING_ROBBER or PLACING_PIRATE.

Since:
2.0.00
See Also:
getRobberyPirateFlag()

movedShipThisTurn

private boolean movedShipThisTurn
Has the current player moved a ship already this turn? Valid only when hasSeaBoard.

Since:
2.0.00

placedShipsThisTurn

private java.util.Vector<java.lang.Integer> placedShipsThisTurn
List of ship edge coordinates placed this turn. A ship cannot be placed and moved on the same turn. Null when not hasSeaBoard.

Since:
2.0.00

placingItem

private SOCInventoryItem placingItem
The special inventory item currently being placed in state PLACING_INV_ITEM, or null. Can be set with setPlacingItem(SOCInventoryItem) before or during that state.

Since:
2.0.00

turnCount

private int turnCount
The number of normal turns (not rounds, not initial placements), including this turn. This is 0 during initial piece placement, and 1 when the first player is about to roll dice for the first time. updated in updateAtTurn().

Since:
1.1.07

roundCount

private int roundCount
The number of normal rounds (each player has 1 turn per round, after initial placements), including this round. for gameoption N7: Roll no 7s during first # rounds. This is 0 during initial piece placement, and 1 when the first player is about to roll dice for the first time. It becomes 2 when that first player's turn begins again. updated in updateAtTurn().

Since:
1.1.07
Constructor Detail

SOCGame

public SOCGame(java.lang.String n)
create a new, active game

Parameters:
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).

SOCGame

public SOCGame(java.lang.String n,
               java.util.Map<java.lang.String,SOCGameOption> op)
        throws java.lang.IllegalArgumentException
create a new, active game with options and optionally a scenario (game option "SC").

Parameters:
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).
Throws:
java.lang.IllegalArgumentException - if op contains unknown options, or any object class besides SOCGameOption
Since:
1.1.07

SOCGame

public SOCGame(java.lang.String n,
               boolean isActive)
        throws java.lang.IllegalArgumentException
create a new game that can be ACTIVE or INACTIVE

Parameters:
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
Throws:
java.lang.IllegalArgumentException - if game name fails SOCMessage.isSingleLineAndSafe(String). This check was added in 1.1.07.

SOCGame

public SOCGame(java.lang.String n,
               boolean isActive,
               java.util.Map<java.lang.String,SOCGameOption> op)
        throws java.lang.IllegalArgumentException
create a new game that can be ACTIVE or INACTIVE, and have options and optionally a scenario (game option "SC").

Parameters:
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
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).
Throws:
java.lang.IllegalArgumentException - if op contains unknown options, or any object class besides SOCGameOption, or if game name fails SOCMessage.isSingleLineAndSafe(String).
Since:
1.1.07
Method Detail

takeMonitor

public void takeMonitor()
Take the synchronization monitor for this game. When done, release it with releaseMonitor().


releaseMonitor

public void releaseMonitor()
release the monitor for this game

See Also:
takeMonitor()

allOriginalPlayers

public boolean allOriginalPlayers()
Returns:
allOriginalPlayers
See Also:
hasHumanPlayers()

hasHumanPlayers

public boolean hasHumanPlayers()
Does this game contain any human players?

Returns:
True if at least one non-vacant seat has a human player (! SOCPlayer.isRobot()).
Since:
1.1.18
See Also:
allOriginalPlayers()

getStartTime

public java.util.Date getStartTime()
Returns:
the start time for this game, or null if not active when created
See Also:
getExpiration()

getExpiration

public long getExpiration()
Get the expiration time at which this game will be destroyed.

Returns:
the expiration time in milliseconds (system clock time, not a duration from startTime); same epoch as Date.getTime()
See Also:
getStartTime()

setScenarioEventListener

public void setScenarioEventListener(SOCScenarioEventListener sel)
                              throws java.lang.IllegalStateException
Set or clear the scenario event listener. Used with large sea board scenario events.

Only one listener is allowed. If you are setting the listener, it must currently be null.

Parameters:
sel - Listener, or null for none
Throws:
java.lang.IllegalStateException - If listener already not null, sel is not null, and listener is not sel
Since:
2.0.00

setExpiration

public void setExpiration(long ex)
Set the expiration time at which this game will be destroyed.

Parameters:
ex - the absolute expiration time in milliseconds (system clock time, not a duration from startTime); same epoch as Date.getTime()

getOwner

public java.lang.String getOwner()
For games at the server, the owner (creator) of the game. Will be the name of a player / server connection. Even if the owner leaves the game, their name may be retained here.

Returns:
the owner's player name, or null if setOwner(String, String) was never called
Since:
1.1.10
See Also:
getOwnerLocale()

setOwner

public void setOwner(java.lang.String gameOwnerName,
                     java.lang.String gameOwnerLocale)
              throws java.lang.IllegalStateException
For games at the server, set the game owner (creator). Will be the name of a player / server connection.

Parameters:
gameOwnerName - The game owner's player name, or null to clear
gameOwnerLocale - The game owner's locale, or null to clear
Throws:
java.lang.IllegalStateException - if gameOwnerName not null, but the game's owner is already set
Since:
1.1.10

getOwnerLocale

public final java.lang.String getOwnerLocale()
For games at the server, get the game owner (creator)'s locale, or null. Used by SOCGameListAtServer.addMember to determine whether to set hasMultiLocales.

Since:
2.0.00

addPlayer

public void addPlayer(java.lang.String name,
                      int pn)
               throws java.lang.IllegalStateException,
                      java.lang.IllegalArgumentException
Add a new player sitting at a certain seat, or sit them again in their same seat (rejoining after a disconnect). Called at server and at client.

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.

Parameters:
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
Throws:
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.
See Also:
isSeatVacant(int)

removePlayer

public void removePlayer(java.lang.String name)
                  throws java.lang.IllegalArgumentException
remove a player from their seat. Player's name becomes 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().

Parameters:
name - the player's name
Throws:
java.lang.IllegalArgumentException - if name isn't in this game. This exception was added in 1.1.07.

isSeatVacant

public boolean isSeatVacant(int pn)
Parameters:
pn - the number of the seat
Returns:
true if the seat is VACANT
See Also:
getAvailableSeatCount()

getAvailableSeatCount

public int getAvailableSeatCount()
How many seats are vacant and available for players? Based on isSeatVacant(int), and game option "PL" (maximum players) or maxPlayers.

Returns:
number of available vacant seats
Since:
1.1.07
See Also:
isSeatVacant(int)

getSeatLock

public SOCGame.SeatLockState getSeatLock(int pn)
Get a seat's lock state.

Parameters:
pn - the number of the seat
Since:
2.0.00

setSeatLock

public void setSeatLock(int pn,
                        SOCGame.SeatLockState sl)
                 throws java.lang.IllegalStateException
Lock or unlock a seat, or mark a bot's seat to be cleared on reset. The meaning of "locked" is different when the game is still forming (gameState 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).

Parameters:
pn - the number of the seat
sl - the new lock state for this seat
Throws:
java.lang.IllegalStateException - if the game is still forming but sl is SOCGame.SeatLockState.CLEAR_ON_RESET, or if getResetVoteActive()
Since:
2.0.00

getPlayer

public SOCPlayer getPlayer(int pn)
                    throws java.lang.ArrayIndexOutOfBoundsException
Parameters:
pn - the player number, in range 0 to maxPlayers-1
Returns:
the player object for a player id; never null if pn is in range
Throws:
java.lang.ArrayIndexOutOfBoundsException - if pn is out of range

getPlayer

public SOCPlayer getPlayer(java.lang.String nn)
Get the player sitting in this game with this name.

Parameters:
nn - the nickname
Returns:
the player object for a player nickname. if there is no match, return null

getName

public java.lang.String getName()
Returns:
the name of the game

getGameOptions

public java.util.Map<java.lang.String,SOCGameOption> getGameOptions()
Returns:
this game's options (SOCGameOption), or null
Since:
1.1.07
See Also:
isGameOptionDefined(String), isGameOptionSet(String), getGameOptionIntValue(String)

isGameOptionDefined

public boolean isGameOptionDefined(java.lang.String optKey)
Is this game option contained in the current game's options?

Parameters:
optKey - Name of a SOCGameOption
Returns:
True if option is defined in ths game's options, false otherwise
Since:
1.1.07
See Also:
isGameOptionSet(String), getGameOptionIntValue(String)

isGameOptionSet

public boolean isGameOptionSet(java.lang.String optKey)
Is this boolean-valued game option currently set to true?

Parameters:
optKey - Name of a SOCGameOption of type OTYPE_BOOL, OTYPE_INTBOOL or OTYPE_ENUMBOOL
Returns:
True if option is set, false if not set or not defined in this game's options
Since:
1.1.07
See Also:
isGameOptionDefined(String), getGameOptionIntValue(String), getGameOptionStringValue(String)

isGameOptionSet

public 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?

Parameters:
opts - A map of SOCGameOption, or null
optKey - Name of a SOCGameOption of type OTYPE_BOOL, OTYPE_INTBOOL or OTYPE_ENUMBOOL
Returns:
True if option is set, false if not set or not defined in this set of options
Since:
1.1.07
See Also:
isGameOptionDefined(String), isGameOptionSet(String), getGameOptionIntValue(Map, String), getGameOptionStringValue(Map, String)

getGameOptionIntValue

public int getGameOptionIntValue(java.lang.String optKey)
What is this integer game option's current value?

Does not reference SOCGameOption.getBoolValue(), only the int value, so this will return a value even if the bool value is false.

Parameters:
optKey - A SOCGameOption of type OTYPE_INT, OTYPE_INTBOOL, OTYPE_ENUM or OTYPE_ENUMBOOL
Returns:
Option's current intValue, or 0 if not defined in this game's options; OTYPE_ENUM's choices give an intVal in range 1 to n.
Since:
1.1.07
See Also:
isGameOptionDefined(String), isGameOptionSet(String)

getGameOptionIntValue

public static int getGameOptionIntValue(java.util.Map<java.lang.String,SOCGameOption> opts,
                                        java.lang.String optKey)
What is this integer game option's current value?

Does not reference SOCGameOption.getBoolValue(), only the int value, so this will return a value even if the bool value is false.

Parameters:
opts - A map of SOCGameOption, or null
optKey - A SOCGameOption of type OTYPE_INT, OTYPE_INTBOOL, OTYPE_ENUM or OTYPE_ENUMBOOL
Returns:
Option's current 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.
Since:
1.1.07
See Also:
isGameOptionDefined(String), isGameOptionSet(String), getGameOptionIntValue(Map, String, int, boolean)

getGameOptionIntValue

public 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?

Can optionally reference SOCGameOption.getBoolValue(), not only the int value.

Parameters:
opts - A map of SOCGameOption, or null
optKey - A SOCGameOption of type OTYPE_INT, OTYPE_INTBOOL, OTYPE_ENUM or OTYPE_ENUMBOOL
defValue - Default value to use if optKey not defined
onlyIfBoolSet - 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.
Returns:
Option's current 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.
Since:
1.1.14
See Also:
isGameOptionDefined(String), isGameOptionSet(String), getGameOptionIntValue(Map, String)

getGameOptionStringValue

public java.lang.String getGameOptionStringValue(java.lang.String optKey)
What is this string game option's current value?

Parameters:
optKey - A SOCGameOption of type OTYPE_STR or OTYPE_STRHIDE
Returns:
Option's current getStringValue or null if not defined in this game's options
Since:
1.1.07
See Also:
isGameOptionDefined(String), isGameOptionSet(String)

getGameOptionStringValue

public 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?

Parameters:
opts - A map of SOCGameOption, or null
optKey - A SOCGameOption of type OTYPE_STR or OTYPE_STRHIDE
Returns:
Option's current getStringValue or null if not defined in this set of options
Since:
1.1.07
See Also:
isGameOptionDefined(String), isGameOptionSet(String)

getClientVersionMinRequired

public 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. Calculated by 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.

Returns:
game version, in same format as Version.versionNumber().
Since:
1.1.06

isBoardReset

public boolean isBoardReset()
Returns:
whether this game was created by board reset of an earlier game

getBoard

public SOCBoard getBoard()
Get the game board. When hasSeaBoard, getBoard() can always be cast to SOCBoardLarge.

Returns:
the game board

getPlayers

public SOCPlayer[] getPlayers()
Returns:
the list of players

setPlayer

protected void setPlayer(int pn,
                         SOCPlayer pl)
set the data for a player

Parameters:
pn - the number of the player
pl - the player data
Throws:
java.lang.IllegalArgumentException - if pl is null

getCurrentPlayerNumber

public int getCurrentPlayerNumber()
Returns:
the number of the current player, or -1 if the game isn't started yet

setCurrentPlayerNumber

public void setCurrentPlayerNumber(int pn)
Set the number of the current player, and check for winner. If you want to update other game status, call 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.

Parameters:
pn - the player number, or -1 permitted in state OVER
See Also:
endTurn(), checkForWinner()

getRoundCount

public int getRoundCount()
The number of normal rounds (each player has 1 turn per round, after initial placements), including this round. This is 0 during initial piece placement, and 1 when the first player is about to roll dice for the first time. It becomes 2 when that first player's turn begins again.

Since:
1.1.07

hasBuiltCity

public boolean hasBuiltCity()
Has any player built a city? Used with house-rule 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.

Returns:
True if putPiece(soc.game.SOCPlayingPiece)(SOCCity) has been called for a non-temporary piece
Since:
1.1.19

getCurrentDice

public int getCurrentDice()
Returns:
the current dice result

setCurrentDice

public void setCurrentDice(int dr)
set the current dice result

Parameters:
dr - the dice result

getGameState

public int getGameState()
Current game state. For general information about what states are expected when, please see the javadoc for 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.

Returns:
the current game state
See Also:
isInitialPlacement(), isSpecialBuilding()

setGameState

public void setGameState(int gs)
set the current game state. If the new state is 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.

Parameters:
gs - the game state
See Also:
checkForWinner()

getResetOldGameState

public int getResetOldGameState()
                         throws java.lang.IllegalStateException
If the game board was reset, get the old game state.

Returns:
the old game state
Throws:
java.lang.IllegalStateException - Game state must be RESET_OLD when called; during normal game play, oldGameState is private.

isInitialPlacement

public final boolean isInitialPlacement()
Are we in the Initial Placement part of the game? Includes game states START1A - START3B and STARTS_WAITING_FOR_PICK_GOLD_RESOURCE.

Returns:
true if in Initial Placement
Since:
1.1.12

isForcingEndTurn

public boolean isForcingEndTurn()
If true, this turn is being ended. Controller of game should call 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.

See Also:
forceEndTurn()

isPickResourceIncludingPirateFleet

public final 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.

Parameters:
pn - Player number
Since:
2.0.00

getNumDevCards

public int getNumDevCards()
Get the number of development cards remaining to be bought.

Returns:
the number of dev cards in the deck

setNumDevCards

public void setNumDevCards(int nd)
set the number of dev cards in the deck

Parameters:
nd - the number of dev cards in the deck

getSpecialItemTypes

public java.util.Set<java.lang.String> getSpecialItemTypes()
Get all types of this game's SOCSpecialItems, if any. Only some scenarios and expansions use Special Items. See getSpecialItems(String) for Special Item details and locking.

Returns:
Special item type keys, or null if none
Since:
2.0.00

getSpecialItems

public java.util.ArrayList<SOCSpecialItem> getSpecialItems(java.lang.String typeKey)
Get a list of all special items of a given type in this game. This is not the union of each player's 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.

Parameters:
typeKey - Special item type. Typically a SOCGameOption keyname; see the SOCSpecialItem class javadoc for details.
Returns:
List of all special items of that type, or 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.
Since:
2.0.00
See Also:
SOCPlayer.getSpecialItems(String), getSpecialItemTypes()

getSpecialItem

public 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. This is not the union of each player's 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.

Parameters:
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
Returns:
The special item, or null if none of that type, or if that index is null within the list or is beyond the size of the list
Since:
2.0.00
See Also:
getSpecialItem(String, int, int, int), SOCPlayer.getSpecialItem(String, int), SOCSpecialItem.playerPickItem(String, SOCGame, SOCPlayer, int, int), SOCSpecialItem.playerSetItem(String, SOCGame, SOCPlayer, int, int, boolean)

getSpecialItem

public 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. When both 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.

Parameters:
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 size
pi - Player item index (requires pn != -1), or -1
pn - Owning player number, or -1
Returns:
The special item, or null if none of that type or if that index is null within the list or is beyond the size of the list
Since:
2.0.00
See Also:
getSpecialItem(String, int), SOCPlayer.getSpecialItem(String, int), SOCSpecialItem.playerPickItem(String, SOCGame, SOCPlayer, int, int), SOCSpecialItem.playerSetItem(String, SOCGame, SOCPlayer, int, int, boolean)

setSpecialItem

public SOCSpecialItem setSpecialItem(java.lang.String typeKey,
                                     int idx,
                                     SOCSpecialItem itm)
                              throws java.lang.IndexOutOfBoundsException
Add or replace a special item in the game's list of items of that type. This is not the union of each player's spItems, but a separately maintained list of items. Only some scenarios and expansions use Special Items.

Parameters:
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
Returns:
The item previously at this index, or null if none
Throws:
java.lang.IndexOutOfBoundsException - if idx < 0
Since:
2.0.00
See Also:
SOCPlayer.setSpecialItem(String, int, SOCSpecialItem)

getPlacingItem

public 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). See that method for lifecycle details.

Returns:
The item being placed, or null
Since:
2.0.00

setPlacingItem

public void setPlacingItem(SOCInventoryItem item)
Set or clear the special Inventory Item to be placed by the current player in state 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.

Parameters:
item - The item being placed, or null to clear
Since:
2.0.00
See Also:
getPlacingItem()

getPlayerWithLargestArmy

public SOCPlayer getPlayerWithLargestArmy()
Returns:
the player with the largest army

setPlayerWithLargestArmy

public void setPlayerWithLargestArmy(SOCPlayer pl)
set the player with the largest army

Parameters:
pl - the player

getPlayerWithLongestRoad

public SOCPlayer getPlayerWithLongestRoad()
Returns:
the player with the longest road or trade route, or null if none

setPlayerWithLongestRoad

public void setPlayerWithLongestRoad(SOCPlayer pl)
set the player with the longest road or trade route

Parameters:
pl - the player, or null to clear

getPlayerWithWin

public SOCPlayer getPlayerWithWin()
Find the player who was declared winner at end of game. This is determined in checkForWinner(); there is no corresponding setter.

Returns:
the winning player, or null if none, or if game is not yet over.

setPlayersLandHexCoordinates

public void setPlayersLandHexCoordinates()
                                  throws java.lang.IllegalStateException
For each player, call 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.

Throws:
java.lang.IllegalStateException - if the board has the v1 or v2 encoding
Since:
2.0.00

gameOverMessageToPlayer

public java.lang.String gameOverMessageToPlayer(SOCPlayer pl)
                                         throws java.lang.IllegalStateException
If game is over, formulate a message to tell a player.

Parameters:
pl - Player to tell (may be the winner)
Returns:
A message of one of these forms: "The game is over; you are the winner!" "The game is over; won." "The game is over; no one won."
Throws:
java.lang.IllegalStateException - If the game state is not OVER

advanceTurnBackwards

protected boolean advanceTurnBackwards()
advance the turn to the previous player, used during initial placement. Does not change any other game state, unless all players have left the game. Clears the forcingEndTurn flag.

Returns:
true if the turn advances, false if all players have left and the gamestate has been changed here to OVER.
See Also:
advanceTurn()

advanceTurn

protected boolean advanceTurn()
advance the turn to the next player. Does not change any other game state, unless all players have left the game. Clears the forcingEndTurn flag.

Returns:
true if the turn advances, false if all players have left and the gamestate has been changed here to OVER.
See Also:
advanceTurnBackwards()

advanceTurnToSpecialBuilding

private boolean advanceTurnToSpecialBuilding()
For the 6-player board, check whether we should either start or continue the Special Building Phase. This method does 1 of 4 possible things:

In 1.1.09 and later:

Returns:
true if gamestate is now SPECIAL_BUILDING
Since:
1.1.08

revealFogHiddenHex

public void revealFogHiddenHex(int hexCoord,
                               int hexType,
                               int diceNum)
                        throws java.lang.IllegalArgumentException,
                               java.lang.IllegalStateException
Reveal one land or water hex hidden by fog. Updates board. If a SOCBoard.WATER_HEX is revealed, updates players' legal ship edges.

Parameters:
hexCoord - Coordinate of the hex to reveal
hexType - 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
Throws:
java.lang.IllegalArgumentException - if hexCoord isn't currently a FOG_HEX
java.lang.IllegalStateException - if ! game.hasSeaBoard
Since:
2.0.00

canRemovePort

public boolean canRemovePort(SOCPlayer pl,
                             int edge)
                      throws java.lang.NullPointerException
For scenario option _SC_FTRI, can a "gift" port be removed from this edge?
All these conditions must be met: Does not check whether SOCGameOption.K_SC_FTRI is set.

Parameters:
pl - Player who would remove the port
edge - Port's edge coordinate
Returns:
True if that edge has a port which can be removed now by pl
Throws:
java.lang.NullPointerException - if pl is null
Since:
2.0.00
See Also:
SOCBoardLarge.canRemovePort(int), removePort(SOCPlayer, int), canPlacePort(SOCPlayer, int)

removePort

public SOCInventoryItem removePort(SOCPlayer pl,
                                   int edge)
                            throws java.lang.UnsupportedOperationException,
                                   java.lang.NullPointerException
For scenario option _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.

Parameters:
pl - Player who is removing the port: Must be current player. Ignored at client, null is okay there.
edge - Port's edge coordinate
Returns:
The port removed, with its SOCInventoryItem.itype in range -WOOD_PORT to -MISC_PORT
Throws:
java.lang.UnsupportedOperationException - if ! hasSeaBoard
java.lang.NullPointerException - if pl is null at server

canPlacePort

public boolean canPlacePort(SOCPlayer pl,
                            int edge)
                     throws java.lang.NullPointerException
For scenario option _SC_FTRI, can a "gift" port be placed at this edge?
All these conditions must be met: Does not check whether SOCGameOption.K_SC_FTRI is set. Does not check getGameState().

Parameters:
pl - Player who would place
edge - Edge where a port is wanted; coordinate not checked for validity. SOCPlayer.getPortMovePotentialLocations(boolean) can calculate edges that meet all conditions for canPlacePort.
Returns:
True if a port can be placed at this edge
Throws:
java.lang.NullPointerException - if pl is null
Since:
2.0.00
See Also:
canRemovePort(SOCPlayer, int), placePort(SOCPlayer, int, int)

placePort

public int placePort(int edge)
              throws java.lang.IllegalStateException,
                     java.lang.IllegalArgumentException,
                     java.lang.UnsupportedOperationException
For scenario option _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.

Parameters:
edge - An available coastal edge adjacent to pl's settlement or city, which should be checked with canPlacePort(SOCPlayer, int)
Returns:
ptype The type of port placed (in range MISC_PORT to WOOD_PORT)
Throws:
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
Since:
2.0.00
See Also:
placePort(SOCPlayer, int, int), removePort(SOCPlayer, int)

placePort

public void placePort(SOCPlayer pl,
                      int ptype,
                      int edge)
               throws java.lang.IllegalArgumentException,
                      java.lang.NullPointerException,
                      java.lang.UnsupportedOperationException
For scenario option _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).

Parameters:
pl - Player who is placing
ptype - 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)
Throws:
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
Since:
2.0.00
See Also:
placePort(int), removePort(SOCPlayer, int)

canPlaceShip

public 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(). Does not check game state, resources, or pieces remaining.

Parameters:
pl - Player
shipEdge - Edge to place a ship
Returns:
true if this player's ship could be placed there
Since:
2.0.00
See Also:
canMoveShip(int, int, int), SOCPlayer.getNumPieces(int)

putPiece

public void putPiece(SOCPlayingPiece pp)
Put this piece on the board and update all related game state. May change current player and gamestate. Calls 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).

Actions taken:

Calls 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().

Valid placements:

Because pp is not checked for validity, please call methods such as 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.
For settlements, call SOCPlayer.canPlaceSettlement(int) to check potentials and other game conditions.
For ships, call canPlaceShip(SOCPlayer, int) to check the potentials and pirate ship location.

Other things to note:

For some scenarios on the 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.

Parameters:
pp - the piece to put on the board; coordinates are not checked for validity, see "valid placements" note

putPieceCommon

private void putPieceCommon(SOCPlayingPiece pp,
                            boolean isTempPiece)
Put a piece or temporary piece on the board, and update all related game state. Update player potentials, longest road, reveal fog hexes at server, etc. Common to putPiece(SOCPlayingPiece) and putTempPiece(SOCPlayingPiece). See putPiece(SOCPlayingPiece) javadoc for more information on what putPieceCommon does.

Parameters:
pp - The piece to put on the board; coordinates are not checked for validity
isTempPiece - Is this a temporary piece? If so, do not change current player or gamestate, or call our SOCScenarioEventListener.
Since:
1.1.14

putPieceCommon_checkFogHexes

private final 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. Reveal it before placing the new piece, so it's easier for players and bots to updatePotentials (their data about the board reachable through their roads/ships). Each revealed fog hex triggers 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.

Parameters:
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.
Since:
2.0.00

advanceTurnStateAfterPutPiece

private boolean advanceTurnStateAfterPutPiece()
After placing a piece on the board, update the state of the game, and possibly current player, for play to continue.

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.

Returns:
true if the turn advances, false if all players have left and the gamestate has been changed here to OVER.

putTempPiece

public void putTempPiece(SOCPlayingPiece pp)
A temporary piece has been put on the board; update all related game state. Update player potentials, longest road, etc. Does not advance turn or update gamestate-related fields.

Parameters:
pp - the piece to put on the board
See Also:
undoPutTempPiece(SOCPlayingPiece), saveLargestArmyState()

canMoveShip

public 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. Game state must be 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.

Parameters:
pn - Player number
fromEdge - Edge coordinate to move the ship from; must contain this player's ship
Returns:
The ship, if the player can move the ship now; null otherwise
Since:
2.0.00
See Also:
canMoveShip(int, int, int)

canMoveShip

public 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. Game state must be 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.

Parameters:
pn - Player number
fromEdge - 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).
Returns:
The ship, if the player can move the ship now; null otherwise
Since:
2.0.00
See Also:
canMoveShip(int, int), moveShip(SOCShip, int)

moveShip

public void moveShip(SOCShip sh,
                     int toEdge)
Move this ship on the board and update all related game state. Calls 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.

Parameters:
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 to
Since:
2.0.00

removeShip

public void removeShip(SOCShip sh)
Remove this ship from the board and update all related game state. Used in scenario option _SC_PIRI by attackPirateFortress(SOCShip) and at the client.

Calls undoPutPieceCommon(sh, false). Not for use with temporary pieces.

Parameters:
sh - the ship to remove
Since:
2.0.00

undoPutPieceCommon

protected void undoPutPieceCommon(SOCPlayingPiece pp,
                                  boolean isTempPiece)
undo the putting of a temporary or initial piece or a ship being moved. If state is START2B or START3B and resources were given, they will be returned.

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.

Parameters:
pp - the piece to remove from the board
isTempPiece - Is this a temporary piece? If so, do not call the game's SOCScenarioEventListener.

undoPutTempPiece

public void undoPutTempPiece(SOCPlayingPiece pp)
undo the putting of a temporary piece

Parameters:
pp - the piece to remove from the board
See Also:
undoPutInitSettlement(SOCPlayingPiece), restoreLargestArmyState()

undoPutInitSettlement

public void undoPutInitSettlement(SOCPlayingPiece pp)
undo the putting of an initial settlement. If state is START2B or START3B and resources were given, they will be returned. Player is unchanged; state will become START1A or START2A or START3A. Not for use with temporary pieces (use undoPutTempPiece(SOCPlayingPiece) instead).

Parameters:
pp - the piece to remove from the board
See Also:
canCancelBuildPiece(int)

startGame

public 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. gameState becomes 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_setupDevCards

private final void startGame_setupDevCards()
For startGame(), fill and shuffle the development card deck. devCardDeck contents are based on game options and number of players.

Since:
2.0.00

setFirstPlayer

public void setFirstPlayer(int pn)
Sets who the first player is. Based on pn and on vacant seats, also recalculates lastPlayer.

Parameters:
pn - the seat number of the first player, or -1 if not set yet

getFirstPlayer

public int getFirstPlayer()
Returns:
the seat number of the first player

canEndTurn

public boolean canEndTurn(int pn)
Can this player end the current turn?

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).

Parameters:
pn - player number of the player who wants to end the turn
Returns:
true if okay for this player to end the turn (They are current player, game state is PLAY1 or SPECIAL_BUILDING)
See Also:
endTurn(), forceEndTurn()

endTurn

public void endTurn()
end the turn for the current player, and check for winner. If no winner yet, set up for the next player's turn (see below). Check for gamestate >= 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().

See Also:
checkForWinner(), forceEndTurn(), isForcingEndTurn()

updateAtBoardLayout

public void updateAtBoardLayout()
Update any miscellaneous game info as needed after the board layout is set, before the game starts.

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.

Since:
2.0.00

updateAtGameFirstTurn

private void updateAtGameFirstTurn()
Update game state as needed after initial placement before the first turn of normal play:

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.

Since:
2.0.00

updateAtTurn

public void updateAtTurn()
Update game state as needed when a player begins their turn (before dice are rolled).

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.

Called by server and client. At client, call this after setGameState(int) and setCurrentPlayerNumber(int). At server, this is called from within endTurn().

Since:
1.1.07

forceEndTurn

public SOCForceEndTurnResult forceEndTurn()
                                   throws java.lang.IllegalStateException
In an active game, force current turn to be able to be ended. May be used if player loses connection, or robot does not respond. Takes whatever action needed to force current player to end their turn, and if possible, sets state to 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:

See also SOCGameHandler.forceEndGameTurn, SOCGameHandler.endGameTurnOrForce.

Returns:
Type of action performed, one of these values:
Throws:
java.lang.IllegalStateException - if game is not active (gamestate < START1A or >= OVER)
See Also:
canEndTurn(int), endTurn()

forceEndTurnStartState

private SOCForceEndTurnResult forceEndTurnStartState(boolean advTurnForward)
Special forceEndTurn() treatment for start-game states. Changes gameState and usually 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.

Parameters:
advTurnForward - Should the next player be normal (placing first settlement), or backwards (placing second settlement)?
Returns:
A forceEndTurn result of type SOCForceEndTurnResult.FORCE_ENDTURN_SKIP_START_ADV, SOCForceEndTurnResult.FORCE_ENDTURN_SKIP_START_ADVBACK, or SOCForceEndTurnResult.FORCE_ENDTURN_SKIP_START_TURN.

forceEndTurnChkDiscardOrGain

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). 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.

Parameters:
pn - Player number to force to randomly discard or gain
isDiscard - True to discard resources, false to gain
Returns:
The force result, including any discarded or gained resources. Type will be SOCForceEndTurnResult.FORCE_ENDTURN_RSRC_DISCARD or SOCForceEndTurnResult.FORCE_ENDTURN_RSRC_DISCARD_WAIT.
See Also:
playerDiscardOrGainRandom(int, boolean)

discardOrGainPickRandom

public static void discardOrGainPickRandom(SOCResourceSet fromHand,
                                           int numToPick,
                                           boolean isDiscard,
                                           SOCResourceSet picks,
                                           java.util.Random rand)
                                    throws java.lang.IllegalArgumentException
Choose discards at random; does not actually discard anything. For discards, randomly choose from contents of fromHand. For gains, randomly choose resource types least plentiful in fromHand.

Parameters:
fromHand - Discard from this set, or gain to add to this set
numToPick - This many must be discarded or gained
isDiscard - True to discard resources, false to gain
picks - Add the picked resources to this set (typically new and empty when called)
rand - Source of random
Throws:
java.lang.IllegalArgumentException - if isDiscard and numDiscards > fromHand.getKnownTotal()

playerDiscardOrGainRandom

public SOCResourceSet playerDiscardOrGainRandom(int pn,
                                                boolean isDiscard)
                                         throws java.lang.IllegalStateException
Force this non-current player to discard or gain resources randomly. Used at server when a player must discard or pick free resources and player loses connection while the game is waiting for them, or a bot is unresponsive.

On return, gameState will be:

Before v2.0.00, this method was playerDiscardRandom(..).

Parameters:
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)
Returns:
Set of resource cards which were discarded or gained
Throws:
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.

canRollDice

public boolean canRollDice(int pn)
Parameters:
pn - player number of the player who wants to roll
Returns:
true if it's ok for this player to roll the dice

rollDice

public SOCGame.RollResult rollDice()
roll the dice. Distribute resources, or (for 7) set gamestate to move robber or to wait for players to discard. 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.
Checks game option N7: Roll no 7s during first # rounds and N7C: Roll no 7s until a city is built.

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.

Returns:
The roll results: Dice numbers, and any scenario-specific results such as SOCGame.RollResult.cloth. The game reuses the same instance each turn, so its field contents will change when rollDice() is called again.

rollDice_update7gameState

private final void rollDice_update7gameState()
When a 7 is rolled, update the 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.

Since:
2.0.00

getResourcesGainedFromRoll

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.

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.

Parameters:
player - the player
roll - the total number rolled on the dice
Returns:
the resource set

getResourcesGainedFromRollPieces

private final 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. Used in 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.

Parameters:
roll - the total number rolled on the dice
resources - Add new resources to this set
robberHex - Robber's position, from SOCBoard.getRobberHex()
sEnum - Enumeration of a type of the player's SOCPlayingPieces; should be either SOCSettlements or SOCCitys
incr - Add this many resources (1 or 2) per playing piece
Since:
1.1.17

canDiscard

public boolean canDiscard(int pn,
                          SOCResourceSet rs)
Parameters:
pn - the number of the player that is discarding
rs - the resources that the player is discarding
Returns:
true if the player can discard these resources
See Also:
discard(int, SOCResourceSet)

discard

public void discard(int pn,
                    SOCResourceSet rs)
A player is discarding resources. Discard, check if other players must still discard, and set gameState to 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.

Parameters:
pn - the number of the player
rs - the resources that are being discarded

canPickGoldHexResources

public boolean canPickGoldHexResources(int pn,
                                       SOCResourceSet rs)
Can the player pick these resources from the gold hex? rs.getTotal() must == SOCPlayer.getNeedToPickGoldHexResources(). Game state must be WAITING_FOR_PICK_GOLD_RESOURCE or STARTS_WAITING_FOR_PICK_GOLD_RESOURCE.

Parameters:
pn - the number of the player that is picking
rs - the resources that the player is picking
Returns:
true if the player can pick these resources
Since:
2.0.00
See Also:
pickGoldHexResources(int, SOCResourceSet)

pickGoldHexResources

public void pickGoldHexResources(int pn,
                                 SOCResourceSet rs)
A player is picking which resources to gain from the gold hex. Gain them, check if other players must still pick, and set gameState to 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).

Parameters:
pn - the number of the player
rs - the resources that are being picked
Since:
2.0.00

canChooseMovePirate

public boolean canChooseMovePirate()
Based on game options, can the pirate ship be moved instead of the robber? True only if hasSeaBoard.

Returns:
true if the pirate ship can be moved
Since:
2.0.00
See Also:
WAITING_FOR_ROBBER_OR_PIRATE, chooseMovePirate(boolean)

chooseMovePirate

public void chooseMovePirate(boolean pirateNotRobber)
                      throws java.lang.IllegalStateException
Choose to move the pirate or the robber, from game state 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.

Parameters:
pirateNotRobber - True to move pirate, false to move robber
Throws:
java.lang.IllegalStateException - if gameState != WAITING_FOR_ROBBER_OR_PIRATE
Since:
2.0.00

canMoveRobber

public boolean canMoveRobber(int pn,
                             int co)
Can this player currently move the robber to these coordinates? Must be different from current robber coordinates. Must not be a desert if game option RD is set to true ("Robber can't return to the desert"). Must be current player. Game state must be PLACING_ROBBER.

Parameters:
pn - the number of the player that is moving the robber
co - the new robber hex coordinates; not validated
Returns:
true if the player can move the robber to the coordinates
See Also:
moveRobber(int, int), canMovePirate(int, int)

moveRobber

public SOCMoveRobberResult moveRobber(int pn,
                                      int rh)
                               throws java.lang.IllegalArgumentException
move the robber.

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.

Parameters:
pn - the number of the player that is moving the robber
rh - the robber's new hex coordinate; must be > 0, not validated beyond that
Returns:
returns a result that says if a resource was stolen, or if the player needs to make a choice. It also returns what was stolen and who was the victim. The private robberResult field is updated to this return value.
Throws:
java.lang.IllegalArgumentException - if rh <= 0

canMovePirate

public 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). 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.

Parameters:
pn - the number of the player that is moving the pirate
hco - the new pirate hex coordinates; will check for a water hex
Returns:
true if this player can move the pirate ship to this hex coordinate
Since:
2.0.00
See Also:
movePirate(int, int), canMoveRobber(int, int)

movePirate

public SOCMoveRobberResult movePirate(int pn,
                                      int ph)
                               throws java.lang.IllegalArgumentException
Move the pirate ship. Update the private robberResult field.

Called only at server. Client gets messages with results of the move, and calls SOCBoardLarge.setPirateHex(int, boolean).

Normal operation:

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.

Parameters:
pn - the number of the player that is moving the pirate ship
ph - the pirate's new hex coordinate; should be a water hex
Returns:
returns a result that says if a resource was stolen, or if the player needs to make a choice. It also returns what was stolen and who was the victim.

In scenario _SC_PIRI only, might contain SOCResourceConstants.GOLD_LOCAL if the player wins; see movePirate(int, int, int) for details.

Throws:
java.lang.IllegalArgumentException - if ph <= 0
Since:
2.0.00

movePirate

private SOCMoveRobberResult movePirate(int pn,
                                       int ph,
                                       int pirFleetStrength)
                                throws java.lang.IllegalArgumentException
Move the pirate, optionally with a pirate fleet strength. The fleet strength is used by 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.

Parameters:
pn - the number of the player that is moving the pirate ship
ph - the pirate's new hex coordinate; should be a water hex
pirFleetStrength - Pirate fleet strength, or -1 if not scenario _SC_PIRI
Returns:
see movePirate(int, int)
Throws:
java.lang.IllegalArgumentException - if ph < 0
Since:
2.0.00

canChoosePlayer

public 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. To choose the player and rob, call choosePlayerForRobbery(int).

Parameters:
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.
Returns:
true if the current player can choose this player to rob
See Also:
getRobberyPirateFlag(), getPossibleVictims(), canChooseRobClothOrResource(int), stealFromPlayer(int, boolean)

choosePlayerForRobbery

public int choosePlayerForRobbery(int pn)
The current player has chosen a victim to rob. Do that, unless they must choose whether to rob cloth or a resource. Calls 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.

Parameters:
pn - the number of the player being robbed
Returns:
the type of resource that was stolen, as in SOCResourceConstants, or 0 if must choose first (state WAITING_FOR_ROB_CLOTH_OR_RESOURCE), or SOCResourceConstants.CLOTH_STOLEN_LOCAL for cloth.
Since:
2.0.00

canChooseRobClothOrResource

public 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()). True only if the player has both cloth and resources.

Assumes canChoosePlayer(int) has been called already.

Used with scenario option _SC_CLVI.

Parameters:
pn - Player number to check
Returns:
true only if current player can choose to rob either cloth or resources from pn.
Since:
2.0.00

canAttackPirateFortress

public 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).

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.

Returns:
Current player's ship adjacent to their SOCFortress, or null if they can't attack
Since:
2.0.00

attackPirateFortress

public int[] attackPirateFortress(SOCShip adjacent)
The current player has built ships to their pirate fortress, and attacks now to try to conquer and recapture it. This can happen at most once per turn: Attacking the fortress always ends the player's turn. Assumes 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.

Parameters:
adjacent - The current player's ship adjacent to their SOCFortress, from canAttackPirateFortress(); unless player wins, this ship will be lost to the pirates.
Returns:
Results array, whose length depends on the number of ships lost by the player to the pirates' defense.
results[0] is the pirate defense strength rolled here.
  • If the player wins, they lose no ships. Array length is 1.
  • If the player ties the pirates, they lose their 1 adjacent ship. Array length is 2; results[1] is adjacent's coordinates.
  • If the player loses to the pirates, they lose their 2 ships closest to the pirate fortress. Array length is 3; results[1] is adjacent's coordinates, results[2] is the other lost ship's coord.
Since:
2.0.00

getPlayersOnHex

public java.util.Vector<SOCPlayer> getPlayersOnHex(int hex)
Get the players who have settlements or cities on this hex.

Parameters:
hex - the coordinates of the hex; not checked for validity
Returns:
a list of 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.

getPlayersShipsOnHex

public java.util.Vector<SOCPlayer> getPlayersShipsOnHex(int hex)
Parameters:
hex - the coordinates of the hex
Returns:
a list of players touching a hex with ships, or an empty Vector if none
Since:
2.0.00

getFortress

public SOCFortress getFortress(int node)
For scenario option _SC_PIRI, get the Pirate Fortress at this node location, if any. A player must defeat 'their' fortress to win.

Parameters:
node - Coordinate to check for fortress
Returns:
Fortress at that location, or null if none or if _SC_PIRI not active. If the player has already defeated their fortress, this will return null, like SOCPlayer.getFortress(); use SOCBoard.settlementAtNode(int) to get the settlement that it's converted into after defeat.
Since:
2.0.00

getRobberyPirateFlag

public 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.

Returns:
true for pirate ship, false for robber
Since:
2.0.00

getPossibleVictims

public 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. 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).

Returns:
a list of possible players to rob, or an empty Vector
See Also:
canChoosePlayer(int), choosePlayerForRobbery(int)

stealFromPlayer

public int stealFromPlayer(int pn,
                           boolean choseCloth)
the current player has choosen a victim to rob. perform the robbery. Set gameState back to oldGameState. The current player gets the stolen item.

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.

Parameters:
pn - the number of the player being robbed
choseCloth - 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.
Returns:
the type of resource that was stolen, as in SOCResourceConstants, or SOCResourceConstants.CLOTH_STOLEN_LOCAL for cloth.
See Also:
stealFromPlayerPirateFleet(int, int)

stealFromPlayerPirateFleet

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. 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:

Assumes proper game state and scenario, does not validate those or pn.

Parameters:
pn - The player number being robbed; not validated
pirFleetStrength - Pirate fleet strength, from rollDice() dice roll
Since:
2.0.00
See Also:
stealFromPlayer(int, boolean)

hasTradeOffers

public boolean hasTradeOffers()
Are there currently any trade offers? Calls each player's SOCPlayer.getCurrentOffer().

Returns:
true if any, false if not
Since:
1.1.12

canMakeTrade

public 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.

Parameters:
offering - the number of the player making the offer
accepting - the number of the player accepting the offer
Returns:
true if the two players can make the trade described in the offering players current offer
See Also:
canMakeBankTrade(SOCResourceSet, SOCResourceSet)

makeTrade

public void makeTrade(int offering,
                      int accepting)
perform a trade between two players. the trade performed is described in the offering player's current offer.

Assumes canMakeTrade(int, int) already was called. If game option "NT" is set, players can trade only with the bank, not with other players.

Parameters:
offering - the number of the player making the offer
accepting - the number of the player accepting the offer
See Also:
makeBankTrade(SOCResourceSet, SOCResourceSet)

canUndoBankTrade

public 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.

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.

Parameters:
undo_gave - Undo giving these resources (get these back from the bank)
undo_got - Undo getting these resources (give these back to the bank)
Returns:
true if the current player can undo a bank trade of these resources
Since:
1.1.13

canMakeBankTrade

public boolean canMakeBankTrade(SOCResourceSet give,
                                SOCResourceSet get)
Parameters:
give - what the player will give to the bank
get - what the player wants from the bank
Returns:
true if the current player can make a particular bank/port trade
See Also:
canUndoBankTrade(SOCResourceSet, SOCResourceSet)

makeBankTrade

public void makeBankTrade(SOCResourceSet give,
                          SOCResourceSet get)
perform a bank trade, or undo the last bank trade.

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).

Parameters:
give - what the player will give to the bank
get - what the player wants from the bank

couldBuildRoad

public boolean couldBuildRoad(int pn)
Parameters:
pn - the number of the player
Returns:
true if the player has the resources, pieces, and room to build a road

couldBuildSettlement

public boolean couldBuildSettlement(int pn)
Parameters:
pn - the number of the player
Returns:
true if the player has the resources, pieces, and room to build a settlement
See Also:
SOCPlayer.canPlaceSettlement(int)

couldBuildCity

public boolean couldBuildCity(int pn)
Parameters:
pn - the number of the player
Returns:
true if the player has the resources, pieces, and room to build a city

couldBuyDevCard

public boolean couldBuyDevCard(int pn)
Parameters:
pn - the number of the player
Returns:
true if the player has the resources to buy a dev card, and if there are dev cards left to buy
See Also:
buyDevCard()

couldBuildShip

public boolean couldBuildShip(int pn)
Parameters:
pn - the number of the player
Returns:
true if the player has the resources, pieces, and room to build a ship. Always false if not hasSeaBoard because players would have 0 ship pieces.
Since:
2.0.00
See Also:
canPlaceShip(SOCPlayer, int)

buyRoad

public void buyRoad(int pn)
a player is buying a road. Assumes couldBuildRoad(int) is true, does not check it here.

Parameters:
pn - the number of the player
See Also:
putPiece(SOCPlayingPiece), cancelBuildRoad(int)

buySettlement

public void buySettlement(int pn)
a player is buying a settlement. Assumes couldBuildSettlement(int) is true, does not check it here.

Parameters:
pn - the number of the player
See Also:
putPiece(SOCPlayingPiece), cancelBuildSettlement(int)

buyCity

public void buyCity(int pn)
a player is buying a city. Assumes couldBuildCity(int) is true, does not check it here.

Parameters:
pn - the number of the player
See Also:
putPiece(SOCPlayingPiece), cancelBuildCity(int)

buyShip

public void buyShip(int pn)
a player is buying a city. Assumes couldBuildShip(int) is true, does not check it here.

Parameters:
pn - the number of the player
Since:
2.0.00
See Also:
putPiece(SOCPlayingPiece), cancelBuildShip(int)

canCancelBuildPiece

public 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. In v1.1.17+, also true in PLACING_FREE_ROAD2 to skip the second placement.

Parameters:
buildType - Piece type (SOCPlayingPiece.ROAD, CITY, etc)
Returns:
true if current game state allows it
Since:
1.1.17
See Also:
cancelBuildRoad(int)

cancelBuildRoad

public boolean cancelBuildRoad(int pn)
a player is UNbuying a road; return resources, set gameState PLAY1 (or SPECIAL_BUILDING)

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.

Parameters:
pn - the number of the player
Returns:
true if resources were returned (false if PLACING_FREE_ROAD2)

cancelBuildSettlement

public void cancelBuildSettlement(int pn)
a player is UNbuying a settlement; return resources, set gameState PLAY1 (or SPECIAL_BUILDING)

To cancel an initial settlement, call undoPutInitSettlement(SOCPlayingPiece) instead.

Parameters:
pn - the number of the player

cancelBuildCity

public void cancelBuildCity(int pn)
a player is UNbuying a city; return resources, set gameState PLAY1 (or SPECIAL_BUILDING)

Parameters:
pn - the number of the player

cancelBuildShip

public boolean cancelBuildShip(int pn)
a player is UNbuying a ship; return resources, set gameState PLAY1 (or SPECIAL_BUILDING)

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.

Parameters:
pn - the number of the player
Returns:
true if resources were returned (false if PLACING_FREE_ROAD2)
Since:
2.0.00

cancelPlaceInventoryItem

public SOCInventoryItem cancelPlaceInventoryItem(boolean forceEndTurn)
In state 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.

Parameters:
forceEndTurn - If true, player's turn is being ended. Return item to inventory even if ! item.canCancelPlay.
Returns:
The item that was being placed, or null if none or if placement can't be canceled for this type
Since:
2.0.00

isShipWarship

public 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. (Those are the ships heading out to sea starting at the player's coastal settlement.)

Parameters:
sh - A ship whose player is in this game
Returns:
True if SOCPlayer.getRoads() contains, among its first SOCPlayer.getNumWarships() ships, a ship located at sh.getCoordinates().
Since:
2.0.00
See Also:
playKnight()

buyDevCard

public int buyDevCard()
the current player is buying a dev card.

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.

Returns:
the card that was drawn; a dev card type from SOCDevCardConstants.

canPlayKnight

public boolean canPlayKnight(int pn)
Can this player currently play a knight card? gameState must be 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.

Parameters:
pn - the number of the player
Returns:
true if the player can play a knight card

canPlayRoadBuilding

public boolean canPlayRoadBuilding(int pn)
Can the current player play a Road Building card?

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.

Parameters:
pn - the number of the player
Returns:
true if the player can play a Road Building card.
See Also:
playRoadBuilding()

canPlayDiscovery

public boolean canPlayDiscovery(int pn)
return true if the player can play a Discovery card

Parameters:
pn - the number of the player

canPlayMonopoly

public boolean canPlayMonopoly(int pn)
return true if the player can play a Monopoly card

Parameters:
pn - the number of the player

canPlayInventoryItem

public int canPlayInventoryItem(int pn,
                                int itype)
Can this player play this special 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.

Recognized scenario game options with special items:

Parameters:
pn - Player number
itype - Inventory item type, from SOCInventoryItem.itype
Returns:
the results of the check:
  • 0 if can be played now
  • 1 if no playable itype in player's SOCInventory
  • 2 if game doesn't have a scenario option that permits special items to be played
  • 3 if cannot be played right now (game state, current player, etc)
  • or any other nonzero scenario-specific detail code for why the item can't be played now
Since:
2.0.00
See Also:
playInventoryItem(int)

playInventoryItem

public SOCInventoryItem playInventoryItem(int itype)
Play a special 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.
Recognized scenario game options with special items:

Parameters:
itype - Special item type, from SOCInventoryItem.itype
Returns:
The item played, or 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.

playKnight

public void playKnight()
The current player plays a Knight card. Assumes 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).


playRoadBuilding

public void playRoadBuilding()
The current player plays a Road Building card. This card directs the player to place 2 roads or ships, or 1 road and 1 ship. If they have 2 or more roads or ships, may place 2; gameState becomes PLACING_FREE_ROAD1. If they have just 1 road/ship, may place that; gameState becomes PLACING_FREE_ROAD2. (Checks of game rules online show "MAY" or "CAN", not "MUST" place 2.) If they have 0 roads, cannot play the card.

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.


playDiscovery

public void playDiscovery()
the current player plays a Discovery card


playMonopoly

public void playMonopoly()
the current player plays a monopoly card


canDoDiscoveryAction

public boolean canDoDiscoveryAction(SOCResourceSet pick)
Parameters:
pick - the resources that the player wants
Returns:
true if the current player can do the discovery card action and the pick contains exactly 2 resources

canDoMonopolyAction

public boolean canDoMonopolyAction()
Returns:
true if the current player can do the Monopoly card action

doDiscoveryAction

public void doDiscoveryAction(SOCResourceSet pick)
perform the Discovery card action

Parameters:
pick - what the player picked

doMonopolyAction

public int[] doMonopolyAction(int rtype)
perform the Monopoly card action. Resources are taken from players that have it. Game state becomes oldGameState (returns to state before monopoly pick).

Parameters:
rtype - the type of resource to monopolize
Returns:
array (1 elem per player) of resource count taken from each player. 0 for players with nothing taken. 0 for the current player (playing the monopoly card).

updateLargestArmy

public void updateLargestArmy()
update which player has the largest army larger than 2


saveLargestArmyState

public void saveLargestArmyState()
Save the state of who has largest army. This is a field, not a stack, so do not call twice unless you call restoreLargestArmyState() between them.


restoreLargestArmyState

public void restoreLargestArmyState()
Restore the state of who had largest army. This is a field, not a stack, so do not call twice unless you call saveLargestArmyState() between them.


updateLongestRoad

public void updateLongestRoad(int pn)
update which player has longest road longer than 4. this version recalculates the longest road only for the player who is affected by the most recently placed piece, by calling their 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.

Parameters:
pn - the number of the player who is affected

checkForWinner

public void checkForWinner()
check current player's vp total to see if the game is over. If so, set game state to 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):

See Also:
getGameState(), getPlayerWithWin()

checkForWinner_SC_CLVI

private final boolean checkForWinner_SC_CLVI()
Check if less than half the villages have cloth remaining. (If half or more still have cloth, return false without changing game state.) If so, end the game; see checkForWinner() for details. Sets state to OVER. Returns true. Caller should fire SOCScenarioGameEvent.SGE_CLVI_WIN_VILLAGE_CLOTH_EMPTY.

Returns:
true if game has ended with a winner under this special condition
Since:
2.0.00

destroyGame

public void destroyGame()
set vars to null so gc can clean up


resetAsCopy

public SOCGame resetAsCopy()
Create a new game with same players and name, new board; like calling constructor otherwise. State of current game can be any state. State of copy is 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.

See Also:
resetVoteBegin(int)

resetVoteBegin

public void resetVoteBegin(int reqPN)
                    throws java.lang.IllegalArgumentException,
                           java.lang.IllegalStateException
Begin a board-reset vote. The requester is marked as voting yes, and we mark other players as "no vote yet". Wait for other human players to vote.

Parameters:
reqPN - Player number requesting the vote
Throws:
java.lang.IllegalArgumentException - If this player number has already requested a reset this turn
java.lang.IllegalStateException - If there is already a vote in progress
See Also:
getResetVoteRequester(), resetVoteRegister(int, boolean), getResetVoteResult()

getResetVoteRequester

public int getResetVoteRequester()
If a board reset vote is active, player number who requested the vote. All human players must vote unanimously, or board reset is rejected. -1 if no vote is active. After the vote completes, this is set to -1 if the vote was rejected, but retains the requester number if the vote succeeded and the board will soon be reset.

Returns:
player number who requested the vote.
See Also:
resetVoteBegin(int)

getResetVoteActive

public boolean getResetVoteActive()
Returns:
if a board-reset vote is active (waiting for votes).

resetVoteRegister

public boolean resetVoteRegister(int pn,
                                 boolean votingYes)
                          throws java.lang.IllegalArgumentException,
                                 java.lang.IllegalStateException
Register this player's vote in a board reset request.

Parameters:
pn - Player number
votingYes - Are they voting yes, or no?
Returns:
True if voting is now complete, false if still waiting for other votes
Throws:
java.lang.IllegalArgumentException - If pn already voted, or can't vote (vacant or robot).
java.lang.IllegalStateException - If voting is not currently active.
See Also:
getResetPlayerVote(int)

getResetPlayerVote

public int getResetPlayerVote(int pn)
Get this player's vote on a board reset request.

Parameters:
pn - Player number
Returns:
Vote value for player: VOTE_YES, VOTE_NO, or if player hasn't yet voted, VOTE_NONE.
See Also:
resetVoteRegister(int, boolean), getResetVoteResult()

resetVoteClear

public void resetVoteClear()
At end of turn, clear flags for board reset voting: requester, players' setAskedBoardReset. This is outside of 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.


getResetVoteResult

public boolean getResetVoteResult()
                           throws java.lang.IllegalStateException
If a board-reset vote is complete, give its result. All human players must vote unanimously, or board reset is rejected.

Returns:
True if accepted, false if rejected.
Throws:
java.lang.IllegalStateException - if voting is still active. See getResetVoteActive().
See Also:
getResetPlayerVote(int)

canBuyOrAskSpecialBuild

public 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.

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.

Parameters:
pn - Player number
Since:
1.1.08
See Also:
canAskSpecialBuild(int, boolean)

isSpecialBuilding

public boolean isSpecialBuilding()
During game play, are we in the Special Building Phase? Includes game state SPECIAL_BUILDING, and placement game states during this phase.

Returns:
true if in Special Building Phase
Since:
1.1.08

canAskSpecialBuild

public boolean canAskSpecialBuild(int pn,
                                  boolean throwExceptions)
                           throws java.lang.IllegalStateException,
                                  java.lang.IllegalArgumentException
For 6-player mode's 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().

Parameters:
pn - The player's number
Throws:
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).
Since:
1.1.08
See Also:
canBuyOrAskSpecialBuild(int)

askSpecialBuild

public void askSpecialBuild(int pn,
                            boolean onlyIfCan)
                     throws java.lang.IllegalStateException,
                            java.lang.IllegalArgumentException
For 6-player mode's Special Building Phase, check state and set the flag for this player asking to build.

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.

Parameters:
pn - The player's number
onlyIfCan - Check if player can do so, before setting player and game flags. Should always be true for server calls.
Throws:
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).
Since:
1.1.08

isDebugFreePlacement

public boolean isDebugFreePlacement()
Are we in the 'free placement' debug mode? See SOCGameHandler.processDebugCommand_freePlace, SOCPlayerInterface.setDebugPaintPieceMode.

Since:
1.1.12
See Also:
putPiece(SOCPlayingPiece)

setDebugFreePlacement

public void setDebugFreePlacement(boolean debugOn)
                           throws java.lang.IllegalStateException
Turn the "free placement" debug mode on or off, if possible.

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.

Parameters:
debugOn - Should the mode be on?
Throws:
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.
Since:
1.1.12

toString

public java.lang.String toString()
toString contains the game name.

Overrides:
toString in class java.lang.Object
Returns:
"SOCGame{" + gameName + "}"
Since:
1.1.12