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();
}