ここでは、 Apache (ssh ではない)を使用するMUD クライアントであるMudletの非常に基本的な Java バージョンに従います。TelnetClient
大部分は演習として、これまでのところ、オブジェクトの値に依存するを返す というContext
1 つの戦略だけを持っています。TargetStrategy
Deque<GameActions>
GameData
アイデアは、より多くの戦略を追加することであり、さらに重要なことに、ゲーム データに基づいて戦略を選択することです。たとえば、String ターゲットをdata
...に渡します。
そして、私は少し迷子になります。私がかなり確信していることの1つは、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();
}
}