package de.lmu.ifi.pp.player; import java.util.regex.Pattern; import de.lmu.ifi.pp.model.Coord; import de.lmu.ifi.pp.model.PieceColor; import de.lmu.ifi.pp.player.action.LobbyAction; import de.lmu.ifi.pp.util.net.ProtocolConstants; /** * Basic idea: *
*
- The server always calls the player (and never vice-versa): The player * connects to the server (via a socket) and then waits for its "procedures" to * be invoked by the server via "remote procedure calls" (RPCs). The available * procedures are the methods of this interface, the RPC conventions are * outlined below. *
* * RPC conventions: *
*
- Caller: Sends method name and arguments, separated by tab, terminated by * newline *
- Callee: Sends return value, terminated by newline *
* * Tournament versus Lobby: *
*
- Player closes the socket *
*
- Tournament: can reconnect later. *
- Lobby: leaves the lobby. *
*
* * Serialization of types: *
*
- void: "OK" *
- boolean: "true" bzw. "false" *
- PieceColor: "BLACK", "WHITE", "null" *
- Coord: "0,2" // x,y, coordinate system starts in the upper left corner * at (0,0) *
- String: strings with tab are not allowed as arguments *
- String[] (as single arguments and return values): transmitted as one * string, separated by {@link #SEP}. *
* * History: *
*
- V1.0: First public version. *
- V1.1: Additional argument for openGame(), new method error(), removed * one argument from closeGame() *
- V1.2: trackAndComputeMove(), changed legal names, separate * {@link ProtocolConstants} *
- V1.3: lobby mode *
- V1.4: ACTION_PLAY extended to include a choice of color, *
getRules()
changed to {@link #setRuleKind(String)} *
- V1.5: More comments to clarify the specification *
*/ public interface PlayerInterface extends ProtocolConstants { /** * Used by the server to check for legal names. */ public static final Pattern LEGAL_NAME = Pattern.compile("^[0-9][0-9] ([A-ZÄÖÜa-zäöü0-9 !?.-]+)$"); public static final String RULES_MODE_TOURNAMENT = "Tournament"; public static final String RULES_MODE_LOBBY = "Lobby"; public static final String RULES_GAME_TICTACTOE = "TicTacToe"; public static final String RULES_GAME_REVERSI = "Reversi"; public static final String RULES_SEP = "-"; public static final String RULES_KIND_REVERSI_TOURNAMENT = RULES_GAME_REVERSI+RULES_SEP+RULES_MODE_TOURNAMENT; public static final String RULES_KIND_REVERSI_LOBBY = RULES_GAME_REVERSI+RULES_SEP+RULES_MODE_LOBBY; public static final String RULES_KIND_TICTACTOE_TOURNAMENT = RULES_GAME_TICTACTOE+RULES_SEP+RULES_MODE_TOURNAMENT; public static final String RULES_KIND_TICTACTOE_LOBBY = RULES_GAME_TICTACTOE+RULES_SEP+RULES_MODE_LOBBY; public static final String GET_NAME = "getName"; public static final String SET_RULE_KIND = "setRuleKind"; public static final String OPEN_GAME = "openGame"; public static final String TRACK_MOVE = "trackMove"; public static final String COMPUTE_MOVE = "computeMove"; public static final String TRACK_AND_COMPUTE_MOVE = "trackAndComputeMove"; public static final String CLOSE_GAME = "closeGame"; public static final String ERROR = "error"; public static final String WAITING_PLAYERS_CHANGED = "waitingPlayersChanged"; public static final String GET_LOBBY_ACTION = "getLobbyAction"; public static final String NAME_IN_USE_PREFIX = "Name already in use: "; //----------------------------- Basics /** * Invoked at least once (and possibly several times) at the beginning of * this protocol. Invoked together with {@link #getName()}, but we don't * specify in which order. * * @param ruleKind * what kind of rules does the server follow? Example: * {@link #RULES_KIND_REVERSI_TOURNAMENT} * @return
true
if the player knows how to handle the rules * dictated by the server. */ public boolean setRuleKind(String ruleKind); /** * Invoked once at the beginning of this protocol. Invoked together with * {@link #setRuleKind(String)}, but we don't specify in which order. * * @return Only the following characters are allowed: {@link #LEGAL_NAME}} */ public String getName(); /** * Start a new game. * * @param color what is the color of the implementor of this interface? * @param opponentName the name of the opponent */ public void openGame(PieceColor color, String opponentName); /** * Track a move of the opponent */ public void trackMove(Coord coord); /** * Compute your own move. * * @param timeLimit * in milliseconds */ public Coord computeMove(long timeLimit); /** * Compute your own move. * * @param timeLimit * in milliseconds */ public Coord trackAndComputeMove(Coord coord, long timeLimit); /** * @param winner * Who won the game?
null
is used for a tie. */ public void closeGame(PieceColor winner); /** * Feedback from the server. Mainly interesting for human users. Often sent * just prior to closing a socket in reaction to a mistake the player made. */ public void error(String message); //----------------------------- Lobby /** * Definition
available players: A player becomes unavailable when * it takes part in a game or leaves the lobby (by disconnecting or * quitting). It becomes available when entering the lobby. *
* This method is only invoked on available players in the lobby, whenever * one of the following two things happen: *
*
- A player has just logged in. Thus she needs to know what players are * available. *
- The available players change. *
* * @see String#split(String) for parsing */ public void waitingPlayersChanged(String[] playerNames); /** Do nothing */ public static final String ACTION_WAIT = "!wait"; /** Leave the lobby */ public static final String ACTION_QUIT = "!quit"; /** * Signature: *
* ActionPlay(PieceColor ownColor, String opponentName, [long computationTimeout, boolean forceTimeout]) *
* Comments: *
*
- If ownColor is
null
, it means that the choice of color * should be randomized by the server. *
- We add the network latency to the computationTimeout! How the server determines * that latency is unspecified. *
*/ public static final String ACTION_PLAY = "!play"; /** * Time interval for polling the client can be freely determined by the * server. The return data written to the socket here can be seen as a * remote procedure call in the opposite direction (when compared to all * other RPC in this interface). * * @return an object representing one of the constants {@link #ACTION_WAIT}, * {@link #ACTION_QUIT} or {@value #ACTION_PLAY}. The complete line sent * depends on the ACTION_* that is involved example: *
* ACTION_PLAY+SEP+ownColor.toProtocolString()+SEP+...
*
*/ public LobbyAction getLobbyAction(); }