package launch;
import action.*;
import action.reader.MoveDataReader;
import action.reader.SetterDataReader;
import action.reader.StringDataReader;
import action.reader.UserCommand;
import bot.BotManager;
import controller.GameController;
import controller.PlayersController;
import model.GameModelHistory;
import org.apache.log4j.Logger;
import streams.StreamCommutator;
import streams.StreamsContainer;
import util.ClassName;
import view.FieldView;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class GameLauncher {
private static final Logger logger = Logger.getLogger(ClassName.getCurrentClassName());
public static GameController InitGame(Parameters parameters) throws IOException {
logger.info("initialization with parameters " + parameters);
GameModelHistory model = new GameModelHistory(parameters.getFieldSize(), parameters.getWinLineLen());
final PlayersController playersController =
createPlayersController(createStreamCommutator(parameters), parameters.getFirstPlayer());
return new GameController(model, new FieldView(), playersController);
}
public static PlayersController createPlayersController(StreamCommutator commutator, int firstPlayer) {
logger.debug("configuring player controller");
return new PlayersController(createActionProvider(),
commutator,
firstPlayer);
}
private static UserActionProvider createActionProvider() {
logger.debug("configuring user action provider");
UserActionProvider actionProvider = new UserActionProvider();
actionProvider.addDataReader(new StringDataReader(UserCommand.QUIT_COMMAND), UserAction.QUIT);
actionProvider.addDataReader(new MoveDataReader(), UserAction.GAME_MOVE);
actionProvider.addDataReader(new SetterDataReader(UserCommand.HISTORY_COMMAND), UserAction.SET_HISTORY);
return actionProvider;
}
private static StreamCommutator createStreamCommutator(Parameters parameters) throws IOException {
logger.debug("selecting game initialization function for game mode " + parameters.getGameMode());
switch (parameters.getGameMode()) {
case HOTSEAT:
return singleGame();
case SERVER:
return serverGame(parameters.getPort());
case CLIENT:
return clientGame(parameters.getHost(), parameters.getPort());
case BOT:
return botGame(parameters);
default:
logger.warn("unknown game mode " + parameters.getGameMode());
return null;
}
}
private static StreamCommutator botGame(Parameters parameters) {
StreamsContainer container = new StreamsContainer(System.out, System.in, StreamCommutator.LOCAL);
BotManager manager = new BotManager(parameters, container);
manager.startBot();
return manager.getUsrCommutator();
}
private static StreamCommutator singleGame() {
logger.info("creating single game");
StreamCommutator commutator = new StreamCommutator();
commutator.addStreams(System.out, System.in, StreamCommutator.LOCAL);
commutator.addStreams(System.out, System.in, StreamCommutator.LOCAL);
return commutator;
}
private static StreamCommutator serverGame(int port) throws IOException {
logger.info("creating server at port" + port);
return createServerCommutator(new ServerSocket(port).accept());
}
private static StreamCommutator createServerCommutator(Socket serverClient) throws IOException {
StreamCommutator commutator = new StreamCommutator();
commutator.addStreams(System.out, System.in, StreamCommutator.LOCAL);
commutator.addStreams(serverClient.getOutputStream(), serverClient.getInputStream(), StreamCommutator.REMOTE);
return commutator;
}
private static StreamCommutator clientGame(String host, int port) throws IOException {
logger.info("crating client game for server " + host + ":" + port);
return createClientCommutator(new Socket(host, port));
}
private static StreamCommutator createClientCommutator(Socket client) throws IOException {
StreamCommutator commutator = new StreamCommutator();
commutator.addStreams(client.getOutputStream(), client.getInputStream(), StreamCommutator.REMOTE);
commutator.addStreams(System.out, System.in, StreamCommutator.LOCAL);
return commutator;
}
}