下面是一个非常基本的 Java 版本的Mudlet,一个使用 Apache (不是 ssh)的MUD 客户端。TelnetClient
Context
到目前为止,很大程度上作为一个练习,只有一个策略,TargetStrategy
即返回一个Deque<GameActions>
依赖于GameData
对象值的策略。
这个想法是添加更多策略,更重要的是根据游戏数据选择策略。例如,将字符串目标传递给data
...
然后我有点迷路了。我相当肯定的一件事是Context
没有GameData
是荒谬的。例如,如果没有生物的名字,就不可能选择一个生物作为目标!
当前流程,设置策略,然后设置数据,是倒退的。这是否需要一个StrategySelector
将游戏数据作为参数并返回的类型类Context
?
Context
代码:
package game;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.logging.Logger;
import model.GameAction;
import model.GameData;
public class Context {
private static Logger log = Logger.getLogger(Context.class.getName());
private Strategy strategy;
private GameData gameData = null;
private Context() {
}
public Context(Strategy strategy) {
this.strategy = strategy;
}
public Deque<GameAction> executeStrategy() {
log.info(strategy.toString());
return this.strategy.execute(gameData);
}
public void setGameData(GameData gameData) {
this.gameData = gameData;
}
}
当观察到新数据时,然后……做什么?控制器代码如下:
package telnet;
import game.Context;
import game.TargetStrategy;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Deque;
import java.util.Observable;
import java.util.Observer;
import java.util.Properties;
import java.util.logging.Logger;
import org.apache.commons.net.telnet.TelnetClient;
import model.GameAction;
import model.GameData;
import model.TelnetEventProcessor;
public class TelnetConnection implements Observer {
private static Logger log = Logger.getLogger(TelnetConnection.class.getName());
private TelnetClient telnetClient = new TelnetClient();
private InputOutput inputOutput = new InputOutput();
private TelnetEventProcessor parser = new TelnetEventProcessor();
private Context context;// = new LogicalContext();
public TelnetConnection() {
try {
init();
} catch (SocketException ex) {
} catch (FileNotFoundException ex) {
} catch (IOException ex) {
}
}
private void init() throws SocketException, FileNotFoundException, IOException {
Properties props = PropertiesReader.getProps();
InetAddress host = InetAddress.getByName(props.getProperty("host"));
int port = Integer.parseInt(props.getProperty("port"));
telnetClient.connect(host, port);
inputOutput.readWriteParse(telnetClient.getInputStream(), telnetClient.getOutputStream());
inputOutput.addObserver(this);
parser.addObserver(this);
}
private void sendAction(GameAction action) throws IOException {
log.fine(action.toString());
byte[] actionBytes = action.getAction().getBytes();
OutputStream outputStream = telnetClient.getOutputStream();
outputStream.write(actionBytes);
outputStream.write(13);
outputStream.write(10);
outputStream.flush();
}
private void sendActions(Deque<GameAction> gameActions) {
while (!gameActions.isEmpty()) {
GameAction action = gameActions.remove();
try {
sendAction(action);
} catch (IOException ex) {
}
}
}
@Override
public void update(Observable o, Object arg) {
GameData data = null;
String line = null;
Deque<GameAction> gameActions;
if (o instanceof InputOutput) {
if (arg instanceof String) {
line = arg.toString();
parser.parse(line);
} else if (arg instanceof GameData) {
data = (GameData) arg;
context = new Context(new TargetStrategy());
context.setGameData(data); //data changes frequently!
//strategy depends on data
//put all this in another class?
gameActions = context.executeStrategy();
sendActions(gameActions);
} else {
log.info("not a i/o arg");
}
} else if (o instanceof TelnetEventProcessor) {
if (arg instanceof GameData) {
log.info("game data arg");
data = (GameData) arg;
gameActions = context.executeStrategy();
sendActions(gameActions);
} else {
log.info("not a telnetevent arg");
}
}
}
public static void main(String[] args) {
new TelnetConnection();
}
}