package com.spbsu.crawl;
import com.spbsu.commons.random.FastRandom;
import com.spbsu.crawl.bl.GameSession;
import com.spbsu.crawl.bl.Hero;
import com.spbsu.crawl.bl.Mob;
import com.spbsu.crawl.bl.crawlSystemView.SystemView;
import com.spbsu.crawl.data.Command;
import com.spbsu.crawl.data.Message;
import com.spbsu.crawl.data.impl.*;
import com.spbsu.crawl.data.impl.system.*;
import com.spbsu.crawl.learning.LearnDataBuilder;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* User: qdeee
* Date: 03.04.16
*/
public class GameProcess implements Runnable {
private static final Logger LOG = Logger.getLogger(GameProcess.class.getName());
private final WSEndpoint endpoint;
private final GameSession session;
private SystemView systemView = new SystemView();
private LearnDataBuilder learnDataBuilder;
private int turns;
public GameProcess(WSEndpoint endpoint, GameSession session) {
this.endpoint = endpoint;
this.session = session;
try {
learnDataBuilder = new LearnDataBuilder();
} catch (IOException e) {
LOG.log(Level.WARNING, "Can't create learn data builder");
System.exit(1);
}
}
private final FastRandom rng = new FastRandom();
public void run() {
skipTo(LobbyComplete.class);
final String user = rng.nextLowerCaseString(10);
endpoint.send(new RegisterMessage(user, user, user + "@localhost"));
skipTo(SetGameLinks.class);
endpoint.send(new StartGameMessage("dcss-web-trunk"));
skipTo(PlayerInfoMessage.class);
endpoint.send(new InputCommandMessage(session.race().select()));
final Hero.Spec spec = session.spec();
endpoint.send(new InputCommandMessage(spec.selectProf()));
if (spec.hasSpec())
endpoint.send(new InputCommandMessage(spec.selectSpec()));
Message message;
systemView.subscribe(session);
learnDataBuilder.attach(systemView);
do {
message = endpoint.poll();
if (message instanceof Command) {
((Command) message).execute(endpoint.out);
} else if (message instanceof UpdateMapMessage) {
systemView.updater().message((UpdateMapMessage) message);
} else if (message instanceof PlayerInfoMessage) {
systemView.updater().message((PlayerInfoMessage) message);
} else if (message instanceof MenuMessage) {
endpoint.send(new KeyMessage(KeyCode.ESCAPE));
} else if (message instanceof GameEnded) {
learnDataBuilder.endGame();
break;
} else if (message instanceof InputModeMessage) {
turns++;
switch (((InputModeMessage) message).inputMode()) {
case 0:
break;
case 1:
final Mob.Action tickAction = session.action();
endpoint.send(new InputCommandMessage(tickAction.code()));
systemView.playerActionView().action(tickAction);
break;
case 5:
endpoint.send(new InputCommandMessage(' '));
break;
case 7:
final Hero.Stat stat = session.chooseStatForUpgrade();
endpoint.send(new InputCommandMessage(stat.select()));
break;
case 8:
endpoint.send(new InputCommandMessage('Y'));
default:
LOG.warning("Unknown input mode received: " + message.json());
}
}
}
while (true);
}
private <T extends Message> T skipTo(Class<T> aClass) {
Message message;
do {
message = endpoint.poll();
if (message instanceof Command) {
((Command) message).execute(endpoint.out);
} else {
// LOG.info("Skipped message: " + message.toString());
}
}
while (!aClass.isAssignableFrom(message.getClass()));
//noinspection unchecked
return (T) message;
}
public double score() {
return systemView.mapView().knownCells() / (double) turns;
}
}